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