Merge pull request #654 from bunnei/cond-exit
gl_shader_decompiler: Use FlowCondition field in EXIT instruction.
This commit is contained in:
commit
52636f67cc
|
@ -201,6 +201,11 @@ enum class IMinMaxExchange : u64 {
|
||||||
XHi = 3,
|
XHi = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class FlowCondition : u64 {
|
||||||
|
Always = 0xF,
|
||||||
|
Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for?
|
||||||
|
};
|
||||||
|
|
||||||
union Instruction {
|
union Instruction {
|
||||||
Instruction& operator=(const Instruction& instr) {
|
Instruction& operator=(const Instruction& instr) {
|
||||||
value = instr.value;
|
value = instr.value;
|
||||||
|
@ -315,6 +320,10 @@ union Instruction {
|
||||||
}
|
}
|
||||||
} bfe;
|
} bfe;
|
||||||
|
|
||||||
|
union {
|
||||||
|
BitField<0, 5, FlowCondition> cond;
|
||||||
|
} flow;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
BitField<48, 1, u64> negate_b;
|
BitField<48, 1, u64> negate_b;
|
||||||
BitField<49, 1, u64> negate_c;
|
BitField<49, 1, u64> negate_c;
|
||||||
|
|
|
@ -1639,16 +1639,32 @@ private:
|
||||||
shader.AddLine("color.a = " + regs.GetRegisterAsFloat(3) + ';');
|
shader.AddLine("color.a = " + regs.GetRegisterAsFloat(3) + ';');
|
||||||
}
|
}
|
||||||
|
|
||||||
shader.AddLine("return true;");
|
switch (instr.flow.cond) {
|
||||||
if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) {
|
case Tegra::Shader::FlowCondition::Always:
|
||||||
// If this is an unconditional exit then just end processing here, otherwise
|
shader.AddLine("return true;");
|
||||||
// we have to account for the possibility of the condition not being met, so
|
if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) {
|
||||||
// continue processing the next instruction.
|
// If this is an unconditional exit then just end processing here,
|
||||||
offset = PROGRAM_END - 1;
|
// otherwise we have to account for the possibility of the condition
|
||||||
|
// not being met, so continue processing the next instruction.
|
||||||
|
offset = PROGRAM_END - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tegra::Shader::FlowCondition::Fcsm_Tr:
|
||||||
|
// TODO(bunnei): What is this used for? If we assume this conditon is not
|
||||||
|
// satisifed, dual vertex shaders in Farming Simulator make more sense
|
||||||
|
LOG_CRITICAL(HW_GPU, "Skipping unknown FlowCondition::Fcsm_Tr");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_CRITICAL(HW_GPU, "Unhandled flow condition: {}",
|
||||||
|
static_cast<u32>(instr.flow.cond.Value()));
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpCode::Id::KIL: {
|
case OpCode::Id::KIL: {
|
||||||
|
ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
|
||||||
shader.AddLine("discard;");
|
shader.AddLine("discard;");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1669,8 +1685,9 @@ private:
|
||||||
// can ignore this when generating GLSL code.
|
// can ignore this when generating GLSL code.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpCode::Id::DEPBAR:
|
case OpCode::Id::SYNC:
|
||||||
case OpCode::Id::SYNC: {
|
ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
|
||||||
|
case OpCode::Id::DEPBAR: {
|
||||||
// TODO(Subv): Find out if we actually have to care about these instructions or if
|
// TODO(Subv): Find out if we actually have to care about these instructions or if
|
||||||
// the GLSL compiler takes care of that for us.
|
// the GLSL compiler takes care of that for us.
|
||||||
LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed");
|
LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed");
|
||||||
|
|
Reference in New Issue