summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-12-22 12:36:56 -0400
committerGravatar GitHub2019-12-22 12:36:56 -0400
commit3dc585d011af857d853adb124d64b743cc1e6d24 (patch)
treece84ad9f5023c31c1d1c6a52e026e817ee51f9e5
parentMerge pull request #3230 from ReinUsesLisp/vk-emu-shaders (diff)
parentvk_shader_decompiler: Fix full decompilation (diff)
downloadyuzu-3dc585d011af857d853adb124d64b743cc1e6d24.tar.gz
yuzu-3dc585d011af857d853adb124d64b743cc1e6d24.tar.xz
yuzu-3dc585d011af857d853adb124d64b743cc1e6d24.zip
Merge pull request #3237 from ReinUsesLisp/vk-shader-decompiler
vk_shader_decompiler: Misc changes
m---------externals/sirit0
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp83
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h4
3 files changed, 49 insertions, 38 deletions
diff --git a/externals/sirit b/externals/sirit
Subproject 12f40a80324d7c154f19f25c448a5ce27d38cd1 Subproject 9f4d057aa28c4e9509bdc767afb27b4aee303b7
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index fae8c95c8..a8baf91de 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -543,7 +543,7 @@ private:
543 } 543 }
544 544
545 for (u32 rt = 0; rt < static_cast<u32>(frag_colors.size()); ++rt) { 545 for (u32 rt = 0; rt < static_cast<u32>(frag_colors.size()); ++rt) {
546 if (!IsRenderTargetUsed(rt)) { 546 if (!specialization.enabled_rendertargets[rt]) {
547 continue; 547 continue;
548 } 548 }
549 549
@@ -1555,40 +1555,48 @@ private:
1555 1555
1556 Expression Texture(Operation operation) { 1556 Expression Texture(Operation operation) {
1557 const auto& meta = std::get<MetaTexture>(operation.GetMeta()); 1557 const auto& meta = std::get<MetaTexture>(operation.GetMeta());
1558 UNIMPLEMENTED_IF(!meta.aoffi.empty());
1559 1558
1560 const bool can_implicit = stage == ShaderType::Fragment; 1559 const bool can_implicit = stage == ShaderType::Fragment;
1561 const Id sampler = GetTextureSampler(operation); 1560 const Id sampler = GetTextureSampler(operation);
1562 const Id coords = GetCoordinates(operation, Type::Float); 1561 const Id coords = GetCoordinates(operation, Type::Float);
1563 1562
1563 std::vector<Id> operands;
1564 spv::ImageOperandsMask mask{};
1565 if (meta.bias) {
1566 mask = mask | spv::ImageOperandsMask::Bias;
1567 operands.push_back(AsFloat(Visit(meta.bias)));
1568 }
1569
1570 if (!can_implicit) {
1571 mask = mask | spv::ImageOperandsMask::Lod;
1572 operands.push_back(v_float_zero);
1573 }
1574
1575 if (!meta.aoffi.empty()) {
1576 mask = mask | spv::ImageOperandsMask::Offset;
1577 operands.push_back(GetOffsetCoordinates(operation));
1578 }
1579
1564 if (meta.depth_compare) { 1580 if (meta.depth_compare) {
1565 // Depth sampling 1581 // Depth sampling
1566 UNIMPLEMENTED_IF(meta.bias); 1582 UNIMPLEMENTED_IF(meta.bias);
1567 const Id dref = AsFloat(Visit(meta.depth_compare)); 1583 const Id dref = AsFloat(Visit(meta.depth_compare));
1568 if (can_implicit) { 1584 if (can_implicit) {
1569 return {OpImageSampleDrefImplicitLod(t_float, sampler, coords, dref, {}), 1585 return {
1570 Type::Float}; 1586 OpImageSampleDrefImplicitLod(t_float, sampler, coords, dref, mask, operands),
1587 Type::Float};
1571 } else { 1588 } else {
1572 return {OpImageSampleDrefExplicitLod(t_float, sampler, coords, dref, 1589 return {
1573 spv::ImageOperandsMask::Lod, v_float_zero), 1590 OpImageSampleDrefExplicitLod(t_float, sampler, coords, dref, mask, operands),
1574 Type::Float}; 1591 Type::Float};
1575 } 1592 }
1576 } 1593 }
1577 1594
1578 std::vector<Id> operands;
1579 spv::ImageOperandsMask mask{};
1580 if (meta.bias) {
1581 mask = mask | spv::ImageOperandsMask::Bias;
1582 operands.push_back(AsFloat(Visit(meta.bias)));
1583 }
1584
1585 Id texture; 1595 Id texture;
1586 if (can_implicit) { 1596 if (can_implicit) {
1587 texture = OpImageSampleImplicitLod(t_float4, sampler, coords, mask, operands); 1597 texture = OpImageSampleImplicitLod(t_float4, sampler, coords, mask, operands);
1588 } else { 1598 } else {
1589 texture = OpImageSampleExplicitLod(t_float4, sampler, coords, 1599 texture = OpImageSampleExplicitLod(t_float4, sampler, coords, mask, operands);
1590 mask | spv::ImageOperandsMask::Lod, v_float_zero,
1591 operands);
1592 } 1600 }
1593 return GetTextureElement(operation, texture, Type::Float); 1601 return GetTextureElement(operation, texture, Type::Float);
1594 } 1602 }
@@ -1601,7 +1609,8 @@ private:
1601 const Id lod = AsFloat(Visit(meta.lod)); 1609 const Id lod = AsFloat(Visit(meta.lod));
1602 1610
1603 spv::ImageOperandsMask mask = spv::ImageOperandsMask::Lod; 1611 spv::ImageOperandsMask mask = spv::ImageOperandsMask::Lod;
1604 std::vector<Id> operands; 1612 std::vector<Id> operands{lod};
1613
1605 if (!meta.aoffi.empty()) { 1614 if (!meta.aoffi.empty()) {
1606 mask = mask | spv::ImageOperandsMask::Offset; 1615 mask = mask | spv::ImageOperandsMask::Offset;
1607 operands.push_back(GetOffsetCoordinates(operation)); 1616 operands.push_back(GetOffsetCoordinates(operation));
@@ -1609,11 +1618,10 @@ private:
1609 1618
1610 if (meta.sampler.IsShadow()) { 1619 if (meta.sampler.IsShadow()) {
1611 const Id dref = AsFloat(Visit(meta.depth_compare)); 1620 const Id dref = AsFloat(Visit(meta.depth_compare));
1612 return { 1621 return {OpImageSampleDrefExplicitLod(t_float, sampler, coords, dref, mask, operands),
1613 OpImageSampleDrefExplicitLod(t_float, sampler, coords, dref, mask, lod, operands), 1622 Type::Float};
1614 Type::Float};
1615 } 1623 }
1616 const Id texture = OpImageSampleExplicitLod(t_float4, sampler, coords, mask, lod, operands); 1624 const Id texture = OpImageSampleExplicitLod(t_float4, sampler, coords, mask, operands);
1617 return GetTextureElement(operation, texture, Type::Float); 1625 return GetTextureElement(operation, texture, Type::Float);
1618 } 1626 }
1619 1627
@@ -1722,7 +1730,7 @@ private:
1722 const std::vector grad = {dx, dy}; 1730 const std::vector grad = {dx, dy};
1723 1731
1724 static constexpr auto mask = spv::ImageOperandsMask::Grad; 1732 static constexpr auto mask = spv::ImageOperandsMask::Grad;
1725 const Id texture = OpImageSampleImplicitLod(t_float4, sampler, coords, mask, grad); 1733 const Id texture = OpImageSampleExplicitLod(t_float4, sampler, coords, mask, grad);
1726 return GetTextureElement(operation, texture, Type::Float); 1734 return GetTextureElement(operation, texture, Type::Float);
1727 } 1735 }
1728 1736
@@ -1833,7 +1841,7 @@ private:
1833 } 1841 }
1834 1842
1835 void PreExit() { 1843 void PreExit() {
1836 if (stage == ShaderType::Vertex) { 1844 if (stage == ShaderType::Vertex && specialization.ndc_minus_one_to_one) {
1837 const u32 position_index = out_indices.position.value(); 1845 const u32 position_index = out_indices.position.value();
1838 const Id z_pointer = AccessElement(t_out_float, out_vertex, position_index, 2U); 1846 const Id z_pointer = AccessElement(t_out_float, out_vertex, position_index, 2U);
1839 const Id w_pointer = AccessElement(t_out_float, out_vertex, position_index, 3U); 1847 const Id w_pointer = AccessElement(t_out_float, out_vertex, position_index, 3U);
@@ -1860,12 +1868,18 @@ private:
1860 // rendertargets/components are skipped in the register assignment. 1868 // rendertargets/components are skipped in the register assignment.
1861 u32 current_reg = 0; 1869 u32 current_reg = 0;
1862 for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) { 1870 for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) {
1871 if (!specialization.enabled_rendertargets[rt]) {
1872 // Skip rendertargets that are not enabled
1873 continue;
1874 }
1863 // TODO(Subv): Figure out how dual-source blending is configured in the Switch. 1875 // TODO(Subv): Figure out how dual-source blending is configured in the Switch.
1864 for (u32 component = 0; component < 4; ++component) { 1876 for (u32 component = 0; component < 4; ++component) {
1877 const Id pointer = AccessElement(t_out_float, frag_colors.at(rt), component);
1865 if (header.ps.IsColorComponentOutputEnabled(rt, component)) { 1878 if (header.ps.IsColorComponentOutputEnabled(rt, component)) {
1866 OpStore(AccessElement(t_out_float, frag_colors.at(rt), component), 1879 OpStore(pointer, SafeGetRegister(current_reg));
1867 SafeGetRegister(current_reg));
1868 ++current_reg; 1880 ++current_reg;
1881 } else {
1882 OpStore(pointer, component == 3 ? v_float_one : v_float_zero);
1869 } 1883 }
1870 } 1884 }
1871 } 1885 }
@@ -1995,15 +2009,6 @@ private:
1995 return DeclareBuiltIn(builtin, spv::StorageClass::Input, type, std::move(name)); 2009 return DeclareBuiltIn(builtin, spv::StorageClass::Input, type, std::move(name));
1996 } 2010 }
1997 2011
1998 bool IsRenderTargetUsed(u32 rt) const {
1999 for (u32 component = 0; component < 4; ++component) {
2000 if (header.ps.IsColorComponentOutputEnabled(rt, component)) {
2001 return true;
2002 }
2003 }
2004 return false;
2005 }
2006
2007 template <typename... Args> 2012 template <typename... Args>
2008 Id AccessElement(Id pointer_type, Id composite, Args... elements_) { 2013 Id AccessElement(Id pointer_type, Id composite, Args... elements_) {
2009 std::vector<Id> members; 2014 std::vector<Id> members;
@@ -2567,7 +2572,7 @@ public:
2567 const Id target = decomp.Constant(decomp.t_uint, expr.value); 2572 const Id target = decomp.Constant(decomp.t_uint, expr.value);
2568 Id gpr = decomp.OpLoad(decomp.t_float, decomp.registers.at(expr.gpr)); 2573 Id gpr = decomp.OpLoad(decomp.t_float, decomp.registers.at(expr.gpr));
2569 gpr = decomp.OpBitcast(decomp.t_uint, gpr); 2574 gpr = decomp.OpBitcast(decomp.t_uint, gpr);
2570 return decomp.OpLogicalEqual(decomp.t_uint, gpr, target); 2575 return decomp.OpIEqual(decomp.t_bool, gpr, target);
2571 } 2576 }
2572 2577
2573 Id Visit(const Expr& node) { 2578 Id Visit(const Expr& node) {
@@ -2637,11 +2642,11 @@ public:
2637 const Id loop_label = decomp.OpLabel(); 2642 const Id loop_label = decomp.OpLabel();
2638 const Id endloop_label = decomp.OpLabel(); 2643 const Id endloop_label = decomp.OpLabel();
2639 const Id loop_start_block = decomp.OpLabel(); 2644 const Id loop_start_block = decomp.OpLabel();
2640 const Id loop_end_block = decomp.OpLabel(); 2645 const Id loop_continue_block = decomp.OpLabel();
2641 current_loop_exit = endloop_label; 2646 current_loop_exit = endloop_label;
2642 decomp.OpBranch(loop_label); 2647 decomp.OpBranch(loop_label);
2643 decomp.AddLabel(loop_label); 2648 decomp.AddLabel(loop_label);
2644 decomp.OpLoopMerge(endloop_label, loop_end_block, spv::LoopControlMask::MaskNone); 2649 decomp.OpLoopMerge(endloop_label, loop_continue_block, spv::LoopControlMask::MaskNone);
2645 decomp.OpBranch(loop_start_block); 2650 decomp.OpBranch(loop_start_block);
2646 decomp.AddLabel(loop_start_block); 2651 decomp.AddLabel(loop_start_block);
2647 ASTNode current = ast.nodes.GetFirst(); 2652 ASTNode current = ast.nodes.GetFirst();
@@ -2649,6 +2654,8 @@ public:
2649 Visit(current); 2654 Visit(current);
2650 current = current->GetNext(); 2655 current = current->GetNext();
2651 } 2656 }
2657 decomp.OpBranch(loop_continue_block);
2658 decomp.AddLabel(loop_continue_block);
2652 ExprDecompiler expr_parser{decomp}; 2659 ExprDecompiler expr_parser{decomp};
2653 const Id condition = expr_parser.Visit(ast.condition); 2660 const Id condition = expr_parser.Visit(ast.condition);
2654 decomp.OpBranchConditional(condition, loop_label, endloop_label); 2661 decomp.OpBranchConditional(condition, loop_label, endloop_label);
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
index 2b01321b6..10794be1c 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
@@ -94,6 +94,7 @@ struct Specialization final {
94 Maxwell::PrimitiveTopology primitive_topology{}; 94 Maxwell::PrimitiveTopology primitive_topology{};
95 std::optional<float> point_size{}; 95 std::optional<float> point_size{};
96 std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; 96 std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{};
97 bool ndc_minus_one_to_one{};
97 98
98 // Tessellation specific 99 // Tessellation specific
99 struct { 100 struct {
@@ -101,6 +102,9 @@ struct Specialization final {
101 Maxwell::TessellationSpacing spacing{}; 102 Maxwell::TessellationSpacing spacing{};
102 bool clockwise{}; 103 bool clockwise{};
103 } tessellation; 104 } tessellation;
105
106 // Fragment specific
107 std::bitset<8> enabled_rendertargets;
104}; 108};
105// Old gcc versions don't consider this trivially copyable. 109// Old gcc versions don't consider this trivially copyable.
106// static_assert(std::is_trivially_copyable_v<Specialization>); 110// static_assert(std::is_trivially_copyable_v<Specialization>);