Vulkan: no one-frame fog/exposure flashes from OoT's queue ordering #523
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!523
Loading…
Reference in a new issue
No description provided.
Delete branch "flicker-queue-order"
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 most of the remaining one-frame flashes on Linux (#371): haze and sun shafts appearing or vanishing for one frame, with the environment brighter or darker while the HUD and characters stay the same.
OoT's presentation queues submit a frame's work before two things it waits for are ready: the scene work (through event waits) and the CPU's writes for that frame (the CPU signals an event when it has finished). Two paths replayed that work against the previous frame's data.
Forced waits. Every NVN queue shared one fence timeline, and it only advanced as far as the oldest submission stopped at a wait. Three things waited on that timeline and pushed the presentation queues' stopped work past its waits:
Fences are now per queue:
nvnQueueFenceSynctakes the queue's own last submission. They are waited on through a second timeline that numbers the recordings. The readbacks no longer force anything through.RX_VK_PER_QUEUE_FENCES=0restores the old behaviour.Stale captures. The memory capture was taken at submit time, so it held the previous frame's data. Now a submission stopped at a wait for a CPU-signalled event takes a fresh capture of the CPU's writes when it resumes, because the console's GPU reads memory after its wait.
RX_VK_RESUME_CAPTURE=0turns this off.Measured on Linux with an RTX 3090: Kokiri Forest save, standing still, 60 s frame log on a 75 Hz monitor, one-frame events counted with
scripts/framelog.py.ba594dac)The frame rate goes up because the main thread no longer blocks on the other queues' stopped work.
Diagnosis:
Known gaps:
The branch is rebased onto current main and includes the RADV hang fix for batched submits (
Vulkan: batched submits signal the recordings' timeline, reported in #415 by azlekayn: withRX_VK_BATCH, RADV's default since #413, the recordings' timeline was never signalled and the game hung before the first movie). The test now checkstake_capture(), which both capture paths share, forcap_view_bump(). The numbers above were measured onba594dac.More numbers, with #513's frame wait applied (same build, 90 s each, Kokiri Forest): with this PR 0 and 1 flash events at ~50 fps; without it (
RX_VK_PER_QUEUE_FENCES=0 RX_VK_RESUME_CAPTURE=0) 45 and 19 events at ~38 fps. #513 depends on this one.Tested on Linux: CachyOS (KDE Wayland), RTX 3080 Laptop 8 GB, driver 615.78, SDL3, 3D resolution 50%.
The failing "Python source checks" job isn't caused by this PR: the branch predates
2d3faa3("test: cover chunk prefetch in the import-window fixture"), so its copy ofnx2/test_import_windows.pydoesn't know the prefetch code invk_memory.cpp. Main's version of the test passes against this branch'svk_memory.cpp, and the branch merges into current main without conflicts, so a rebase should turn it green.Results: the same build each time, with this PR on or off (
RX_VK_PER_QUEUE_FENCES=0 RX_VK_RESUME_CAPTURE=0). Same save in Kakariko Village, camera untouched for 120 s, runs alternated:So about 20-30% faster with it on, the same direction as your Kokiri numbers. In this still scene there were no fog/exposure flashes to remove either way (the few the frame recorder flagged were Navi's glow moving, identical before and after), so I can't confirm the flash fix itself from this test, only that nothing new flickers with it on.