diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 6f66dfbcd..eb8d37c9b 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -115,7 +115,16 @@ private: | |||
| 115 | if (const auto opcode = OpCode::Decode(instr)) { | 115 | if (const auto opcode = OpCode::Decode(instr)) { |
| 116 | switch (opcode->GetId()) { | 116 | switch (opcode->GetId()) { |
| 117 | case OpCode::Id::EXIT: { | 117 | case OpCode::Id::EXIT: { |
| 118 | return exit_method = ExitMethod::AlwaysEnd; | 118 | // The EXIT instruction can be predicated, which means that the shader can |
| 119 | // conditionally end on this instruction. We have to consider the case where the | ||
| 120 | // condition is not met and check the exit method of that other basic block. | ||
| 121 | using Tegra::Shader::Pred; | ||
| 122 | if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) { | ||
| 123 | return exit_method = ExitMethod::AlwaysEnd; | ||
| 124 | } else { | ||
| 125 | ExitMethod not_met = Scan(offset + 1, end, labels); | ||
| 126 | return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met); | ||
| 127 | } | ||
| 119 | } | 128 | } |
| 120 | case OpCode::Id::BRA: { | 129 | case OpCode::Id::BRA: { |
| 121 | u32 target = offset + instr.bra.GetBranchTarget(); | 130 | u32 target = offset + instr.bra.GetBranchTarget(); |
| @@ -1213,9 +1222,6 @@ private: | |||
| 1213 | default: { | 1222 | default: { |
| 1214 | switch (opcode->GetId()) { | 1223 | switch (opcode->GetId()) { |
| 1215 | case OpCode::Id::EXIT: { | 1224 | case OpCode::Id::EXIT: { |
| 1216 | ASSERT_MSG(instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex), | ||
| 1217 | "Predicated exits not implemented"); | ||
| 1218 | |||
| 1219 | // Final color output is currently hardcoded to GPR0-3 for fragment shaders | 1225 | // Final color output is currently hardcoded to GPR0-3 for fragment shaders |
| 1220 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { | 1226 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { |
| 1221 | shader.AddLine("color.r = " + regs.GetRegisterAsFloat(0) + ';'); | 1227 | shader.AddLine("color.r = " + regs.GetRegisterAsFloat(0) + ';'); |
| @@ -1225,7 +1231,12 @@ private: | |||
| 1225 | } | 1231 | } |
| 1226 | 1232 | ||
| 1227 | shader.AddLine("return true;"); | 1233 | shader.AddLine("return true;"); |
| 1228 | offset = PROGRAM_END - 1; | 1234 | if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) { |
| 1235 | // If this is an unconditional exit then just end processing here, otherwise we | ||
| 1236 | // have to account for the possibility of the condition not being met, so | ||
| 1237 | // continue processing the next instruction. | ||
| 1238 | offset = PROGRAM_END - 1; | ||
| 1239 | } | ||
| 1229 | break; | 1240 | break; |
| 1230 | } | 1241 | } |
| 1231 | case OpCode::Id::KIL: { | 1242 | case OpCode::Id::KIL: { |