fix(agc): record write_data produced labels so WAIT_REG_MEM can resume (#834)

ApplySubmittedWriteData wrote label values to guest memory but never called
GpuWaitRegistry.RecordProduced, unlike ApplySubmittedReleaseMem. A suspended
WAIT_REG_MEM on a write_data label (e.g. Dead Cells frame fence 0x10243CFD8)
then could never be latched or deadlock-broken: guest memory is reset to 0 for
frame reuse before the next re-check, and _lastProduced had no value to replay.
Record each written dword and, for increment count2, the combined 64-bit value
so 32/64-bit waits latch like ReleaseMem dataSel=2.
This commit is contained in:
angleyanalbedo
2026-08-22 01:18:30 +08:00
committed by GitHub
parent 35a28f0143
commit 3a744c991e
+19
View File
@@ -6478,6 +6478,25 @@ public static partial class AgcExports
var targetAddress = destinationAddress +
(incrementAddress ? (ulong)index * sizeof(uint) : 0);
wroteData = TryWriteUInt32(ctx, targetAddress, values[index]);
if (wroteData)
{
GpuWaitRegistry.RecordProduced(
ctx.Memory, targetAddress, values[index]);
}
}
// Like ReleaseMem dataSel=2: a 64-bit WAIT_REG_MEM watches an
// 8-byte label written as two 32-bit dwords. Record the combined
// 64-bit value so a 64-bit EQ can latch even though the writes
// landed as two 32-bit stores.
if (wroteData && dwordCount >= 2 && incrementAddress)
{
var combined = ((ulong)values[1] << 32) | values[0];
GpuWaitRegistry.RecordProduced(
ctx.Memory, destinationAddress, combined);
// Also latch the high half's address for symmetry: a stray
// 32-bit wait on the high dword should not be confused, but
// recording it does not hurt and mirrors the per-dword stores.
}
if (tracePacket)