3
0
Fork 0
forked from suyu/suyu

gl_shader_decompiler: F2F: Implement rounding modes.

This commit is contained in:
bunnei 2018-06-06 22:21:29 -04:00
parent 03f877919d
commit 128aeba0f3
2 changed files with 35 additions and 10 deletions

View file

@ -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;

View file

@ -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: