mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-19 18:36:53 +02:00
graphics: preserve FP16 inline constants
This commit is contained in:
@@ -16,11 +16,12 @@ bool Translator::TranslatePackedFloat16(const IR::Instruction& inst) {
|
||||
default: return false;
|
||||
}
|
||||
const auto translate_lane = [&](bool high) {
|
||||
const auto lhs = ReadF16LaneAsF32(inst.src[0], high);
|
||||
const auto rhs = ReadF16LaneAsF32(inst.src[1], high);
|
||||
const auto lhs = ReadF16LaneAsF32(inst.src[0], high, true);
|
||||
const auto rhs = ReadF16LaneAsF32(inst.src[1], high, true);
|
||||
IR::F32 result;
|
||||
if (inst.src_count == 3u) {
|
||||
result = IR::F32(ir.Emit(opcode, {lhs, rhs, ReadF16LaneAsF32(inst.src[2], high)}));
|
||||
result = IR::F32(
|
||||
ir.Emit(opcode, {lhs, rhs, ReadF16LaneAsF32(inst.src[2], high, true)}));
|
||||
} else {
|
||||
result = IR::F32(ir.Emit(opcode, {lhs, rhs}));
|
||||
}
|
||||
|
||||
@@ -456,7 +456,21 @@ IR::U64 Translator::ReadU64(const IR::Operand& operand) {
|
||||
return IR::U64(ReadOperand(operand, IR::Type::U64));
|
||||
}
|
||||
|
||||
IR::F32 Translator::ReadF16LaneAsF32(const IR::Operand& operand, bool high_lane) {
|
||||
IR::F32 Translator::ReadF16LaneAsF32(const IR::Operand& operand, bool high_lane, bool packed) {
|
||||
if (operand.float_inline) {
|
||||
const bool use_zero = packed && (high_lane ? operand.op_sel_hi : operand.op_sel);
|
||||
auto value = use_zero ? IR::F32(IR::Value::F32(0.0f))
|
||||
: ir.BitCastF32(IR::U32(IR::Value(operand.imm)));
|
||||
const auto half = IR::F16(ir.Emit(IR::ValueOpcode::ConvertF16F32, {value}));
|
||||
value = IR::F32(ir.Emit(IR::ValueOpcode::ConvertF32F16, {half}));
|
||||
if (operand.absolute) {
|
||||
value = IR::F32(ir.Emit(IR::ValueOpcode::FPAbs32, {value}));
|
||||
}
|
||||
if (high_lane ? operand.negate_hi : operand.negate) {
|
||||
value = IR::F32(ir.Emit(IR::ValueOpcode::FPNeg32, {value}));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
auto raw_operand = operand;
|
||||
raw_operand.sdwa_sel = 6;
|
||||
raw_operand.sdwa_sext = false;
|
||||
|
||||
@@ -38,7 +38,8 @@ private:
|
||||
IR::U32 ReadU32(const IR::Operand& operand);
|
||||
std::array<IR::U32, 2> ReadU32Pair(const IR::Operand& operand);
|
||||
IR::U64 ReadU64(const IR::Operand& operand);
|
||||
IR::F32 ReadF16LaneAsF32(const IR::Operand& operand, bool high_lane);
|
||||
IR::F32 ReadF16LaneAsF32(const IR::Operand& operand, bool high_lane,
|
||||
bool packed = false);
|
||||
IR::F32 ReadF16AsF32(const IR::Operand& operand);
|
||||
IR::F32 ReadMixF32(const IR::Operand& operand);
|
||||
IR::U32 ReadU16LaneRaw(const IR::Operand& operand, bool high_lane);
|
||||
|
||||
@@ -157,10 +157,11 @@ bool LowerSourceOperand(const Decoder::Operand& decoded, Operand& operand, std::
|
||||
case Decoder::OperandKind::FloatInlineConstant:
|
||||
operand = {};
|
||||
CopyOperandModifiers(decoded, operand);
|
||||
operand.kind = OperandKind::ImmediateU32;
|
||||
operand.imm = decoded.value;
|
||||
operand.sext_64 = decoded.kind == Decoder::OperandKind::IntegerInlineConstant &&
|
||||
decoded.signed_val < 0;
|
||||
operand.kind = OperandKind::ImmediateU32;
|
||||
operand.imm = decoded.value;
|
||||
operand.float_inline = decoded.kind == Decoder::OperandKind::FloatInlineConstant;
|
||||
operand.sext_64 = decoded.kind == Decoder::OperandKind::IntegerInlineConstant &&
|
||||
decoded.signed_val < 0;
|
||||
return true;
|
||||
case Decoder::OperandKind::Null:
|
||||
case Decoder::OperandKind::PopsExitingWaveId:
|
||||
|
||||
@@ -37,6 +37,7 @@ struct Operand {
|
||||
OperandKind kind = OperandKind::Null;
|
||||
Register reg;
|
||||
uint32_t imm = 0;
|
||||
bool float_inline = false;
|
||||
bool sext_64 = false;
|
||||
uint32_t sdwa_sel = 6;
|
||||
uint32_t sdwa_dst_unused = 2;
|
||||
|
||||
@@ -13867,6 +13867,34 @@ TestCase VectorVop3FmaF16UsesRdna2Opcode34b() {
|
||||
{O::V_MOV_B32, O::V_FMA_F16, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||
}
|
||||
|
||||
TestCase FloatInlineConstantF16UsesNumericValue() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
std::vector<u32> code;
|
||||
AppendVMovLiteral(&code, 1, 0x38003800u); // 0.5h, 0.5h
|
||||
AppendVMovLiteral(&code, 2, 0x3c003c00u); // 1.0h, 1.0h
|
||||
AppendVMovLiteral(&code, 10, 0xaaaa0000u);
|
||||
AppendVMovLiteral(&code, 12, 0xbbbb0000u);
|
||||
|
||||
AppendVop3(&code, 0x34bu, 10, 246u, Vgpr(1), Vgpr(2));
|
||||
AppendVop3p(&code, 0x0eu, 11, 246u, Vgpr(1), Vgpr(2), 0x1u);
|
||||
AppendVop3(&code, 0x34bu, 12, 248u, 242u, 128u);
|
||||
|
||||
AppendStoreVgpr(&code, 10, 0);
|
||||
AppendStoreVgpr(&code, 11, 1);
|
||||
AppendStoreVgpr(&code, 12, 2);
|
||||
AppendEnd(&code);
|
||||
|
||||
TestCase test;
|
||||
test.name = "FloatInlineConstantF16UsesNumericValue";
|
||||
test.code = std::move(code);
|
||||
test.expected = {0xaaaa4200u, 0x3c004200u, 0xbbbb3118u};
|
||||
test.opcodes = {O::V_MOV_B32, O::V_FMA_F16, O::V_PK_FMA_F16,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
test.decoded_counts = {{"4.000000", 2}, {"0.159155", 1}};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase VectorFloatControlContractPreservesInfNan() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
@@ -18941,6 +18969,7 @@ std::vector<TestCase> MakeCases() {
|
||||
AddCase(MadMixF16LiteralHalfSourceUsesOpsel);
|
||||
AddCase(MadMixF16NegHiIsAbsAndNegIsIndependent);
|
||||
AddCase(VectorVop3FmaF16UsesRdna2Opcode34b);
|
||||
AddCase(FloatInlineConstantF16UsesNumericValue);
|
||||
AddCase(VectorFloatControlContractPreservesInfNan);
|
||||
AddCase(VectorFloatArithmeticOps);
|
||||
AddCase(VectorMinMaxF32NanAndSignedZeroEdges);
|
||||
|
||||
Reference in New Issue
Block a user