shader: keep pixel helper lanes out of the EXEC and VCC words

This commit is contained in:
nmzik committed 2026-10-26 07:43:11 +01:00
1 parent 025d1f7edf
commit 5429888d4c
20 files changed
+428 -390

No files matched your search

@@ -5,30 +5,20 @@
namespace Libs::Graphics::ShaderRecompiler::Frontend {
void Translator::EmitCompareResult(const Decoder::Instruction& inst, IR::U1 value, bool scalar,
bool cmpx) {
void Translator::EmitCompareResult(const Decoder::Instruction& inst, IR::U1 value, bool scalar) {
if (scalar) {
ir.SetScc(value);
return;
}
const auto masked = ir.LogicalAnd(ir.GetExec(), value);
if (cmpx) {
const auto mask = BallotMask(masked);
ir.SetExec(masked);
ir.SetExecLo(mask[0]);
ir.SetExecHi(mask[1]);
return;
}
WriteMask(inst.dst, masked);
WriteVectorMask(inst.dst, value);
}
void Translator::EmitCompareConstant(const Decoder::Instruction& inst, bool value, bool scalar,
bool cmpx) {
EmitCompareResult(inst, IR::U1(IR::Value(value)), scalar, cmpx);
void Translator::EmitCompareConstant(const Decoder::Instruction& inst, bool value, bool scalar) {
EmitCompareResult(inst, IR::U1(IR::Value(value)), scalar);
}
void Translator::EmitIntegerCompare(const Decoder::Instruction& inst, IR::ValueOpcode opcode,
IR::Type type, bool scalar, bool cmpx, bool swap_operands) {
IR::Type type, bool scalar, bool swap_operands) {
// The equality compares share their IR opcode with the unsigned ones.
const bool signed_64 = opcode == IR::ValueOpcode::SLessThan64 ||
opcode == IR::ValueOpcode::SLessThanEqual64 ||
@@ -49,18 +39,18 @@ void Translator::EmitIntegerCompare(const Decoder::Instruction& inst, IR::ValueO
if (swap_operands) {
std::swap(lhs, rhs);
}
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs})), scalar, cmpx);
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs})), scalar);
}
void Translator::EmitInteger16Compare(const Decoder::Instruction& inst, IR::ValueOpcode opcode,
bool signed_value, bool cmpx) {
bool signed_value) {
const auto lhs = ReadU16AsU32(inst.src0, signed_value);
const auto rhs = ReadU16AsU32(inst.src1, signed_value);
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs})), false, cmpx);
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs})), false);
}
void Translator::EmitFloatCompare(const Decoder::Instruction& inst, IR::ValueOpcode opcode,
bool half, bool cmpx) {
bool half) {
const auto type = IR::ArgTypeOf(opcode, 0);
const auto lhs =
half ? IR::Value(ReadF16AsF32(inst.src0)) : ReadOperand(inst.src0, type);
@@ -68,10 +58,10 @@ void Translator::EmitFloatCompare(const Decoder::Instruction& inst, IR::ValueOpc
half ? IR::Value(ReadF16AsF32(inst.src1)) : ReadOperand(inst.src1, type);
const IR::FPCompareFlags flags{
.flush_input_denorms = !half && type == IR::Type::F32 && flush_f32_inputs};
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs}, flags)), false, cmpx);
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs}, flags)), false);
}
void Translator::EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered, bool cmpx,
void Translator::EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered,
bool is64) {
const auto type = is64 ? IR::Type::F64 : IR::Type::F32;
const auto is_nan_op = is64 ? IR::ValueOpcode::FPIsNan64 : IR::ValueOpcode::FPIsNan32;
@@ -79,16 +69,16 @@ void Translator::EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool
const auto rhs = ReadOperand(inst.src1, type);
const auto unordered = ir.LogicalOr(IR::U1(ir.Emit(is_nan_op, {lhs})),
IR::U1(ir.Emit(is_nan_op, {rhs})));
EmitCompareResult(inst, ordered ? ir.LogicalNot(unordered) : unordered, false, cmpx);
EmitCompareResult(inst, ordered ? ir.LogicalNot(unordered) : unordered, false);
}
void Translator::EmitFloatClassCompare(const Decoder::Instruction& inst, bool cmpx, bool half) {
void Translator::EmitFloatClassCompare(const Decoder::Instruction& inst, bool half) {
const auto value = half ? IR::Value(Read16LaneBits(inst.src0, false))
: ReadOperand(inst.src0, IR::Type::F32);
const auto mask = half ? IR::Value(Read16LaneBits(inst.src1, false))
: ReadOperand(inst.src1, IR::Type::U32);
const auto opcode = half ? IR::ValueOpcode::FPCmpClass16 : IR::ValueOpcode::FPCmpClass32;
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {value, mask})), false, cmpx);
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {value, mask})), false);
}
} // namespace Libs::Graphics::ShaderRecompiler::Frontend