WIP: Vulkan: no one-frame exposure flashes from the CPU overwriting GPU-written words (stopgap: frame wait) #513
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!513
Loading…
Reference in a new issue
No description provided.
Delete branch "flicker-frame-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?
Fixes the one-frame brightness flashes (haze, sun shafts, exposure jumping for a frame) on Linux.
OoT's CPU and GPU overlap: the CPU prepares frame N+1 while the GPU is still on frame N, and some of OoT's queues submit work before what it depends on is ready (the console's GPU simply waits). #523 fixes the queue-ordering side; this PR fixes the remaining race.
Depends on #523 (merge that first). Measured on the same build, 90 s each, Kokiri Forest:
The fix: each present waits for its frame's GPU work
The flashes left after the queue-ordering fixes in #523. Some data is written by both the GPU and the CPU (parameters the passes before the exposure meter read). The GPU's writes reach guest memory only when its frame finishes, but the CPU, already on the next frame, wrote to the same 4 KB page before that and the page's capture held the GPU's old words; the capture's sync then put those old words over the GPU's new ones. That frame's scene, and the exposure meter's samples of it, came out too bright, and the exposure reacted the frame after (flashes came in pairs).
Stopgap: this change is meant to be replaced once the proper fix (WIP, see Notes) lands; it trades a frame of CPU/GPU overlap for correctness until then.
The present now waits for its frame's submissions, so the GPU's writes have landed before the CPU's next capture.
RX_VK_WAIT_GPU=-1: no wait (old behaviour);=<n>: n frames ahead.In-session A/B on an RTX 3090 (the wait toggled every 15 s in one session, so both halves see the same scenes; flashes counted from the frame log):
Mean brightness unchanged (86.8 / 86.8 in run 1), ~60 fps both ways. Also played normally on Linux: no flashes.
Notes
Marking this as a draft: I've traced the remaining race to a single page that both the CPU and GPU write, and I'm working on an updated fix that syncs only the words the CPU actually changed there. That should keep the CPU/GPU overlap instead of waiting at every present. I'll update this PR when it's tested.