mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 05:46:56 +01:00
shader: emit a real ballot for S_CMP on an exec mask
S_CMP_{EQ,LG}_U64 against a mask operand and zero is the idiom for 'are any
lanes live'. Treating it as a scalar compare loses the per-lane information, so
emit an actual ballot for that shape.
This commit is contained in:
@@ -22,6 +22,33 @@ Decoder::Operand ConditionOperand(Decoder::OperandKind kind) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
bool IsMaskOperand(const Decoder::Operand& operand) {
|
||||||
|
return operand.kind == Decoder::OperandKind::VccLo ||
|
||||||
|
operand.kind == Decoder::OperandKind::ExecLo || operand.kind == Decoder::OperandKind::Sgpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsZeroConstant(const Decoder::Operand& operand) {
|
||||||
|
return (operand.kind == Decoder::OperandKind::LiteralConstant ||
|
||||||
|
operand.kind == Decoder::OperandKind::IntegerInlineConstant) &&
|
||||||
|
operand.value == 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool Translator::S_CMP_MASK_ANY(const Decoder::Instruction& inst, bool not_equal) {
|
||||||
|
if (!IsMaskOperand(inst.src0) || !IsZeroConstant(inst.src1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto predicate = ReadMask(inst.src0);
|
||||||
|
const auto ballot = ir.Emit(IR::ValueOpcode::Ballot, {predicate});
|
||||||
|
const auto lo = ir.CompositeExtract(ballot, 0);
|
||||||
|
const auto hi = ir.CompositeExtract(ballot, 1);
|
||||||
|
const auto any =
|
||||||
|
ir.INotEqual(ir.BitwiseOr(lo, hi), IR::U32(IR::Value(0u)));
|
||||||
|
ir.SetScc(not_equal ? any : ir.LogicalNot(any));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Translator::S_SAVEEXEC(const Decoder::Instruction& inst, IR::ValueOpcode operation,
|
void Translator::S_SAVEEXEC(const Decoder::Instruction& inst, IR::ValueOpcode operation,
|
||||||
bool negate_exec, bool negate_source, bool write_64) {
|
bool negate_exec, bool negate_source, bool write_64) {
|
||||||
if (write_64) {
|
if (write_64) {
|
||||||
|
|||||||
Reference in New Issue
Block a user