summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp55
1 files changed, 36 insertions, 19 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index ca063d90d..db52841f3 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -165,10 +165,11 @@ private:
const ExitMethod jmp = Scan(target, end, labels);
return exit_method = ParallelExit(no_jmp, jmp);
}
- case OpCode::Id::SSY: {
- // The SSY instruction uses a similar encoding as the BRA instruction.
+ case OpCode::Id::SSY:
+ case OpCode::Id::PBK: {
+ // The SSY and PBK use a similar encoding as the BRA instruction.
ASSERT_MSG(instr.bra.constant_buffer == 0,
- "Constant buffer SSY is not supported");
+ "Constant buffer branching is not supported");
const u32 target = offset + instr.bra.GetBranchTarget();
labels.insert(target);
// Continue scanning for an exit method.
@@ -1153,27 +1154,27 @@ private:
}
/*
- * Emits code to push the input target address to the SSY address stack, incrementing the stack
+ * Emits code to push the input target address to the flow address stack, incrementing the stack
* top.
*/
- void EmitPushToSSYStack(u32 target) {
+ void EmitPushToFlowStack(u32 target) {
shader.AddLine('{');
++shader.scope;
- shader.AddLine("ssy_stack[ssy_stack_top] = " + std::to_string(target) + "u;");
- shader.AddLine("ssy_stack_top++;");
+ shader.AddLine("flow_stack[flow_stack_top] = " + std::to_string(target) + "u;");
+ shader.AddLine("flow_stack_top++;");
--shader.scope;
shader.AddLine('}');
}
/*
- * Emits code to pop an address from the SSY address stack, setting the jump address to the
+ * Emits code to pop an address from the flow address stack, setting the jump address to the
* popped address and decrementing the stack top.
*/
- void EmitPopFromSSYStack() {
+ void EmitPopFromFlowStack() {
shader.AddLine('{');
++shader.scope;
- shader.AddLine("ssy_stack_top--;");
- shader.AddLine("jmp_to = ssy_stack[ssy_stack_top];");
+ shader.AddLine("flow_stack_top--;");
+ shader.AddLine("jmp_to = flow_stack[flow_stack_top];");
shader.AddLine("break;");
--shader.scope;
shader.AddLine('}');
@@ -2933,16 +2934,32 @@ private:
// The SSY opcode tells the GPU where to re-converge divergent execution paths, it
// sets the target of the jump that the SYNC instruction will make. The SSY opcode
// has a similar structure to the BRA opcode.
- ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported");
+ ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer flow is not supported");
const u32 target = offset + instr.bra.GetBranchTarget();
- EmitPushToSSYStack(target);
+ EmitPushToFlowStack(target);
+ break;
+ }
+ case OpCode::Id::PBK: {
+ // PBK pushes to a stack the address where BRK will jump to. This shares stack with
+ // SSY but using SYNC on a PBK address will kill the shader execution. We don't
+ // emulate this because it's very unlikely a driver will emit such invalid shader.
+ ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer PBK is not supported");
+
+ const u32 target = offset + instr.bra.GetBranchTarget();
+ EmitPushToFlowStack(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);
- EmitPopFromSSYStack();
+ EmitPopFromFlowStack();
+ break;
+ }
+ case OpCode::Id::BRK: {
+ // The BRK opcode jumps to the address previously set by the PBK opcode
+ ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
+ EmitPopFromFlowStack();
break;
}
case OpCode::Id::DEPBAR: {
@@ -3096,11 +3113,11 @@ private:
labels.insert(subroutine.begin);
shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;");
- // 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;");
+ // TODO(Subv): Figure out the actual depth of the flow stack, for now it seems
+ // unlikely that shaders will use 20 nested SSYs and PBKs.
+ constexpr u32 FLOW_STACK_SIZE = 20;
+ shader.AddLine("uint flow_stack[" + std::to_string(FLOW_STACK_SIZE) + "];");
+ shader.AddLine("uint flow_stack_top = 0u;");
shader.AddLine("while (true) {");
++shader.scope;