From 4eea3d1c2fdacf072b39ed2ee55b2092c72d9bd4 Mon Sep 17 00:00:00 2001 From: chrg6 Date: Tue, 10 Nov 2026 23:09:17 -0500 Subject: [PATCH] Wait for the write-backs before returning to the game where pools are shadow copies. With shadow storage (the default on Linux and under Wine) what the GPU wrote reaches the game's memory in the completion thread's fence callback, after the executed timeline that the split wait returns at. The game could then rewrite a pool, and an older write-back overwrote what it wrote: in Kokiri Forest a sky coefficient the game had reset came back, and the world flickered and looked washed out. The wait now covers the write-backs whenever shadow storage is in use; with imported or mirrored pools, the Windows default, nothing changes. The contributor's RX 9070 XT under RADV no longer showed the flicker. Co-Authored-By: Claude Fable 5.2 --- runtime/vk_sync.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runtime/vk_sync.c b/runtime/vk_sync.c index 9e7ee07a..cc4a6bb4 100644 --- a/runtime/vk_sync.c +++ b/runtime/vk_sync.c @@ -703,7 +703,11 @@ static int fence_wait_impl(uint64_t value, uint64_t timeout_ns) { // CPU side effects of its fence may still be to come. 1 when reached. int vk_sync_exec_wait(uint64_t value, uint64_t timeout_ns) { vk_sync_start(); - if (!vk_sync_wb_split()) return vk_sync_fence_wait(value, timeout_ns); + // With shadow storage (vk_mem_shadow_storage) what the GPU wrote reaches guest memory in the completion thread's + // fence callback, after the executed timeline: a wait that returned there let the game rewrite a pool that an + // older write-back then overwrote (Kokiri Forest: a sky coefficient the game had reset came back, and the world + // flickered washed out). So the wait covers the write-backs there, as without the split. + if (vk_mem_shadow_storage() || !vk_sync_wb_split()) return vk_sync_fence_wait(value, timeout_ns); if (__atomic_load_n(&done, __ATOMIC_ACQUIRE) >= value) return 1; uint64_t p0 = perf_begin(); hold_release(value, 0, 0); // a held submission the waiter needs goes to the queue now