diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 33 |
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 | ||
| 205 | enum class FlowCondition : u64 { | ||
| 206 | Always = 0xF, | ||
| 207 | Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? | ||
| 208 | }; | ||
| 209 | |||
| 205 | union Instruction { | 210 | union 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"); |