WIP: perf(vk): fix the late pages on the GPU, word by word, instead of waiting for their write-back #248
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!248
Loading…
Reference in a new issue
No description provided.
Delete branch "GummiNaomi/Longshot:perf/late-pages-fix"
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?
Why
In busy places (Lon Lon Ranch by day, crowds, many characters) the game drops from 60 to 50-55 fps, and on some PCs to the 30s, because the renderer waits on the CPU every frame for the GPU to finish writing an earlier frame's results back to game memory: "late pages". At Lon Lon Ranch that wait is ~4.7 ms of a 17.8 ms frame; a player with an RTX 5090 measured ~5.8 ms a frame with 15-30 ms spikes, and an RTX 3080 player saw 31-34 fps (NotRexed/Hookshot#2655, #2789's thread). This removes the wait on PCs whose pools have VRAM mirrors.
What changed
gpu/vk/vk_memory.cpp, the block// ---- the late pages' fix (longshot, 2026-11-13) ----; newgpu/vk/shaders/late_fix.comp):take_capturecopies the late pages again with no wait.late_fix_buildthen records, for the write-backs still on the GPU, which words they wrote.late_fix_emitdispatcheslate_fix.comp, which writes those words into the capture's buffer before anything copies out of it:mirror_sync,mirror_make, the write-back. The result is word for word what the wait's copy gave.late_fix_build):wb_diff.compnow stamps the submission's value on exactly the words it changes, in 64 KB stamp blocks tied to the pool's write-back shadow.note_direct_write, now recorded inwb_direct);late_fix_cpu_read).shadow_sync_copy,shadow_synced_known,RX_VK_SHADOW_FOLLOWS_SYNC). This fixes an existing write-back bug the fix exposed: the diff put stale words back over newer CPU writes every frame. In OoT, the per-character animation records' padding (0x6f6f6f6f) went back over floats the CPU had written, which showed as black flashes in a play test of an earlier version.RX_VK_LATE_FIX=0, underRX_VK_PARALLEL>1, or when the pipeline can't be made. Capture buffers get storage/address usage only with the fix on.tests/test_late_fix_build.py: when a capture gets a fix and when it waits.tests/test_wb_shadow_follows_sync.pytests/test_late_fix_shaders.py: the shaders' structs match the C++ ones, and the SPIR-V headers match their sources.Flags and settings
RX_VK_LATE_FIX=0: the late pages' wait, as beforeRX_VK_SHADOW_FOLLOWS_SYNC=0: the write-back shadow is filled from guest memory at the write-back, as beforeBoth are documented in
docs/development.mdbesideRX_VK_WB_DIFF.Measurements
WIP: the Longshot A/B (main @
2e1e2e8cagainst this PR, the ranch, interleaved) is queued. The numbers below come from the same change on Hookshot, with the switch off and on in one build.Baseline:
Hookshot perf/late-fix @ 56fbc038, RX_VK_LATE_FIX=0(the wait, as main)Why not main: measured before the move to Longshot. To be replaced by main @
2e1e2e8cagainst this PR.Hardware: RTX 4070 SUPER 12 GB, NVIDIA 617.42, i7-14700K, 32 GB, Windows 11 Pro 26200
Scene: Lon Lon Ranch at noon, 2560x1440 DLAA, cap 60, unattended scripted run (
ranch-day3), 90 s eachMethod: the frame trace (
RX_VK_FRAME_TRACE=1), 2-second windows at presents 1920-4800; the slow stretch is presents 3840-4320; three runs: on, off, onHow to reproduce: a save on the grass by Lon Lon Ranch,
!cheat 112(noon), stand and turn;RX_VK_FRAME_TRACE=1On build 134 (before review, same method): fix on 57.9-60.2 fps, median 16.4-16.5 ms, 19-23 frames over 20 ms of 481; off 53.1-55.8 fps, 18.4 ms, 48.
Correctness (a TEMP verify patch, not part of this PR): every late page's bytes after the fix were compared with what the wait would have copied.
Testing
Tested:
RX_VK_FLASH=1) at the ranch and in Kokiri Forest;mirror_makereading before the fix;Not tested:
Needs other testers:
RX_VK_LATE_FIX=0against default. Expect the late-pages wait gone (the frame trace'slate_wait_ms~0) and no flashes (request to open).Screenshots
Nothing on screen (frame pacing only); flash-detector runs found nothing.
Risk and rollback
A wrong word in a capture would show as a one-frame artifact (a flash). Every case that can't be exact falls back to the old wait, and the verify found 0 differing words. To turn it off:
RX_VK_LATE_FIX=0, andRX_VK_SHADOW_FOLLOWS_SYNC=0for the shadow part. Reverting the commit is also enough.Reviewer notes
late_fix_build(when it fixes and when it waits) andlate_fix_emit(where it records).fix(vk)PR if you prefer.Issues
See NotRexed/Hookshot#2655 (the late-pages wait). No Longshot issue yet.
Checklist
For everyone
type(scope): description).main.python -I -B tests/run_all.pyrun and passing: the checks reading the changed files ran (39/39). The full run is still to do on this PC, where some unrelated checks don't build (they also fail on main here).third_party/untouched (a new folder with aPROVENANCE.mdinstead).If applicable
Assisted-by:/Co-Authored-By:trailers.docs/tested-configurations.mdfor each measured run (with the Longshot A/B).mainand passing here.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.