Vulkan: no exposure flashes without the frame wait (a capture waits only for the write-back of a page it copies) #645
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!645
Loading…
Reference in a new issue
No description provided.
Delete branch "flicker-capture-wait"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This replaces #513's frame wait (each present waiting for its frame's GPU work), which is now on by default on Linux and Windows, with a wait only where the race actually is. The flicker stays gone and the replay can run a frame ahead of the GPU again.
What the frame wait was hiding. The one-frame exposure flashes come from one page that OoT's GPU and CPU both write: the exposure meter. The GPU adds the frame's light into it; the CPU sets the sums back to 0 and fills in the rest. The CPU runs a frame ahead, so its capture of that page could be taken before the GPU's write-back of it had reached guest memory. The mirror sync then copied the page whole, with the GPU's words from the frame before, over the GPU's newer ones, and the exposure stepped for a frame. Waiting at every present closed that window, but for every frame and every page.
Change.
capture_makechecks the pages the CPU wrote against the submissions that write them back (the readback wait's table,wb_pages). When one of those submissions is still on the GPU, the copy waits for it (250 ms at most). Other captures don't wait.vk_timeline_completed/vk_timeline_wait(bounded) invk_replay.cppfor that.RX_VK_WAIT_GPU=<frames>still limits how far ahead the replay may run; unset means no wait, as before #513.RX_VK_CAPTURE_WAIT=0turns the new wait off.About 1 capture in 6 waits, roughly 12 ms each, in Kokiri Forest.
Measured (Linux, RTX 3090, Kokiri Forest, fixed 60 s runs, one-frame flash events counted from the frame log):
RX_VK_CAPTURE_WAIT=0(no wait at all)In-session A/B on main + #523 (same session, toggled): 165 → 0.7 flashes per 1000 frames, normal exposure.
Note on the readback refresh (
e84d467, from #430). Without any wait, refreshing the readback pages from guest memory at each submission makes this flicker much worse here: 16.9 → 192.5 flashes per 1000 frames in an in-session A/B with no wait. With this PR's wait it makes no difference (0.7 vs 0.0 per 1000). That is probably why Windows players saw the flashing come back once the frame wait was off there (issue 574).Not tested: Windows and AMD. The wait only triggers on pages with a write-back still in flight, so it should cost less than the frame wait there too, but I couldn't measure it.