summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorGravatar bunnei2018-10-23 00:01:38 -0400
committerGravatar GitHub2018-10-23 00:01:38 -0400
commit848a49112a774cd95fe1a600f1acdfec7aefcc6d (patch)
treec1d6bf385df694f4c0789a766a041b175daeefe9 /src/video_core/renderer_opengl
parentMerge pull request #1550 from FernandoS27/fmul32 (diff)
parentgl_shader_decompiler: Implement PBK and BRK (diff)
downloadyuzu-848a49112a774cd95fe1a600f1acdfec7aefcc6d.tar.gz
yuzu-848a49112a774cd95fe1a600f1acdfec7aefcc6d.tar.xz
yuzu-848a49112a774cd95fe1a600f1acdfec7aefcc6d.zip
Merge pull request #1512 from ReinUsesLisp/brk
gl_shader_decompiler: Implement PBK and BRK
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 a3daef014..d36f190b7 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -163,10 +163,11 @@ private:
163 const ExitMethod jmp = Scan(target, end, labels); 163 const ExitMethod jmp = Scan(target, end, labels);
164 return exit_method = ParallelExit(no_jmp, jmp); 164 return exit_method = ParallelExit(no_jmp, jmp);
165 } 165 }
166 case OpCode::Id::SSY: { 166 case OpCode::Id::SSY:
167 // The SSY instruction uses a similar encoding as the BRA instruction. 167 case OpCode::Id::PBK: {
168 // The SSY and PBK use a similar encoding as the BRA instruction.
168 ASSERT_MSG(instr.bra.constant_buffer == 0, 169 ASSERT_MSG(instr.bra.constant_buffer == 0,
169 "Constant buffer SSY is not supported"); 170 "Constant buffer branching is not supported");
170 const u32 target = offset + instr.bra.GetBranchTarget(); 171 const u32 target = offset + instr.bra.GetBranchTarget();
171 labels.insert(target); 172 labels.insert(target);
172 // Continue scanning for an exit method. 173 // Continue scanning for an exit method.
@@ -1233,27 +1234,27 @@ private:
1233 } 1234 }
1234 1235
1235 /* 1236 /*
1236 * Emits code to push the input target address to the SSY address stack, incrementing the stack 1237 * Emits code to push the input target address to the flow address stack, incrementing the stack
1237 * top. 1238 * top.
1238 */ 1239 */
1239 void EmitPushToSSYStack(u32 target) { 1240 void EmitPushToFlowStack(u32 target) {
1240 shader.AddLine('{'); 1241 shader.AddLine('{');
1241 ++shader.scope; 1242 ++shader.scope;
1242 shader.AddLine("ssy_stack[ssy_stack_top] = " + std::to_string(target) + "u;"); 1243 shader.AddLine("flow_stack[flow_stack_top] = " + std::to_string(target) + "u;");
1243 shader.AddLine("ssy_stack_top++;"); 1244 shader.AddLine("flow_stack_top++;");
1244 --shader.scope; 1245 --shader.scope;
1245 shader.AddLine('}'); 1246 shader.AddLine('}');
1246 } 1247 }
1247 1248
1248 /* 1249 /*
1249 * Emits code to pop an address from the SSY address stack, setting the jump address to the 1250 * Emits code to pop an address from the flow address stack, setting the jump address to the
1250 * popped address and decrementing the stack top. 1251 * popped address and decrementing the stack top.
1251 */ 1252 */
1252 void EmitPopFromSSYStack() { 1253 void EmitPopFromFlowStack() {
1253 shader.AddLine('{'); 1254 shader.AddLine('{');
1254 ++shader.scope; 1255 ++shader.scope;
1255 shader.AddLine("ssy_stack_top--;"); 1256 shader.AddLine("flow_stack_top--;");
1256 shader.AddLine("jmp_to = ssy_stack[ssy_stack_top];"); 1257 shader.AddLine("jmp_to = flow_stack[flow_stack_top];");
1257 shader.AddLine("break;"); 1258 shader.AddLine("break;");
1258 --shader.scope; 1259 --shader.scope;
1259 shader.AddLine('}'); 1260 shader.AddLine('}');
@@ -3265,16 +3266,32 @@ private:
3265 // The SSY opcode tells the GPU where to re-converge divergent execution paths, it 3266 // The SSY opcode tells the GPU where to re-converge divergent execution paths, it
3266 // sets the target of the jump that the SYNC instruction will make. The SSY opcode 3267 // sets the target of the jump that the SYNC instruction will make. The SSY opcode
3267 // has a similar structure to the BRA opcode. 3268 // has a similar structure to the BRA opcode.
3268 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); 3269 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer flow is not supported");
3269 3270
3270 const u32 target = offset + instr.bra.GetBranchTarget(); 3271 const u32 target = offset + instr.bra.GetBranchTarget();
3271 EmitPushToSSYStack(target); 3272 EmitPushToFlowStack(target);
3273 break;
3274 }
3275 case OpCode::Id::PBK: {
3276 // PBK pushes to a stack the address where BRK will jump to. This shares stack with
3277 // SSY but using SYNC on a PBK address will kill the shader execution. We don't
3278 // emulate this because it's very unlikely a driver will emit such invalid shader.
3279 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer PBK is not supported");
3280
3281 const u32 target = offset + instr.bra.GetBranchTarget();
3282 EmitPushToFlowStack(target);
3272 break; 3283 break;
3273 } 3284 }
3274 case OpCode::Id::SYNC: { 3285 case OpCode::Id::SYNC: {
3275 // The SYNC opcode jumps to the address previously set by the SSY opcode 3286 // The SYNC opcode jumps to the address previously set by the SSY opcode
3276 ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); 3287 ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
3277 EmitPopFromSSYStack(); 3288 EmitPopFromFlowStack();
3289 break;
3290 }
3291 case OpCode::Id::BRK: {
3292 // The BRK opcode jumps to the address previously set by the PBK opcode
3293 ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
3294 EmitPopFromFlowStack();
3278 break; 3295 break;
3279 } 3296 }
3280 case OpCode::Id::DEPBAR: { 3297 case OpCode::Id::DEPBAR: {
@@ -3428,11 +3445,11 @@ private:
3428 labels.insert(subroutine.begin); 3445 labels.insert(subroutine.begin);
3429 shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); 3446 shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;");
3430 3447
3431 // TODO(Subv): Figure out the actual depth of the SSY stack, for now it seems 3448 // TODO(Subv): Figure out the actual depth of the flow stack, for now it seems
3432 // unlikely that shaders will use 20 nested SSYs. 3449 // unlikely that shaders will use 20 nested SSYs and PBKs.
3433 constexpr u32 SSY_STACK_SIZE = 20; 3450 constexpr u32 FLOW_STACK_SIZE = 20;
3434 shader.AddLine("uint ssy_stack[" + std::to_string(SSY_STACK_SIZE) + "];"); 3451 shader.AddLine("uint flow_stack[" + std::to_string(FLOW_STACK_SIZE) + "];");
3435 shader.AddLine("uint ssy_stack_top = 0u;"); 3452 shader.AddLine("uint flow_stack_top = 0u;");
3436 3453
3437 shader.AddLine("while (true) {"); 3454 shader.AddLine("while (true) {");
3438 ++shader.scope; 3455 ++shader.scope;