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