summaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/video_core/engines/shader_bytecode.h10
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp55
2 files changed, 43 insertions, 22 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index d3095089c..ac50bb622 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -1213,11 +1213,13 @@ public:
1213 KIL, 1213 KIL,
1214 SSY, 1214 SSY,
1215 SYNC, 1215 SYNC,
1216 BRK,
1216 DEPBAR, 1217 DEPBAR,
1217 BFE_C, 1218 BFE_C,
1218 BFE_R, 1219 BFE_R,
1219 BFE_IMM, 1220 BFE_IMM,
1220 BRA, 1221 BRA,
1222 PBK,
1221 LD_A, 1223 LD_A,
1222 LD_C, 1224 LD_C,
1223 ST_A, 1225 ST_A,
@@ -1374,7 +1376,7 @@ public:
1374 /// conditionally executed). 1376 /// conditionally executed).
1375 static bool IsPredicatedInstruction(Id opcode) { 1377 static bool IsPredicatedInstruction(Id opcode) {
1376 // TODO(Subv): Add the rest of unpredicated instructions. 1378 // TODO(Subv): Add the rest of unpredicated instructions.
1377 return opcode != Id::SSY; 1379 return opcode != Id::SSY && opcode != Id::PBK;
1378 } 1380 }
1379 1381
1380 class Matcher { 1382 class Matcher {
@@ -1470,9 +1472,11 @@ private:
1470#define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) 1472#define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name)
1471 INST("111000110011----", Id::KIL, Type::Flow, "KIL"), 1473 INST("111000110011----", Id::KIL, Type::Flow, "KIL"),
1472 INST("111000101001----", Id::SSY, Type::Flow, "SSY"), 1474 INST("111000101001----", Id::SSY, Type::Flow, "SSY"),
1475 INST("111000101010----", Id::PBK, Type::Flow, "PBK"),
1473 INST("111000100100----", Id::BRA, Type::Flow, "BRA"), 1476 INST("111000100100----", Id::BRA, Type::Flow, "BRA"),
1477 INST("1111000011111---", Id::SYNC, Type::Flow, "SYNC"),
1478 INST("111000110100---", Id::BRK, Type::Flow, "BRK"),
1474 INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"), 1479 INST("1111000011110---", Id::DEPBAR, Type::Synch, "DEPBAR"),
1475 INST("1111000011111---", Id::SYNC, Type::Synch, "SYNC"),
1476 INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), 1480 INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"),
1477 INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), 1481 INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"),
1478 INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"), 1482 INST("1110111111110---", Id::ST_A, Type::Memory, "ST_A"),
@@ -1610,4 +1614,4 @@ private:
1610 } 1614 }
1611}; 1615};
1612 1616
1613} // namespace Tegra::Shader 1617} // namespace Tegra::Shader \ No newline at end of file
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;