summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp11
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();