mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-06-12 10:37:59 -05:00
shader_ir/decode: Fix half float pre-operations and remove MetaHalfArithmetic
Operations done before the main half float operation (like HAdd) were managing a packed value instead of the unpacked one. Adding an unpacked operation allows us to drop the per-operand MetaHalfArithmetic entry, simplifying the code overall.
This commit is contained in:
@ -29,9 +29,8 @@ u32 ShaderIR::DecodeArithmeticHalf(NodeBlock& bb, u32 pc) {
|
||||
const bool negate_b =
|
||||
opcode->get().GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0;
|
||||
|
||||
const Node op_a = GetOperandAbsNegHalf(GetRegister(instr.gpr8), instr.alu_half.abs_a, negate_a);
|
||||
|
||||
// instr.alu_half.type_a
|
||||
Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.alu_half.type_a);
|
||||
op_a = GetOperandAbsNegHalf(op_a, instr.alu_half.abs_a, negate_a);
|
||||
|
||||
Node op_b = [&]() {
|
||||
switch (opcode->get().GetId()) {
|
||||
@ -46,17 +45,17 @@ u32 ShaderIR::DecodeArithmeticHalf(NodeBlock& bb, u32 pc) {
|
||||
return Immediate(0);
|
||||
}
|
||||
}();
|
||||
op_b = UnpackHalfFloat(op_b, instr.alu_half.type_b);
|
||||
op_b = GetOperandAbsNegHalf(op_b, instr.alu_half.abs_b, negate_b);
|
||||
|
||||
Node value = [&]() {
|
||||
MetaHalfArithmetic meta{true, {instr.alu_half_imm.type_a, instr.alu_half.type_b}};
|
||||
switch (opcode->get().GetId()) {
|
||||
case OpCode::Id::HADD2_C:
|
||||
case OpCode::Id::HADD2_R:
|
||||
return Operation(OperationCode::HAdd, meta, op_a, op_b);
|
||||
return Operation(OperationCode::HAdd, PRECISE, op_a, op_b);
|
||||
case OpCode::Id::HMUL2_C:
|
||||
case OpCode::Id::HMUL2_R:
|
||||
return Operation(OperationCode::HMul, meta, op_a, op_b);
|
||||
return Operation(OperationCode::HMul, PRECISE, op_a, op_b);
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unhandled half float instruction: {}", opcode->get().GetName());
|
||||
return Immediate(0);
|
||||
|
@ -24,18 +24,17 @@ u32 ShaderIR::DecodeArithmeticHalfImmediate(NodeBlock& bb, u32 pc) {
|
||||
UNIMPLEMENTED_IF(instr.alu_half_imm.precision != Tegra::Shader::HalfPrecision::None);
|
||||
}
|
||||
|
||||
Node op_a = GetRegister(instr.gpr8);
|
||||
Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.alu_half_imm.type_a);
|
||||
op_a = GetOperandAbsNegHalf(op_a, instr.alu_half_imm.abs_a, instr.alu_half_imm.negate_a);
|
||||
|
||||
const Node op_b = UnpackHalfImmediate(instr, true);
|
||||
|
||||
Node value = [&]() {
|
||||
MetaHalfArithmetic meta{true, {instr.alu_half_imm.type_a}};
|
||||
switch (opcode->get().GetId()) {
|
||||
case OpCode::Id::HADD2_IMM:
|
||||
return Operation(OperationCode::HAdd, meta, op_a, op_b);
|
||||
return Operation(OperationCode::HAdd, PRECISE, op_a, op_b);
|
||||
case OpCode::Id::HMUL2_IMM:
|
||||
return Operation(OperationCode::HMul, meta, op_a, op_b);
|
||||
return Operation(OperationCode::HMul, PRECISE, op_a, op_b);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Immediate(0);
|
||||
|
@ -22,9 +22,9 @@ u32 ShaderIR::DecodeHalfSet(NodeBlock& bb, u32 pc) {
|
||||
LOG_WARNING(HW_GPU, "{} FTZ not implemented", opcode->get().GetName());
|
||||
}
|
||||
|
||||
// instr.hset2.type_a
|
||||
// instr.hset2.type_b
|
||||
Node op_a = GetRegister(instr.gpr8);
|
||||
Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.hset2.type_a);
|
||||
op_a = GetOperandAbsNegHalf(op_a, instr.hset2.abs_a, instr.hset2.negate_a);
|
||||
|
||||
Node op_b = [&]() {
|
||||
switch (opcode->get().GetId()) {
|
||||
case OpCode::Id::HSET2_R:
|
||||
@ -34,14 +34,12 @@ u32 ShaderIR::DecodeHalfSet(NodeBlock& bb, u32 pc) {
|
||||
return Immediate(0);
|
||||
}
|
||||
}();
|
||||
|
||||
op_a = GetOperandAbsNegHalf(op_a, instr.hset2.abs_a, instr.hset2.negate_a);
|
||||
op_b = UnpackHalfFloat(op_b, instr.hset2.type_b);
|
||||
op_b = GetOperandAbsNegHalf(op_b, instr.hset2.abs_b, instr.hset2.negate_b);
|
||||
|
||||
const Node second_pred = GetPredicate(instr.hset2.pred39, instr.hset2.neg_pred);
|
||||
|
||||
MetaHalfArithmetic meta{false, {instr.hset2.type_a, instr.hset2.type_b}};
|
||||
const Node comparison_pair = GetPredicateComparisonHalf(instr.hset2.cond, meta, op_a, op_b);
|
||||
const Node comparison_pair = GetPredicateComparisonHalf(instr.hset2.cond, op_a, op_b);
|
||||
|
||||
const OperationCode combiner = GetPredicateCombiner(instr.hset2.op);
|
||||
|
||||
|
@ -19,10 +19,10 @@ u32 ShaderIR::DecodeHalfSetPredicate(NodeBlock& bb, u32 pc) {
|
||||
|
||||
UNIMPLEMENTED_IF(instr.hsetp2.ftz != 0);
|
||||
|
||||
Node op_a = GetRegister(instr.gpr8);
|
||||
Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.hsetp2.type_a);
|
||||
op_a = GetOperandAbsNegHalf(op_a, instr.hsetp2.abs_a, instr.hsetp2.negate_a);
|
||||
|
||||
const Node op_b = [&]() {
|
||||
Node op_b = [&]() {
|
||||
switch (opcode->get().GetId()) {
|
||||
case OpCode::Id::HSETP2_R:
|
||||
return GetOperandAbsNegHalf(GetRegister(instr.gpr20), instr.hsetp2.abs_a,
|
||||
@ -32,6 +32,7 @@ u32 ShaderIR::DecodeHalfSetPredicate(NodeBlock& bb, u32 pc) {
|
||||
return Immediate(0);
|
||||
}
|
||||
}();
|
||||
op_b = UnpackHalfFloat(op_b, instr.hsetp2.type_b);
|
||||
|
||||
// We can't use the constant predicate as destination.
|
||||
ASSERT(instr.hsetp2.pred3 != static_cast<u64>(Pred::UnusedIndex));
|
||||
@ -42,8 +43,7 @@ u32 ShaderIR::DecodeHalfSetPredicate(NodeBlock& bb, u32 pc) {
|
||||
const OperationCode pair_combiner =
|
||||
instr.hsetp2.h_and ? OperationCode::LogicalAll2 : OperationCode::LogicalAny2;
|
||||
|
||||
MetaHalfArithmetic meta = {false, {instr.hsetp2.type_a, instr.hsetp2.type_b}};
|
||||
const Node comparison = GetPredicateComparisonHalf(instr.hsetp2.cond, meta, op_a, op_b);
|
||||
const Node comparison = GetPredicateComparisonHalf(instr.hsetp2.cond, op_a, op_b);
|
||||
const Node first_pred = Operation(pair_combiner, comparison);
|
||||
|
||||
// Set the primary predicate to the result of Predicate OP SecondPredicate
|
||||
|
@ -27,10 +27,6 @@ u32 ShaderIR::DecodeHfma2(NodeBlock& bb, u32 pc) {
|
||||
}
|
||||
|
||||
constexpr auto identity = HalfType::H0_H1;
|
||||
|
||||
const HalfType type_a = instr.hfma2.type_a;
|
||||
const Node op_a = GetRegister(instr.gpr8);
|
||||
|
||||
bool neg_b{}, neg_c{};
|
||||
auto [saturate, type_b, op_b, type_c,
|
||||
op_c] = [&]() -> std::tuple<bool, HalfType, Node, HalfType, Node> {
|
||||
@ -62,11 +58,11 @@ u32 ShaderIR::DecodeHfma2(NodeBlock& bb, u32 pc) {
|
||||
}();
|
||||
UNIMPLEMENTED_IF_MSG(saturate, "HFMA2 saturation is not implemented");
|
||||
|
||||
op_b = GetOperandAbsNegHalf(op_b, false, neg_b);
|
||||
op_c = GetOperandAbsNegHalf(op_c, false, neg_c);
|
||||
const Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.hfma2.type_a);
|
||||
op_b = GetOperandAbsNegHalf(UnpackHalfFloat(op_b, type_b), false, neg_b);
|
||||
op_c = GetOperandAbsNegHalf(UnpackHalfFloat(op_c, type_c), false, neg_c);
|
||||
|
||||
MetaHalfArithmetic meta{true, {type_a, type_b, type_c}};
|
||||
Node value = Operation(OperationCode::HFma, meta, op_a, op_b, op_c);
|
||||
Node value = Operation(OperationCode::HFma, PRECISE, op_a, op_b, op_c);
|
||||
value = HalfMerge(GetRegister(instr.gpr0), value, instr.hfma2.merge);
|
||||
|
||||
SetRegister(bb, instr.gpr0, value);
|
||||
|
Reference in New Issue
Block a user