diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 32f06f409..532a47037 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -141,6 +141,15 @@ private: | |||
| 141 | ExitMethod jmp = Scan(target, end, labels); | 141 | ExitMethod jmp = Scan(target, end, labels); |
| 142 | return exit_method = ParallelExit(no_jmp, jmp); | 142 | return exit_method = ParallelExit(no_jmp, jmp); |
| 143 | } | 143 | } |
| 144 | case OpCode::Id::SSY: { | ||
| 145 | // The SSY instruction uses a similar encoding as the BRA instruction. | ||
| 146 | ASSERT_MSG(instr.bra.constant_buffer == 0, | ||
| 147 | "Constant buffer SSY is not supported"); | ||
| 148 | u32 target = offset + instr.bra.GetBranchTarget(); | ||
| 149 | labels.insert(target); | ||
| 150 | // Continue scanning for an exit method. | ||
| 151 | break; | ||
| 152 | } | ||
| 144 | } | 153 | } |
| 145 | } | 154 | } |
| 146 | } | 155 | } |
| @@ -1668,16 +1677,25 @@ private: | |||
| 1668 | break; | 1677 | break; |
| 1669 | } | 1678 | } |
| 1670 | case OpCode::Id::SSY: { | 1679 | case OpCode::Id::SSY: { |
| 1671 | // The SSY opcode tells the GPU where to re-converge divergent execution paths, we | 1680 | // The SSY opcode tells the GPU where to re-converge divergent execution paths, it |
| 1672 | // can ignore this when generating GLSL code. | 1681 | // sets the target of the jump that the SYNC instruction will make. The SSY opcode |
| 1682 | // has a similar structure to the BRA opcode. | ||
| 1683 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); | ||
| 1684 | |||
| 1685 | u32 target = offset + instr.bra.GetBranchTarget(); | ||
| 1686 | shader.AddLine("ssy_target = " + std::to_string(target) + "u;"); | ||
| 1673 | break; | 1687 | break; |
| 1674 | } | 1688 | } |
| 1675 | case OpCode::Id::SYNC: | 1689 | case OpCode::Id::SYNC: { |
| 1690 | // The SYNC opcode jumps to the address previously set by the SSY opcode | ||
| 1676 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | 1691 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); |
| 1692 | shader.AddLine("{ jmp_to = ssy_target; break; }"); | ||
| 1693 | break; | ||
| 1694 | } | ||
| 1677 | case OpCode::Id::DEPBAR: { | 1695 | case OpCode::Id::DEPBAR: { |
| 1678 | // TODO(Subv): Find out if we actually have to care about these instructions or if | 1696 | // TODO(Subv): Find out if we actually have to care about this instruction or if |
| 1679 | // the GLSL compiler takes care of that for us. | 1697 | // the GLSL compiler takes care of that for us. |
| 1680 | LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed"); | 1698 | LOG_WARNING(HW_GPU, "DEPBAR instruction is stubbed"); |
| 1681 | break; | 1699 | break; |
| 1682 | } | 1700 | } |
| 1683 | default: { | 1701 | default: { |
| @@ -1742,6 +1760,7 @@ private: | |||
| 1742 | } else { | 1760 | } else { |
| 1743 | labels.insert(subroutine.begin); | 1761 | labels.insert(subroutine.begin); |
| 1744 | shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); | 1762 | shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); |
| 1763 | shader.AddLine("uint ssy_target = 0u;"); | ||
| 1745 | shader.AddLine("while (true) {"); | 1764 | shader.AddLine("while (true) {"); |
| 1746 | ++shader.scope; | 1765 | ++shader.scope; |
| 1747 | 1766 | ||
| @@ -1757,7 +1776,7 @@ private: | |||
| 1757 | u32 compile_end = CompileRange(label, next_label); | 1776 | u32 compile_end = CompileRange(label, next_label); |
| 1758 | if (compile_end > next_label && compile_end != PROGRAM_END) { | 1777 | if (compile_end > next_label && compile_end != PROGRAM_END) { |
| 1759 | // This happens only when there is a label inside a IF/LOOP block | 1778 | // This happens only when there is a label inside a IF/LOOP block |
| 1760 | shader.AddLine("{ jmp_to = " + std::to_string(compile_end) + "u; break; }"); | 1779 | shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }"); |
| 1761 | labels.emplace(compile_end); | 1780 | labels.emplace(compile_end); |
| 1762 | } | 1781 | } |
| 1763 | 1782 | ||