diff options
| author | 2018-10-23 00:01:38 -0400 | |
|---|---|---|
| committer | 2018-10-23 00:01:38 -0400 | |
| commit | 848a49112a774cd95fe1a600f1acdfec7aefcc6d (patch) | |
| tree | c1d6bf385df694f4c0789a766a041b175daeefe9 /src/video_core/renderer_opengl | |
| parent | Merge pull request #1550 from FernandoS27/fmul32 (diff) | |
| parent | gl_shader_decompiler: Implement PBK and BRK (diff) | |
| download | yuzu-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.cpp | 55 |
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; |