mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: implement RDNA2 frexp mantissa
This commit is contained in:
@@ -567,6 +567,7 @@ std::string OpcodeToString(Opcode opcode) {
|
||||
case Opcode::VCvtRpiI32F32: return "v_cvt_rpi_i32_f32";
|
||||
case Opcode::VCvtFlrI32F32: return "v_cvt_flr_i32_f32";
|
||||
case Opcode::VFrexpExpI32F32: return "v_frexp_exp_i32_f32";
|
||||
case Opcode::VFrexpMantF32: return "v_frexp_mant_f32";
|
||||
case Opcode::VCvtOffF32I4: return "v_cvt_off_f32_i4";
|
||||
case Opcode::VCvtF32Ubyte0: return "v_cvt_f32_ubyte0";
|
||||
case Opcode::VCvtF32Ubyte1: return "v_cvt_f32_ubyte1";
|
||||
|
||||
@@ -152,6 +152,7 @@ enum class Opcode {
|
||||
VCvtRpiI32F32,
|
||||
VCvtFlrI32F32,
|
||||
VFrexpExpI32F32,
|
||||
VFrexpMantF32,
|
||||
VCvtOffF32I4,
|
||||
VCvtF32Ubyte0,
|
||||
VCvtF32Ubyte1,
|
||||
|
||||
@@ -121,6 +121,7 @@ constexpr OpcodeMap VOP1_OPCODE_LIST[] = {
|
||||
{0x39u, Opcode::VFfbhU32},
|
||||
{0x3au, Opcode::VFfblB32},
|
||||
{0x3fu, Opcode::VFrexpExpI32F32},
|
||||
{0x40u, Opcode::VFrexpMantF32},
|
||||
{0x42u, Opcode::VMovreldB32},
|
||||
{0x43u, Opcode::VMovrelsB32},
|
||||
{0x50u, Opcode::VCvtF16U16},
|
||||
@@ -170,6 +171,7 @@ constexpr OpcodeMap VOP3_ENCODED_VOP1_OPCODE_LIST[] = {
|
||||
{0x39u, Opcode::VFfbhU32},
|
||||
{0x3au, Opcode::VFfblB32},
|
||||
{0x3fu, Opcode::VFrexpExpI32F32},
|
||||
{0x40u, Opcode::VFrexpMantF32},
|
||||
{0x42u, Opcode::VMovreldB32},
|
||||
{0x43u, Opcode::VMovrelsB32},
|
||||
{0x50u, Opcode::VCvtF16U16},
|
||||
@@ -413,6 +415,7 @@ bool IsVop1FloatSourceOpcode(Opcode opcode) {
|
||||
case Opcode::VCvtRpiI32F32:
|
||||
case Opcode::VCvtFlrI32F32:
|
||||
case Opcode::VFrexpExpI32F32:
|
||||
case Opcode::VFrexpMantF32:
|
||||
case Opcode::VCvtF16F32:
|
||||
case Opcode::VRcpF32:
|
||||
case Opcode::VRcpIflagF32:
|
||||
@@ -767,6 +770,7 @@ bool IsVop1FloatResultOpcode(Opcode opcode) {
|
||||
case Opcode::VCeilF32:
|
||||
case Opcode::VRndneF32:
|
||||
case Opcode::VFloorF32:
|
||||
case Opcode::VFrexpMantF32:
|
||||
case Opcode::VExpF32:
|
||||
case Opcode::VLogF32:
|
||||
case Opcode::VRsqF32:
|
||||
|
||||
@@ -93,6 +93,26 @@ bool Translator::TranslateFloat16Operation(const IR::Instruction& inst) {
|
||||
}
|
||||
|
||||
bool Translator::TranslateFloatOperation(const IR::Instruction& inst) {
|
||||
if (inst.op == IR::Opcode::FrexpMantF32) {
|
||||
const auto bits = ReadU32(inst.src[0]);
|
||||
const auto exponent = IR::U32(
|
||||
ir.Emit(IR::ValueOpcode::BitFieldUExtract, {bits, IR::Value(23u), IR::Value(8u)}));
|
||||
const auto mantissa = ir.BitwiseAnd(bits, IR::U32(IR::Value(0x007fffffu)));
|
||||
const auto sign = ir.BitwiseAnd(bits, IR::U32(IR::Value(0x80000000u)));
|
||||
const auto base = ir.BitwiseOr(sign, IR::U32(IR::Value(0x3f000000u)));
|
||||
const auto normal = ir.BitwiseOr(base, mantissa);
|
||||
const auto msb = IR::U32(ir.Emit(IR::ValueOpcode::FindUMsb32, {mantissa}));
|
||||
const auto shift = ir.ISub(IR::U32(IR::Value(23u)), msb);
|
||||
const auto fraction =
|
||||
ir.BitwiseAnd(ir.ShiftLeftLogical(mantissa, shift), IR::U32(IR::Value(0x007fffffu)));
|
||||
const auto subnormal = ir.BitwiseOr(base, fraction);
|
||||
const auto zero = ir.IEqual(mantissa, IR::U32(IR::Value(0u)));
|
||||
const auto finite = ir.Select(ir.INotEqual(exponent, IR::U32(IR::Value(0u))), normal,
|
||||
ir.Select(zero, bits, subnormal));
|
||||
const auto result = ir.Select(ir.IEqual(exponent, IR::U32(IR::Value(0xffu))), bits, finite);
|
||||
WriteOperand(inst.dst, ir.BitCastF32(result));
|
||||
return true;
|
||||
}
|
||||
IR::ValueOpcode opcode {};
|
||||
switch (inst.op) {
|
||||
case IR::Opcode::RcpF32: opcode = IR::ValueOpcode::FPRecip32; break;
|
||||
|
||||
@@ -104,6 +104,7 @@ constexpr LowerMap LOWER_OPS[] = {
|
||||
{Decoder::Opcode::VCvtRpiI32F32, Opcode::ConvertRoundPlusInfF32ToI32},
|
||||
{Decoder::Opcode::VCvtFlrI32F32, Opcode::ConvertFloorF32ToI32},
|
||||
{Decoder::Opcode::VFrexpExpI32F32, Opcode::FrexpExpI32F32},
|
||||
{Decoder::Opcode::VFrexpMantF32, Opcode::FrexpMantF32},
|
||||
{Decoder::Opcode::VCvtOffF32I4, Opcode::ConvertI4ToOffsetF32},
|
||||
{Decoder::Opcode::VRcpF32, Opcode::RcpF32},
|
||||
{Decoder::Opcode::VRcpIflagF32, Opcode::RcpIflagF32},
|
||||
|
||||
@@ -214,6 +214,7 @@ IR_OPCODE(ConvertF16ToI16, General, Conversion)
|
||||
IR_OPCODE(ConvertRoundPlusInfF32ToI32, General, Conversion)
|
||||
IR_OPCODE(ConvertFloorF32ToI32, General, Conversion)
|
||||
IR_OPCODE(FrexpExpI32F32, General, Conversion)
|
||||
IR_OPCODE(FrexpMantF32, General, Float)
|
||||
IR_OPCODE(ConvertI4ToOffsetF32, General, Conversion)
|
||||
IR_OPCODE(LdexpF32, General, Float)
|
||||
IR_OPCODE(PackF32ToF16Rtz, General, Conversion)
|
||||
|
||||
Reference in New Issue
Block a user