summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h9
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp33
2 files changed, 34 insertions, 8 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index ab978c2e2..2ec1de285 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -201,6 +201,11 @@ enum class IMinMaxExchange : u64 {
201 XHi = 3, 201 XHi = 3,
202}; 202};
203 203
204enum class FlowCondition : u64 {
205 Always = 0xF,
206 Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for?
207};
208
204union Instruction { 209union Instruction {
205 Instruction& operator=(const Instruction& instr) { 210 Instruction& operator=(const Instruction& instr) {
206 value = instr.value; 211 value = instr.value;
@@ -316,6 +321,10 @@ union Instruction {
316 } bfe; 321 } bfe;
317 322
318 union { 323 union {
324 BitField<0, 5, FlowCondition> cond;
325 } flow;
326
327 union {
319 BitField<48, 1, u64> negate_b; 328 BitField<48, 1, u64> negate_b;
320 BitField<49, 1, u64> negate_c; 329 BitField<49, 1, u64> negate_c;
321 } ffma; 330 } ffma;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index c29cabb84..36a6f1cc5 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1639,16 +1639,32 @@ private:
1639 shader.AddLine("color.a = " + regs.GetRegisterAsFloat(3) + ';'); 1639 shader.AddLine("color.a = " + regs.GetRegisterAsFloat(3) + ';');
1640 } 1640 }
1641 1641
1642 shader.AddLine("return true;"); 1642 switch (instr.flow.cond) {
1643 if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) { 1643 case Tegra::Shader::FlowCondition::Always:
1644 // If this is an unconditional exit then just end processing here, otherwise 1644 shader.AddLine("return true;");
1645 // we have to account for the possibility of the condition not being met, so 1645 if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) {
1646 // continue processing the next instruction. 1646 // If this is an unconditional exit then just end processing here,
1647 offset = PROGRAM_END - 1; 1647 // otherwise we have to account for the possibility of the condition
1648 // not being met, so continue processing the next instruction.
1649 offset = PROGRAM_END - 1;
1650 }
1651 break;
1652
1653 case Tegra::Shader::FlowCondition::Fcsm_Tr:
1654 // TODO(bunnei): What is this used for? If we assume this conditon is not
1655 // satisifed, dual vertex shaders in Farming Simulator make more sense
1656 LOG_CRITICAL(HW_GPU, "Skipping unknown FlowCondition::Fcsm_Tr");
1657 break;
1658
1659 default:
1660 LOG_CRITICAL(HW_GPU, "Unhandled flow condition: {}",
1661 static_cast<u32>(instr.flow.cond.Value()));
1662 UNREACHABLE();
1648 } 1663 }
1649 break; 1664 break;
1650 } 1665 }
1651 case OpCode::Id::KIL: { 1666 case OpCode::Id::KIL: {
1667 ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
1652 shader.AddLine("discard;"); 1668 shader.AddLine("discard;");
1653 break; 1669 break;
1654 } 1670 }
@@ -1669,8 +1685,9 @@ private:
1669 // can ignore this when generating GLSL code. 1685 // can ignore this when generating GLSL code.
1670 break; 1686 break;
1671 } 1687 }
1672 case OpCode::Id::DEPBAR: 1688 case OpCode::Id::SYNC:
1673 case OpCode::Id::SYNC: { 1689 ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
1690 case OpCode::Id::DEPBAR: {
1674 // TODO(Subv): Find out if we actually have to care about these instructions or if 1691 // TODO(Subv): Find out if we actually have to care about these instructions or if
1675 // the GLSL compiler takes care of that for us. 1692 // the GLSL compiler takes care of that for us.
1676 LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed"); 1693 LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed");