gl_shader_decompiler: F2F: Implement rounding modes.
This commit is contained in:
parent
03f877919d
commit
128aeba0f3
|
@ -168,13 +168,22 @@ enum class SubOp : u64 {
|
||||||
Min = 0x8,
|
Min = 0x8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class FloatRoundingOp : u64 {
|
enum class F2iRoundingOp : u64 {
|
||||||
None = 0,
|
None = 0,
|
||||||
Floor = 1,
|
Floor = 1,
|
||||||
Ceil = 2,
|
Ceil = 2,
|
||||||
Trunc = 3,
|
Trunc = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class F2fRoundingOp : u64 {
|
||||||
|
None = 0,
|
||||||
|
Pass = 3,
|
||||||
|
Round = 8,
|
||||||
|
Floor = 9,
|
||||||
|
Ceil = 10,
|
||||||
|
Trunc = 11,
|
||||||
|
};
|
||||||
|
|
||||||
enum class UniformType : u64 {
|
enum class UniformType : u64 {
|
||||||
UnsignedByte = 0,
|
UnsignedByte = 0,
|
||||||
SignedByte = 1,
|
SignedByte = 1,
|
||||||
|
@ -314,11 +323,11 @@ union Instruction {
|
||||||
BitField<50, 1, u64> saturate_a;
|
BitField<50, 1, u64> saturate_a;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
BitField<39, 2, FloatRoundingOp> rounding;
|
BitField<39, 2, F2iRoundingOp> rounding;
|
||||||
} f2i;
|
} f2i;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
BitField<39, 4, u64> rounding;
|
BitField<39, 4, F2fRoundingOp> rounding;
|
||||||
} f2f;
|
} f2f;
|
||||||
} conversion;
|
} conversion;
|
||||||
|
|
||||||
|
|
|
@ -1056,10 +1056,27 @@ private:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpCode::Id::F2F_R: {
|
case OpCode::Id::F2F_R: {
|
||||||
// TODO(Subv): Implement rounding operations.
|
|
||||||
ASSERT_MSG(instr.conversion.f2f.rounding == 0, "Unimplemented rounding operation");
|
|
||||||
std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
|
std::string op_a = regs.GetRegisterAsFloat(instr.gpr20);
|
||||||
|
|
||||||
|
switch (instr.conversion.f2f.rounding) {
|
||||||
|
case Tegra::Shader::F2fRoundingOp::None:
|
||||||
|
break;
|
||||||
|
case Tegra::Shader::F2fRoundingOp::Floor:
|
||||||
|
op_a = "floor(" + op_a + ')';
|
||||||
|
break;
|
||||||
|
case Tegra::Shader::F2fRoundingOp::Ceil:
|
||||||
|
op_a = "ceil(" + op_a + ')';
|
||||||
|
break;
|
||||||
|
case Tegra::Shader::F2fRoundingOp::Trunc:
|
||||||
|
op_a = "trunc(" + op_a + ')';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NGLOG_CRITICAL(HW_GPU, "Unimplemented f2f rounding mode {}",
|
||||||
|
static_cast<u32>(instr.conversion.f2f.rounding.Value()));
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (instr.conversion.abs_a) {
|
if (instr.conversion.abs_a) {
|
||||||
op_a = "abs(" + op_a + ')';
|
op_a = "abs(" + op_a + ')';
|
||||||
}
|
}
|
||||||
|
@ -1074,17 +1091,16 @@ private:
|
||||||
op_a = "abs(" + op_a + ')';
|
op_a = "abs(" + op_a + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
using Tegra::Shader::FloatRoundingOp;
|
|
||||||
switch (instr.conversion.f2i.rounding) {
|
switch (instr.conversion.f2i.rounding) {
|
||||||
case FloatRoundingOp::None:
|
case Tegra::Shader::F2iRoundingOp::None:
|
||||||
break;
|
break;
|
||||||
case FloatRoundingOp::Floor:
|
case Tegra::Shader::F2iRoundingOp::Floor:
|
||||||
op_a = "floor(" + op_a + ')';
|
op_a = "floor(" + op_a + ')';
|
||||||
break;
|
break;
|
||||||
case FloatRoundingOp::Ceil:
|
case Tegra::Shader::F2iRoundingOp::Ceil:
|
||||||
op_a = "ceil(" + op_a + ')';
|
op_a = "ceil(" + op_a + ')';
|
||||||
break;
|
break;
|
||||||
case FloatRoundingOp::Trunc:
|
case Tegra::Shader::F2iRoundingOp::Trunc:
|
||||||
op_a = "trunc(" + op_a + ')';
|
op_a = "trunc(" + op_a + ')';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Reference in New Issue