yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

Assert Control Flow Instructions using Control Codes

This commit is contained in:
FernandoS27 2018-10-19 12:17:02 -04:00
parent b5f8a5f0a3
commit 3aa8b644a9
2 changed files with 28 additions and 3 deletions

View File

@ -1232,6 +1232,7 @@ union Instruction {
BitField<60, 1, u64> is_b_gpr; BitField<60, 1, u64> is_b_gpr;
BitField<59, 1, u64> is_c_gpr; BitField<59, 1, u64> is_c_gpr;
BitField<20, 24, s64> smem_imm; BitField<20, 24, s64> smem_imm;
BitField<0, 5, ControlCode> flow_control_code;
Attribute attribute; Attribute attribute;
Sampler sampler; Sampler sampler;
@ -1658,4 +1659,4 @@ private:
} }
}; };
} // namespace Tegra::Shader } // namespace Tegra::Shader

View File

@ -3375,6 +3375,12 @@ private:
EmitFragmentOutputsWrite(); EmitFragmentOutputsWrite();
} }
const Tegra::Shader::ControlCode cc = instr.flow_control_code;
if (cc != Tegra::Shader::ControlCode::T) {
LOG_CRITICAL(HW_GPU, "EXIT Control Code used: {}", static_cast<u32>(cc));
UNREACHABLE();
}
switch (instr.flow.cond) { switch (instr.flow.cond) {
case Tegra::Shader::FlowCondition::Always: case Tegra::Shader::FlowCondition::Always:
shader.AddLine("return true;"); shader.AddLine("return true;");
@ -3404,6 +3410,11 @@ private:
// Enclose "discard" in a conditional, so that GLSL compilation does not complain // Enclose "discard" in a conditional, so that GLSL compilation does not complain
// about unexecuted instructions that may follow this. // about unexecuted instructions that may follow this.
const Tegra::Shader::ControlCode cc = instr.flow_control_code;
if (cc != Tegra::Shader::ControlCode::T) {
LOG_CRITICAL(HW_GPU, "KIL Control Code used: {}", static_cast<u32>(cc));
UNREACHABLE();
}
shader.AddLine("if (true) {"); shader.AddLine("if (true) {");
++shader.scope; ++shader.scope;
shader.AddLine("discard;"); shader.AddLine("discard;");
@ -3461,6 +3472,11 @@ private:
case OpCode::Id::BRA: { case OpCode::Id::BRA: {
ASSERT_MSG(instr.bra.constant_buffer == 0, ASSERT_MSG(instr.bra.constant_buffer == 0,
"BRA with constant buffers are not implemented"); "BRA with constant buffers are not implemented");
const Tegra::Shader::ControlCode cc = instr.flow_control_code;
if (cc != Tegra::Shader::ControlCode::T) {
LOG_CRITICAL(HW_GPU, "BRA Control Code used: {}", static_cast<u32>(cc));
UNREACHABLE();
}
const u32 target = offset + instr.bra.GetBranchTarget(); const u32 target = offset + instr.bra.GetBranchTarget();
shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }");
break; break;
@ -3501,13 +3517,21 @@ private:
} }
case OpCode::Id::SYNC: { case OpCode::Id::SYNC: {
// The SYNC opcode jumps to the address previously set by the SSY opcode // The SYNC opcode jumps to the address previously set by the SSY opcode
ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); const Tegra::Shader::ControlCode cc = instr.flow_control_code;
if (cc != Tegra::Shader::ControlCode::T) {
LOG_CRITICAL(HW_GPU, "SYNC Control Code used: {}", static_cast<u32>(cc));
UNREACHABLE();
}
EmitPopFromFlowStack(); EmitPopFromFlowStack();
break; break;
} }
case OpCode::Id::BRK: { case OpCode::Id::BRK: {
// The BRK opcode jumps to the address previously set by the PBK opcode // The BRK opcode jumps to the address previously set by the PBK opcode
ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); const Tegra::Shader::ControlCode cc = instr.flow_control_code;
if (cc != Tegra::Shader::ControlCode::T) {
LOG_CRITICAL(HW_GPU, "BRK Control Code used: {}", static_cast<u32>(cc));
UNREACHABLE();
}
EmitPopFromFlowStack(); EmitPopFromFlowStack();
break; break;
} }