summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-11-01 00:34:56 -0400
committerGravatar GitHub2018-11-01 00:34:56 -0400
commit9afcbba8e49ef33c56af08bbed1dcded4bb2bb09 (patch)
treebe4a7da66ce796ec4b1a48168172c9f9c196748b /src
parentMerge pull request #1622 from bunnei/fix-macros (diff)
parentAssert Control Flow Instructions using Control Codes (diff)
downloadyuzu-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.h1
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp28
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 }