shader: allocate split-wave dispatcher spill IDs in program order

This commit is contained in:
Mr. Big Britches authored and nmzik committed 2026-10-20 15:21:19 +02:00
1 parent feed075a9f
commit f0e462a8a2
1 file changed
+9 -8
@@ -623,6 +623,12 @@ void EmitProgram(EmitterState& state) {
} }
if (state.program.dispatcher_fallback) { if (state.program.dispatcher_fallback) {
auto& dispatch = dispatcher.emplace(); auto& dispatch = dispatcher.emplace();
// Allocate both halves in program order so the SPIR-V is identical across runs.
const auto add_spill = [&](const IR::Inst* inst) {
for (uint32_t half = 0; half < state.lane_count; half++) {
dispatch.spills[half].emplace(inst, state.builder.AllocateId());
}
};
for (const auto* block: program.blocks) { for (const auto* block: program.blocks) {
for (const auto& inst: *block) { for (const auto& inst: *block) {
if (inst.GetOpcode() != IR::ValueOpcode::Phi) { if (inst.GetOpcode() != IR::ValueOpcode::Phi) {
@@ -632,7 +638,7 @@ void EmitProgram(EmitterState& state) {
ctx.Fail(inst, "cannot be stored by the dispatcher"); ctx.Fail(inst, "cannot be stored by the dispatcher");
break; break;
} }
dispatch.spills[0].emplace(&inst, state.builder.AllocateId()); add_spill(&inst);
} }
} }
const auto mark_cross_block = [&](IR::Value value, const IR::Block* consumer) { const auto mark_cross_block = [&](IR::Value value, const IR::Block* consumer) {
@@ -647,7 +653,7 @@ void EmitProgram(EmitterState& state) {
return; return;
} }
if (!dispatch.spills[0].contains(definition)) { if (!dispatch.spills[0].contains(definition)) {
dispatch.spills[0].emplace(definition, state.builder.AllocateId()); add_spill(definition);
} }
}; };
for (const auto* block: program.blocks) { for (const auto* block: program.blocks) {
@@ -669,12 +675,7 @@ void EmitProgram(EmitterState& state) {
dispatch.continue_label = state.builder.AllocateId(); dispatch.continue_label = state.builder.AllocateId();
dispatch.merge_label = state.builder.AllocateId(); dispatch.merge_label = state.builder.AllocateId();
ctx.dispatcher_spills = &dispatch.spills[0]; ctx.dispatcher_spills = &dispatch.spills[0];
if (state.lane_count == 2) { high.dispatcher_spills = &dispatch.spills[1];
for (const auto& [inst, id]: dispatch.spills[0]) {
dispatch.spills[1].emplace(inst, state.builder.AllocateId());
}
high.dispatcher_spills = &dispatch.spills[1];
}
} }
DefineGetBdaPointer(state); DefineGetBdaPointer(state);
DefineIndirectBufferLoads(ctx); DefineIndirectBufferLoads(ctx);