graphics: preserve FP16 inline constants

This commit is contained in:
nmzik
2026-08-20 18:39:17 +02:00
parent 129c64235f
commit d5410a93c8
6 changed files with 56 additions and 9 deletions
@@ -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;