diff options
| author | 2018-11-01 00:34:56 -0400 | |
|---|---|---|
| committer | 2018-11-01 00:34:56 -0400 | |
| commit | 9afcbba8e49ef33c56af08bbed1dcded4bb2bb09 (patch) | |
| tree | be4a7da66ce796ec4b1a48168172c9f9c196748b /src | |
| parent | Merge pull request #1622 from bunnei/fix-macros (diff) | |
| parent | Assert Control Flow Instructions using Control Codes (diff) | |
| download | yuzu-9afcbba8e49ef33c56af08bbed1dcded4bb2bb09.tar.gz yuzu-9afcbba8e49ef33c56af08bbed1dcded4bb2bb09.tar.xz yuzu-9afcbba8e49ef33c56af08bbed1dcded4bb2bb09.zip | |
Merge pull request #1527 from FernandoS27/assert-flow
Assert Control Flow Instructions using Control Codes
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 28 |
2 files changed, 27 insertions, 2 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 27c011e6f..83a6fd875 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1235,6 +1235,7 @@ union Instruction { | |||
| 1235 | BitField<60, 1, u64> is_b_gpr; | 1235 | BitField<60, 1, u64> is_b_gpr; |
| 1236 | BitField<59, 1, u64> is_c_gpr; | 1236 | BitField<59, 1, u64> is_c_gpr; |
| 1237 | BitField<20, 24, s64> smem_imm; | 1237 | BitField<20, 24, s64> smem_imm; |
| 1238 | BitField<0, 5, ControlCode> flow_control_code; | ||
| 1238 | 1239 | ||
| 1239 | Attribute attribute; | 1240 | Attribute attribute; |
| 1240 | Sampler sampler; | 1241 | Sampler sampler; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 601c41f31..09b003c59 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -3474,6 +3474,12 @@ private: | |||
| 3474 | EmitFragmentOutputsWrite(); | 3474 | EmitFragmentOutputsWrite(); |
| 3475 | } | 3475 | } |
| 3476 | 3476 | ||
| 3477 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; | ||
| 3478 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3479 | LOG_CRITICAL(HW_GPU, "EXIT Control Code used: {}", static_cast<u32>(cc)); | ||
| 3480 | UNREACHABLE(); | ||
| 3481 | } | ||
| 3482 | |||
| 3477 | switch (instr.flow.cond) { | 3483 | switch (instr.flow.cond) { |
| 3478 | case Tegra::Shader::FlowCondition::Always: | 3484 | case Tegra::Shader::FlowCondition::Always: |
| 3479 | shader.AddLine("return true;"); | 3485 | shader.AddLine("return true;"); |
| @@ -3503,6 +3509,11 @@ private: | |||
| 3503 | 3509 | ||
| 3504 | // Enclose "discard" in a conditional, so that GLSL compilation does not complain | 3510 | // Enclose "discard" in a conditional, so that GLSL compilation does not complain |
| 3505 | // about unexecuted instructions that may follow this. | 3511 | // about unexecuted instructions that may follow this. |
| 3512 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; | ||
| 3513 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3514 | LOG_CRITICAL(HW_GPU, "KIL Control Code used: {}", static_cast<u32>(cc)); | ||
| 3515 | UNREACHABLE(); | ||
| 3516 | } | ||
| 3506 | shader.AddLine("if (true) {"); | 3517 | shader.AddLine("if (true) {"); |
| 3507 | ++shader.scope; | 3518 | ++shader.scope; |
| 3508 | shader.AddLine("discard;"); | 3519 | shader.AddLine("discard;"); |
| @@ -3560,6 +3571,11 @@ private: | |||
| 3560 | case OpCode::Id::BRA: { | 3571 | case OpCode::Id::BRA: { |
| 3561 | ASSERT_MSG(instr.bra.constant_buffer == 0, | 3572 | ASSERT_MSG(instr.bra.constant_buffer == 0, |
| 3562 | "BRA with constant buffers are not implemented"); | 3573 | "BRA with constant buffers are not implemented"); |
| 3574 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; | ||
| 3575 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3576 | LOG_CRITICAL(HW_GPU, "BRA Control Code used: {}", static_cast<u32>(cc)); | ||
| 3577 | UNREACHABLE(); | ||
| 3578 | } | ||
| 3563 | const u32 target = offset + instr.bra.GetBranchTarget(); | 3579 | const u32 target = offset + instr.bra.GetBranchTarget(); |
| 3564 | shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); | 3580 | shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); |
| 3565 | break; | 3581 | break; |
| @@ -3600,13 +3616,21 @@ private: | |||
| 3600 | } | 3616 | } |
| 3601 | case OpCode::Id::SYNC: { | 3617 | case OpCode::Id::SYNC: { |
| 3602 | // The SYNC opcode jumps to the address previously set by the SSY opcode | 3618 | // The SYNC opcode jumps to the address previously set by the SSY opcode |
| 3603 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | 3619 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; |
| 3620 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3621 | LOG_CRITICAL(HW_GPU, "SYNC Control Code used: {}", static_cast<u32>(cc)); | ||
| 3622 | UNREACHABLE(); | ||
| 3623 | } | ||
| 3604 | EmitPopFromFlowStack(); | 3624 | EmitPopFromFlowStack(); |
| 3605 | break; | 3625 | break; |
| 3606 | } | 3626 | } |
| 3607 | case OpCode::Id::BRK: { | 3627 | case OpCode::Id::BRK: { |
| 3608 | // The BRK opcode jumps to the address previously set by the PBK opcode | 3628 | // The BRK opcode jumps to the address previously set by the PBK opcode |
| 3609 | ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); | 3629 | const Tegra::Shader::ControlCode cc = instr.flow_control_code; |
| 3630 | if (cc != Tegra::Shader::ControlCode::T) { | ||
| 3631 | LOG_CRITICAL(HW_GPU, "BRK Control Code used: {}", static_cast<u32>(cc)); | ||
| 3632 | UNREACHABLE(); | ||
| 3633 | } | ||
| 3610 | EmitPopFromFlowStack(); | 3634 | EmitPopFromFlowStack(); |
| 3611 | break; | 3635 | break; |
| 3612 | } | 3636 | } |