summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2018-08-18 17:48:12 +0200
committerSubv <subv2112@gmail.com>2018-08-18 17:48:12 +0200
commitff358d97e88a279e7659ab3969bce820f58c77cf (patch)
tree2caf666e85eb62ab86b118c0f0f6ef29ac269a14
parentMerge pull request #1100 from ogniK5377/missing-pred (diff)
downloadyuzu-ff358d97e88a279e7659ab3969bce820f58c77cf.tar
yuzu-ff358d97e88a279e7659ab3969bce820f58c77cf.tar.gz
yuzu-ff358d97e88a279e7659ab3969bce820f58c77cf.tar.bz2
yuzu-ff358d97e88a279e7659ab3969bce820f58c77cf.tar.lz
yuzu-ff358d97e88a279e7659ab3969bce820f58c77cf.tar.xz
yuzu-ff358d97e88a279e7659ab3969bce820f58c77cf.tar.zst
yuzu-ff358d97e88a279e7659ab3969bce820f58c77cf.zip
-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:
shader.AddLine('}');
}
+ /*
+ * Emits code to push the input target address to the SSY address stack, incrementing the stack
+ * top.
+ */
+ void EmitPushToSSYStack(u32 target) {
+ shader.AddLine('{');
+ ++shader.scope;
+ shader.AddLine("ssy_stack[ssy_stack_top] = " + std::to_string(target) + "u;");
+ shader.AddLine("ssy_stack_top++;");
+ --shader.scope;
+ shader.AddLine('}');
+ }
+
+ /*
+ * Emits code to pop an address from the SSY address stack, setting the jump address to the
+ * popped address and decrementing the stack top.
+ */
+ void EmitPopFromSSYStack() {
+ shader.AddLine('{');
+ ++shader.scope;
+ shader.AddLine("ssy_stack_top--;");
+ shader.AddLine("jmp_to = ssy_stack[ssy_stack_top];");
+ shader.AddLine("break;");
+ --shader.scope;
+ shader.AddLine('}');
+ }
+
/**
* Compiles a single instruction from Tegra to GLSL.
* @param offset the offset of the Tegra shader instruction.
@@ -1843,13 +1870,13 @@ private:
ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported");
u32 target = offset + instr.bra.GetBranchTarget();
- shader.AddLine("ssy_target = " + std::to_string(target) + "u;");
+ EmitPushToSSYStack(target);
break;
}
case OpCode::Id::SYNC: {
// The SYNC opcode jumps to the address previously set by the SSY opcode
ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
- shader.AddLine("{ jmp_to = ssy_target; break; }");
+ EmitPopFromSSYStack();
break;
}
case OpCode::Id::DEPBAR: {
@@ -1920,7 +1947,13 @@ private:
} else {
labels.insert(subroutine.begin);
shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;");
- shader.AddLine("uint ssy_target = 0u;");
+
+ // TODO(Subv): Figure out the actual depth of the SSY stack, for now it seems
+ // unlikely that shaders will use 20 nested SSYs.
+ constexpr u32 SSY_STACK_SIZE = 20;
+ shader.AddLine("uint ssy_stack[" + std::to_string(SSY_STACK_SIZE) + "];");
+ shader.AddLine("uint ssy_stack_top = 0u;");
+
shader.AddLine("while (true) {");
++shader.scope;