diff options
| author | 2018-10-19 12:17:02 -0400 | |
|---|---|---|
| committer | 2018-10-28 19:16:41 -0400 | |
| commit | 3aa8b644a921020beb91109f284ae86dc2f7e189 (patch) | |
| tree | fb5430bbc80ebae720492760b82d2f4986298ce8 /src | |
| parent | Merge pull request #1607 from FearlessTobi/patch-3 (diff) | |
| download | yuzu-3aa8b644a921020beb91109f284ae86dc2f7e189.tar.gz yuzu-3aa8b644a921020beb91109f284ae86dc2f7e189.tar.xz yuzu-3aa8b644a921020beb91109f284ae86dc2f7e189.zip | |
Assert Control Flow Instructions using Control Codes
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 28 |
2 files changed, 28 insertions, 3 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 141b9159b..55763332e 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1232,6 +1232,7 @@ union Instruction { | |||
| 1232 | BitField<60, 1, u64> is_b_gpr; | 1232 | BitField<60, 1, u64> is_b_gpr; |
| 1233 | BitField<59, 1, u64> is_c_gpr; | 1233 | BitField<59, 1, u64> is_c_gpr; |
| 1234 | BitField<20, 24, s64> smem_imm; | 1234 | BitField<20, 24, s64> smem_imm; |
| 1235 | BitField<0, 5, ControlCode> flow_control_code; | ||
| 1235 | 1236 | ||
| 1236 | Attribute attribute; | 1237 | Attribute attribute; |
| 1237 | Sampler sampler; | 1238 | Sampler sampler; |
| @@ -1658,4 +1659,4 @@ private: | |||
| 1658 | } | 1659 | } |
| 1659 | }; | 1660 | }; |
| 1660 | 1661 | ||
| 1661 | } // namespace Tegra::Shader \ No newline at end of file | 1662 | } // namespace Tegra::Shader |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index dcf6941b0..087baf9ed 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -3375,6 +3375,12 @@ private: | |||
| 3375 | EmitFragmentOutputsWrite(); | 3375 | EmitFragmentOutputsWrite(); |
| 3376 | } | 3376 | } |
| 3377 | 3377 | ||
| 3378 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; | ||
| 3379 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3380 | LOG_CRITICAL(HW_GPU, "EXIT Control Code used: {}", static_cast<u32>(cc)); | ||
| 3381 | UNREACHABLE(); | ||
| 3382 | } | ||
| 3383 | |||
| 3378 | switch (instr.flow.cond) { | 3384 | switch (instr.flow.cond) { |
| 3379 | case Tegra::Shader::FlowCondition::Always: | 3385 | case Tegra::Shader::FlowCondition::Always: |
| 3380 | shader.AddLine("return true;"); | 3386 | shader.AddLine("return true;"); |
| @@ -3404,6 +3410,11 @@ private: | |||
| 3404 | 3410 | ||
| 3405 | // Enclose "discard" in a conditional, so that GLSL compilation does not complain | 3411 | // Enclose "discard" in a conditional, so that GLSL compilation does not complain |
| 3406 | // about unexecuted instructions that may follow this. | 3412 | // about unexecuted instructions that may follow this. |
| 3413 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; | ||
| 3414 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3415 | LOG_CRITICAL(HW_GPU, "KIL Control Code used: {}", static_cast<u32>(cc)); | ||
| 3416 | UNREACHABLE(); | ||
| 3417 | } | ||
| 3407 | shader.AddLine("if (true) {"); | 3418 | shader.AddLine("if (true) {"); |
| 3408 | ++shader.scope; | 3419 | ++shader.scope; |
| 3409 | shader.AddLine("discard;"); | 3420 | shader.AddLine("discard;"); |
| @@ -3461,6 +3472,11 @@ private: | |||
| 3461 | case OpCode::Id::BRA: { | 3472 | case OpCode::Id::BRA: { |
| 3462 | ASSERT_MSG(instr.bra.constant_buffer == 0, | 3473 | ASSERT_MSG(instr.bra.constant_buffer == 0, |
| 3463 | "BRA with constant buffers are not implemented"); | 3474 | "BRA with constant buffers are not implemented"); |
| 3475 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; | ||
| 3476 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3477 | LOG_CRITICAL(HW_GPU, "BRA Control Code used: {}", static_cast<u32>(cc)); | ||
| 3478 | UNREACHABLE(); | ||
| 3479 | } | ||
| 3464 | const u32 target = offset + instr.bra.GetBranchTarget(); | 3480 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 3465 | shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); | 3481 | shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); |
| 3466 | break; | 3482 | break; |
| @@ -3501,13 +3517,21 @@ private: | |||
| 3501 | } | 3517 | } |
| 3502 | case OpCode::Id::SYNC: { | 3518 | case OpCode::Id::SYNC: { |
| 3503 | // The SYNC opcode jumps to the address previously set by the SSY opcode | 3519 | // The SYNC opcode jumps to the address previously set by the SSY opcode |
| 3504 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | 3520 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; |
| 3521 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3522 | LOG_CRITICAL(HW_GPU, "SYNC Control Code used: {}", static_cast<u32>(cc)); | ||
| 3523 | UNREACHABLE(); | ||
| 3524 | } | ||
| 3505 | EmitPopFromFlowStack(); | 3525 | EmitPopFromFlowStack(); |
| 3506 | break; | 3526 | break; |
| 3507 | } | 3527 | } |
| 3508 | case OpCode::Id::BRK: { | 3528 | case OpCode::Id::BRK: { |
| 3509 | // The BRK opcode jumps to the address previously set by the PBK opcode | 3529 | // The BRK opcode jumps to the address previously set by the PBK opcode |
| 3510 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | 3530 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; |
| 3531 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3532 | LOG_CRITICAL(HW_GPU, "BRK Control Code used: {}", static_cast<u32>(cc)); | ||
| 3533 | UNREACHABLE(); | ||
| 3534 | } | ||
| 3511 | EmitPopFromFlowStack(); | 3535 | EmitPopFromFlowStack(); |
| 3512 | break; | 3536 | break; |
| 3513 | } | 3537 | } |