diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 4527e9261..11effe4a1 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -646,7 +646,9 @@ private: | |||
| 646 | Emit(OpBranchConditional(condition, true_label, skip_label)); | 646 | Emit(OpBranchConditional(condition, true_label, skip_label)); |
| 647 | Emit(true_label); | 647 | Emit(true_label); |
| 648 | 648 | ||
| 649 | ++conditional_nest_count; | ||
| 649 | VisitBasicBlock(conditional->GetCode()); | 650 | VisitBasicBlock(conditional->GetCode()); |
| 651 | --conditional_nest_count; | ||
| 650 | 652 | ||
| 651 | Emit(OpBranch(skip_label)); | 653 | Emit(OpBranch(skip_label)); |
| 652 | Emit(skip_label); | 654 | Emit(skip_label); |
| @@ -1011,7 +1013,10 @@ private: | |||
| 1011 | UNIMPLEMENTED_IF(!target); | 1013 | UNIMPLEMENTED_IF(!target); |
| 1012 | 1014 | ||
| 1013 | Emit(OpStore(jmp_to, Constant(t_uint, target->GetValue()))); | 1015 | Emit(OpStore(jmp_to, Constant(t_uint, target->GetValue()))); |
| 1014 | BranchingOp([&]() { Emit(OpBranch(continue_label)); }); | 1016 | Emit(OpBranch(continue_label)); |
| 1017 | if (conditional_nest_count == 0) { | ||
| 1018 | Emit(OpLabel()); | ||
| 1019 | } | ||
| 1015 | return {}; | 1020 | return {}; |
| 1016 | } | 1021 | } |
| 1017 | 1022 | ||
| @@ -1019,7 +1024,10 @@ private: | |||
| 1019 | const Id op_a = VisitOperand<Type::Uint>(operation, 0); | 1024 | const Id op_a = VisitOperand<Type::Uint>(operation, 0); |
| 1020 | 1025 | ||
| 1021 | Emit(OpStore(jmp_to, op_a)); | 1026 | Emit(OpStore(jmp_to, op_a)); |
| 1022 | BranchingOp([&]() { Emit(OpBranch(continue_label)); }); | 1027 | Emit(OpBranch(continue_label)); |
| 1028 | if (conditional_nest_count == 0) { | ||
| 1029 | Emit(OpLabel()); | ||
| 1030 | } | ||
| 1023 | return {}; | 1031 | return {}; |
| 1024 | } | 1032 | } |
| 1025 | 1033 | ||
| @@ -1046,7 +1054,10 @@ private: | |||
| 1046 | 1054 | ||
| 1047 | Emit(OpStore(flow_stack_top, previous)); | 1055 | Emit(OpStore(flow_stack_top, previous)); |
| 1048 | Emit(OpStore(jmp_to, target)); | 1056 | Emit(OpStore(jmp_to, target)); |
| 1049 | BranchingOp([&]() { Emit(OpBranch(continue_label)); }); | 1057 | Emit(OpBranch(continue_label)); |
| 1058 | if (conditional_nest_count == 0) { | ||
| 1059 | Emit(OpLabel()); | ||
| 1060 | } | ||
| 1050 | return {}; | 1061 | return {}; |
| 1051 | } | 1062 | } |
| 1052 | 1063 | ||
| @@ -1103,12 +1114,28 @@ private: | |||
| 1103 | 1114 | ||
| 1104 | Id Exit(Operation operation) { | 1115 | Id Exit(Operation operation) { |
| 1105 | PreExit(); | 1116 | PreExit(); |
| 1106 | BranchingOp([&]() { Emit(OpReturn()); }); | 1117 | if (conditional_nest_count > 0) { |
| 1118 | Emit(OpReturn()); | ||
| 1119 | } else { | ||
| 1120 | const Id dummy = OpLabel(); | ||
| 1121 | Emit(OpBranch(dummy)); | ||
| 1122 | Emit(dummy); | ||
| 1123 | Emit(OpReturn()); | ||
| 1124 | Emit(OpLabel()); | ||
| 1125 | } | ||
| 1107 | return {}; | 1126 | return {}; |
| 1108 | } | 1127 | } |
| 1109 | 1128 | ||
| 1110 | Id Discard(Operation operation) { | 1129 | Id Discard(Operation operation) { |
| 1111 | BranchingOp([&]() { Emit(OpKill()); }); | 1130 | if (conditional_nest_count > 0) { |
| 1131 | Emit(OpKill()); | ||
| 1132 | } else { | ||
| 1133 | const Id dummy = OpLabel(); | ||
| 1134 | Emit(OpBranch(dummy)); | ||
| 1135 | Emit(dummy); | ||
| 1136 | Emit(OpKill()); | ||
| 1137 | Emit(OpLabel()); | ||
| 1138 | } | ||
| 1112 | return {}; | 1139 | return {}; |
| 1113 | } | 1140 | } |
| 1114 | 1141 | ||
| @@ -1303,17 +1330,6 @@ private: | |||
| 1303 | return {}; | 1330 | return {}; |
| 1304 | } | 1331 | } |
| 1305 | 1332 | ||
| 1306 | void BranchingOp(std::function<void()> call) { | ||
| 1307 | const Id true_label = OpLabel(); | ||
| 1308 | const Id skip_label = OpLabel(); | ||
| 1309 | Emit(OpSelectionMerge(skip_label, spv::SelectionControlMask::Flatten)); | ||
| 1310 | Emit(OpBranchConditional(v_true, true_label, skip_label, 1, 0)); | ||
| 1311 | Emit(true_label); | ||
| 1312 | call(); | ||
| 1313 | |||
| 1314 | Emit(skip_label); | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | std::tuple<Id, Id> CreateFlowStack() { | 1333 | std::tuple<Id, Id> CreateFlowStack() { |
| 1318 | // TODO(Rodrigo): Figure out the actual depth of the flow stack, for now it seems unlikely | 1334 | // TODO(Rodrigo): Figure out the actual depth of the flow stack, for now it seems unlikely |
| 1319 | // that shaders will use 20 nested SSYs and PBKs. | 1335 | // that shaders will use 20 nested SSYs and PBKs. |
| @@ -1519,6 +1535,7 @@ private: | |||
| 1519 | const ShaderIR& ir; | 1535 | const ShaderIR& ir; |
| 1520 | const ShaderStage stage; | 1536 | const ShaderStage stage; |
| 1521 | const Tegra::Shader::Header header; | 1537 | const Tegra::Shader::Header header; |
| 1538 | u64 conditional_nest_count{}; | ||
| 1522 | 1539 | ||
| 1523 | const Id t_void = Name(TypeVoid(), "void"); | 1540 | const Id t_void = Name(TypeVoid(), "void"); |
| 1524 | 1541 | ||