mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2024-12-26 05:05:40 +00:00
Merge pull request #2753 from FernandoS27/float-convert
Shader_Ir: Implement F16 Variants of F2F, F2I, I2F.
This commit is contained in:
commit
cedc1aab4a
|
@ -1023,8 +1023,6 @@ union Instruction {
|
|||
} f2i;
|
||||
|
||||
union {
|
||||
BitField<8, 2, Register::Size> src_size;
|
||||
BitField<10, 2, Register::Size> dst_size;
|
||||
BitField<39, 4, u64> rounding;
|
||||
// H0, H1 extract for F16 missing
|
||||
BitField<41, 1, u64> selector; // Guessed as some games set it, TODO: reverse this value
|
||||
|
|
|
@ -1136,6 +1136,16 @@ private:
|
|||
Type::Float);
|
||||
}
|
||||
|
||||
std::string FCastHalf0(Operation operation) {
|
||||
const std::string op_a = VisitOperand(operation, 0, Type::HalfFloat);
|
||||
return fmt::format("({})[0]", op_a);
|
||||
}
|
||||
|
||||
std::string FCastHalf1(Operation operation) {
|
||||
const std::string op_a = VisitOperand(operation, 0, Type::HalfFloat);
|
||||
return fmt::format("({})[1]", op_a);
|
||||
}
|
||||
|
||||
template <Type type>
|
||||
std::string Min(Operation operation) {
|
||||
return GenerateBinaryCall(operation, "min", type, type, type);
|
||||
|
@ -1292,6 +1302,11 @@ private:
|
|||
return ApplyPrecise(operation, BitwiseCastResult(clamped, Type::HalfFloat));
|
||||
}
|
||||
|
||||
std::string HCastFloat(Operation operation) {
|
||||
const std::string op_a = VisitOperand(operation, 0, Type::Float);
|
||||
return fmt::format("fromHalf2(vec2({}, 0.0f))", op_a);
|
||||
}
|
||||
|
||||
std::string HUnpack(Operation operation) {
|
||||
const std::string operand{VisitOperand(operation, 0, Type::HalfFloat)};
|
||||
const auto value = [&]() -> std::string {
|
||||
|
@ -1732,6 +1747,8 @@ private:
|
|||
&GLSLDecompiler::Negate<Type::Float>,
|
||||
&GLSLDecompiler::Absolute<Type::Float>,
|
||||
&GLSLDecompiler::FClamp,
|
||||
&GLSLDecompiler::FCastHalf0,
|
||||
&GLSLDecompiler::FCastHalf1,
|
||||
&GLSLDecompiler::Min<Type::Float>,
|
||||
&GLSLDecompiler::Max<Type::Float>,
|
||||
&GLSLDecompiler::FCos,
|
||||
|
@ -1792,6 +1809,7 @@ private:
|
|||
&GLSLDecompiler::Absolute<Type::HalfFloat>,
|
||||
&GLSLDecompiler::HNegate,
|
||||
&GLSLDecompiler::HClamp,
|
||||
&GLSLDecompiler::HCastFloat,
|
||||
&GLSLDecompiler::HUnpack,
|
||||
&GLSLDecompiler::HMergeF32,
|
||||
&GLSLDecompiler::HMergeH0,
|
||||
|
|
|
@ -735,6 +735,16 @@ private:
|
|||
return {};
|
||||
}
|
||||
|
||||
Id FCastHalf0(Operation operation) {
|
||||
UNIMPLEMENTED();
|
||||
return {};
|
||||
}
|
||||
|
||||
Id FCastHalf1(Operation operation) {
|
||||
UNIMPLEMENTED();
|
||||
return {};
|
||||
}
|
||||
|
||||
Id HNegate(Operation operation) {
|
||||
UNIMPLEMENTED();
|
||||
return {};
|
||||
|
@ -745,6 +755,11 @@ private:
|
|||
return {};
|
||||
}
|
||||
|
||||
Id HCastFloat(Operation operation) {
|
||||
UNIMPLEMENTED();
|
||||
return {};
|
||||
}
|
||||
|
||||
Id HUnpack(Operation operation) {
|
||||
UNIMPLEMENTED();
|
||||
return {};
|
||||
|
@ -1210,6 +1225,8 @@ private:
|
|||
&SPIRVDecompiler::Unary<&Module::OpFNegate, Type::Float>,
|
||||
&SPIRVDecompiler::Unary<&Module::OpFAbs, Type::Float>,
|
||||
&SPIRVDecompiler::Ternary<&Module::OpFClamp, Type::Float>,
|
||||
&SPIRVDecompiler::FCastHalf0,
|
||||
&SPIRVDecompiler::FCastHalf1,
|
||||
&SPIRVDecompiler::Binary<&Module::OpFMin, Type::Float>,
|
||||
&SPIRVDecompiler::Binary<&Module::OpFMax, Type::Float>,
|
||||
&SPIRVDecompiler::Unary<&Module::OpCos, Type::Float>,
|
||||
|
@ -1270,6 +1287,7 @@ private:
|
|||
&SPIRVDecompiler::Unary<&Module::OpFAbs, Type::HalfFloat>,
|
||||
&SPIRVDecompiler::HNegate,
|
||||
&SPIRVDecompiler::HClamp,
|
||||
&SPIRVDecompiler::HCastFloat,
|
||||
&SPIRVDecompiler::HUnpack,
|
||||
&SPIRVDecompiler::HMergeF32,
|
||||
&SPIRVDecompiler::HMergeH0,
|
||||
|
|
|
@ -57,7 +57,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
|
|||
case OpCode::Id::I2F_R:
|
||||
case OpCode::Id::I2F_C:
|
||||
case OpCode::Id::I2F_IMM: {
|
||||
UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word);
|
||||
UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
|
||||
UNIMPLEMENTED_IF(instr.conversion.selector);
|
||||
UNIMPLEMENTED_IF_MSG(instr.generates_cc,
|
||||
"Condition codes generation in I2F is not implemented");
|
||||
|
@ -82,14 +82,19 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
|
|||
value = GetOperandAbsNegFloat(value, false, instr.conversion.negate_a);
|
||||
|
||||
SetInternalFlagsFromFloat(bb, value, instr.generates_cc);
|
||||
|
||||
if (instr.conversion.dst_size == Register::Size::Short) {
|
||||
value = Operation(OperationCode::HCastFloat, PRECISE, value);
|
||||
}
|
||||
|
||||
SetRegister(bb, instr.gpr0, value);
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::F2F_R:
|
||||
case OpCode::Id::F2F_C:
|
||||
case OpCode::Id::F2F_IMM: {
|
||||
UNIMPLEMENTED_IF(instr.conversion.f2f.dst_size != Register::Size::Word);
|
||||
UNIMPLEMENTED_IF(instr.conversion.f2f.src_size != Register::Size::Word);
|
||||
UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
|
||||
UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long);
|
||||
UNIMPLEMENTED_IF_MSG(instr.generates_cc,
|
||||
"Condition codes generation in F2F is not implemented");
|
||||
|
||||
|
@ -107,6 +112,11 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
|
|||
}
|
||||
}();
|
||||
|
||||
if (instr.conversion.src_size == Register::Size::Short) {
|
||||
// TODO: figure where extract is sey in the encoding
|
||||
value = Operation(OperationCode::FCastHalf0, PRECISE, value);
|
||||
}
|
||||
|
||||
value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);
|
||||
|
||||
value = [&]() {
|
||||
|
@ -124,19 +134,24 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
|
|||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented F2F rounding mode {}",
|
||||
static_cast<u32>(instr.conversion.f2f.rounding.Value()));
|
||||
return Immediate(0);
|
||||
return value;
|
||||
}
|
||||
}();
|
||||
value = GetSaturatedFloat(value, instr.alu.saturate_d);
|
||||
|
||||
SetInternalFlagsFromFloat(bb, value, instr.generates_cc);
|
||||
|
||||
if (instr.conversion.dst_size == Register::Size::Short) {
|
||||
value = Operation(OperationCode::HCastFloat, PRECISE, value);
|
||||
}
|
||||
|
||||
SetRegister(bb, instr.gpr0, value);
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::F2I_R:
|
||||
case OpCode::Id::F2I_C:
|
||||
case OpCode::Id::F2I_IMM: {
|
||||
UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word);
|
||||
UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long);
|
||||
UNIMPLEMENTED_IF_MSG(instr.generates_cc,
|
||||
"Condition codes generation in F2I is not implemented");
|
||||
Node value = [&]() {
|
||||
|
@ -153,6 +168,11 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
|
|||
}
|
||||
}();
|
||||
|
||||
if (instr.conversion.src_size == Register::Size::Short) {
|
||||
// TODO: figure where extract is sey in the encoding
|
||||
value = Operation(OperationCode::FCastHalf0, PRECISE, value);
|
||||
}
|
||||
|
||||
value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);
|
||||
|
||||
value = [&]() {
|
||||
|
|
|
@ -30,6 +30,8 @@ enum class OperationCode {
|
|||
FNegate, /// (MetaArithmetic, float a) -> float
|
||||
FAbsolute, /// (MetaArithmetic, float a) -> float
|
||||
FClamp, /// (MetaArithmetic, float value, float min, float max) -> float
|
||||
FCastHalf0, /// (MetaArithmetic, f16vec2 a) -> float
|
||||
FCastHalf1, /// (MetaArithmetic, f16vec2 a) -> float
|
||||
FMin, /// (MetaArithmetic, float a, float b) -> float
|
||||
FMax, /// (MetaArithmetic, float a, float b) -> float
|
||||
FCos, /// (MetaArithmetic, float a) -> float
|
||||
|
@ -83,17 +85,18 @@ enum class OperationCode {
|
|||
UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
|
||||
UBitCount, /// (MetaArithmetic, uint) -> uint
|
||||
|
||||
HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
|
||||
HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
|
||||
HFma, /// (MetaArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
|
||||
HAbsolute, /// (f16vec2 a) -> f16vec2
|
||||
HNegate, /// (f16vec2 a, bool first, bool second) -> f16vec2
|
||||
HClamp, /// (f16vec2 src, float min, float max) -> f16vec2
|
||||
HUnpack, /// (Tegra::Shader::HalfType, T value) -> f16vec2
|
||||
HMergeF32, /// (f16vec2 src) -> float
|
||||
HMergeH0, /// (f16vec2 dest, f16vec2 src) -> f16vec2
|
||||
HMergeH1, /// (f16vec2 dest, f16vec2 src) -> f16vec2
|
||||
HPack2, /// (float a, float b) -> f16vec2
|
||||
HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
|
||||
HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
|
||||
HFma, /// (MetaArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
|
||||
HAbsolute, /// (f16vec2 a) -> f16vec2
|
||||
HNegate, /// (f16vec2 a, bool first, bool second) -> f16vec2
|
||||
HClamp, /// (f16vec2 src, float min, float max) -> f16vec2
|
||||
HCastFloat, /// (MetaArithmetic, float a) -> f16vec2
|
||||
HUnpack, /// (Tegra::Shader::HalfType, T value) -> f16vec2
|
||||
HMergeF32, /// (f16vec2 src) -> float
|
||||
HMergeH0, /// (f16vec2 dest, f16vec2 src) -> f16vec2
|
||||
HMergeH1, /// (f16vec2 dest, f16vec2 src) -> f16vec2
|
||||
HPack2, /// (float a, float b) -> f16vec2
|
||||
|
||||
LogicalAssign, /// (bool& dst, bool src) -> void
|
||||
LogicalAnd, /// (bool a, bool b) -> bool
|
||||
|
|
Loading…
Reference in a new issue