diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 4cfd6f042..c802532db 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(); |