mirror of
https://gitlab.com/suyu-emu/suyu.git
synced 2024-03-15 23:15:44 +00:00
Merge pull request #458 from Subv/fmnmx
Shaders: Implemented the FMNMX shader instruction.
This commit is contained in:
commit
898f0fa029
|
@ -193,6 +193,11 @@ union Instruction {
|
||||||
BitField<50, 1, u64> abs_d;
|
BitField<50, 1, u64> abs_d;
|
||||||
BitField<56, 1, u64> negate_imm;
|
BitField<56, 1, u64> negate_imm;
|
||||||
|
|
||||||
|
union {
|
||||||
|
BitField<39, 3, u64> pred;
|
||||||
|
BitField<42, 1, u64> negate_pred;
|
||||||
|
} fmnmx;
|
||||||
|
|
||||||
float GetImm20_19() const {
|
float GetImm20_19() const {
|
||||||
float result{};
|
float result{};
|
||||||
u32 imm{static_cast<u32>(imm20_19)};
|
u32 imm{static_cast<u32>(imm20_19)};
|
||||||
|
|
|
@ -580,14 +580,17 @@ private:
|
||||||
* @param instr Instruction to generate the if condition for.
|
* @param instr Instruction to generate the if condition for.
|
||||||
* @returns string containing the predicate condition.
|
* @returns string containing the predicate condition.
|
||||||
*/
|
*/
|
||||||
std::string GetPredicateCondition(Instruction instr) const {
|
std::string GetPredicateCondition(u64 index, bool negate) const {
|
||||||
using Tegra::Shader::Pred;
|
using Tegra::Shader::Pred;
|
||||||
ASSERT(instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex));
|
std::string variable;
|
||||||
|
|
||||||
std::string variable =
|
// Index 7 is used as an 'Always True' condition.
|
||||||
'p' + std::to_string(static_cast<u64>(instr.pred.pred_index.Value()));
|
if (index == static_cast<u64>(Pred::UnusedIndex))
|
||||||
|
variable = "true";
|
||||||
|
else
|
||||||
|
variable = 'p' + std::to_string(index);
|
||||||
|
|
||||||
if (instr.negate_pred) {
|
if (negate) {
|
||||||
return "!(" + variable + ')';
|
return "!(" + variable + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,7 +637,9 @@ private:
|
||||||
"NeverExecute predicate not implemented");
|
"NeverExecute predicate not implemented");
|
||||||
|
|
||||||
if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
|
if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
|
||||||
shader.AddLine("if (" + GetPredicateCondition(instr) + ')');
|
shader.AddLine("if (" +
|
||||||
|
GetPredicateCondition(instr.pred.pred_index, instr.negate_pred != 0) +
|
||||||
|
')');
|
||||||
shader.AddLine('{');
|
shader.AddLine('{');
|
||||||
++shader.scope;
|
++shader.scope;
|
||||||
}
|
}
|
||||||
|
@ -730,6 +735,16 @@ private:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OpCode::Id::FMNMX: {
|
||||||
|
std::string condition =
|
||||||
|
GetPredicateCondition(instr.alu.fmnmx.pred, instr.alu.fmnmx.negate_pred != 0);
|
||||||
|
std::string parameters = op_a + ',' + op_b;
|
||||||
|
regs.SetRegisterToFloat(instr.gpr0, 0,
|
||||||
|
'(' + condition + ") ? min(" + parameters + ") : max(" +
|
||||||
|
parameters + ')',
|
||||||
|
1, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OpCode::Id::RRO: {
|
case OpCode::Id::RRO: {
|
||||||
NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction");
|
NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction");
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue