diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index bb01b3c27..ab32492e3 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -815,6 +815,33 @@ private: | |||
| 815 | shader.AddLine('}'); | 815 | shader.AddLine('}'); |
| 816 | } | 816 | } |
| 817 | 817 | ||
| 818 | /* | ||
| 819 | * Emits code to push the input target address to the SSY address stack, incrementing the stack | ||
| 820 | * top. | ||
| 821 | */ | ||
| 822 | void EmitPushToSSYStack(u32 target) { | ||
| 823 | shader.AddLine('{'); | ||
| 824 | ++shader.scope; | ||
| 825 | shader.AddLine("ssy_stack[ssy_stack_top] = " + std::to_string(target) + "u;"); | ||
| 826 | shader.AddLine("ssy_stack_top++;"); | ||
| 827 | --shader.scope; | ||
| 828 | shader.AddLine('}'); | ||
| 829 | } | ||
| 830 | |||
| 831 | /* | ||
| 832 | * Emits code to pop an address from the SSY address stack, setting the jump address to the | ||
| 833 | * popped address and decrementing the stack top. | ||
| 834 | */ | ||
| 835 | void EmitPopFromSSYStack() { | ||
| 836 | shader.AddLine('{'); | ||
| 837 | ++shader.scope; | ||
| 838 | shader.AddLine("ssy_stack_top--;"); | ||
| 839 | shader.AddLine("jmp_to = ssy_stack[ssy_stack_top];"); | ||
| 840 | shader.AddLine("break;"); | ||
| 841 | --shader.scope; | ||
| 842 | shader.AddLine('}'); | ||
| 843 | } | ||
| 844 | |||
| 818 | /** | 845 | /** |
| 819 | * Compiles a single instruction from Tegra to GLSL. | 846 | * Compiles a single instruction from Tegra to GLSL. |
| 820 | * @param offset the offset of the Tegra shader instruction. | 847 | * @param offset the offset of the Tegra shader instruction. |
| @@ -1843,13 +1870,13 @@ private: | |||
| 1843 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); | 1870 | ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); |
| 1844 | 1871 | ||
| 1845 | u32 target = offset + instr.bra.GetBranchTarget(); | 1872 | u32 target = offset + instr.bra.GetBranchTarget(); |
| 1846 | shader.AddLine("ssy_target = " + std::to_string(target) + "u;"); | 1873 | EmitPushToSSYStack(target); |
| 1847 | break; | 1874 | break; |
| 1848 | } | 1875 | } |
| 1849 | case OpCode::Id::SYNC: { | 1876 | case OpCode::Id::SYNC: { |
| 1850 | // The SYNC opcode jumps to the address previously set by the SSY opcode | 1877 | // The SYNC opcode jumps to the address previously set by the SSY opcode |
| 1851 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | 1878 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); |
| 1852 | shader.AddLine("{ jmp_to = ssy_target; break; }"); | 1879 | EmitPopFromSSYStack(); |
| 1853 | break; | 1880 | break; |
| 1854 | } | 1881 | } |
| 1855 | case OpCode::Id::DEPBAR: { | 1882 | case OpCode::Id::DEPBAR: { |
| @@ -1920,7 +1947,13 @@ private: | |||
| 1920 | } else { | 1947 | } else { |
| 1921 | labels.insert(subroutine.begin); | 1948 | labels.insert(subroutine.begin); |
| 1922 | shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); | 1949 | shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); |
| 1923 | shader.AddLine("uint ssy_target = 0u;"); | 1950 | |
| 1951 | // TODO(Subv): Figure out the actual depth of the SSY stack, for now it seems | ||
| 1952 | // unlikely that shaders will use 20 nested SSYs. | ||
| 1953 | constexpr u32 SSY_STACK_SIZE = 20; | ||
| 1954 | shader.AddLine("uint ssy_stack[" + std::to_string(SSY_STACK_SIZE) + "];"); | ||
| 1955 | shader.AddLine("uint ssy_stack_top = 0u;"); | ||
| 1956 | |||
| 1924 | shader.AddLine("while (true) {"); | 1957 | shader.AddLine("while (true) {"); |
| 1925 | ++shader.scope; | 1958 | ++shader.scope; |
| 1926 | 1959 | ||