diff options
| -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 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 | ||
| 204 | enum class FlowCondition : u64 { | ||
| 205 | Always = 0xF, | ||
| 206 | Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? | ||
| 207 | }; | ||
| 208 | |||
| 204 | union Instruction { | 209 | union 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"); |