shader: share SMEM load results across emulated wave64 halves

This commit is contained in:
nmzik
2026-10-20 22:32:48 +02:00
parent 1ce663b5a9
commit 8cc5f5364a
@@ -233,14 +233,17 @@ void Invoke(Return (*emit)(Context&, Args...), ValueEmitContext& ctx, const IR::
}
void EmitDirectInstruction(ValueEmitContext& ctx, const IR::Inst& inst) {
if (ctx.half != 0 && (inst.GetOpcode() == IR::ValueOpcode::Ballot ||
inst.GetOpcode() == IR::ValueOpcode::ReadFirstLane ||
inst.GetOpcode() == IR::ValueOpcode::SubgroupUMinU32)) {
// These operations combine both emulated halves into one whole-wave result.
using Op = IR::ValueOpcode;
const auto op = inst.GetOpcode();
if (ctx.half != 0 &&
(op == Op::Ballot || op == Op::ReadFirstLane || op == Op::SubgroupUMinU32 ||
op == Op::ReadConstBuffer ||
(op == Op::LoadAddressU32 && ctx.Memory(inst).kind == IR::ResourceKind::ScalarAddress))) {
// Whole-wave results and SMEM loads (SGPR operands, no EXEC) are identical in both halves.
ctx.Define(inst, ctx.other_half->Result(inst));
return;
}
switch (inst.GetOpcode()) {
switch (op) {
#define VALUE_OPCODE(name, ...) \
case IR::ValueOpcode::name: return Invoke(Emit##name, ctx, inst);
#include "graphics/shader/recompiler/ir/opcodes/ValueOpcodes.inc"