summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp39
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