vk: a readback's wait flushes the held batch (FR_READBACK) #1905
Closed
kafasam wants to merge 1 commit from
readback-flush-only into main
pull from: readback-flush-only
merge into: MagicBeanDev:main
MagicBeanDev:main
MagicBeanDev:github/pr/2893
MagicBeanDev:github/pr/2890
MagicBeanDev:github/pr/2887
MagicBeanDev:github/pr/2878
MagicBeanDev:github/pr/2875
MagicBeanDev:github/pr/2874
MagicBeanDev:github/pr/2873
MagicBeanDev:github/pr/2871
MagicBeanDev:github/pr/2756
MagicBeanDev:github/pr/2897
MagicBeanDev:github/pr/2896
MagicBeanDev:github/pr/2718
MagicBeanDev:github/pr/2842
MagicBeanDev:github/pr/2691
MagicBeanDev:github/pr/2895
MagicBeanDev:github/pr/2743
MagicBeanDev:github/pr/2765
MagicBeanDev:github/pr/2708
MagicBeanDev:github/pr/2732
MagicBeanDev:github/pr/2755
MagicBeanDev:github/pr/2817
MagicBeanDev:github/pr/2876
MagicBeanDev:release-please--branches--main
MagicBeanDev:release-please--branches--main--release-notes
MagicBeanDev:github/pr/2778
MagicBeanDev:github/pr/2888
MagicBeanDev:github/pr/2866
MagicBeanDev:github/pr/2877
MagicBeanDev:github/pr/2800
MagicBeanDev:github/pr/2829
MagicBeanDev:github/pr/2850
MagicBeanDev:github/pr/2889
MagicBeanDev:github/pr/2882
MagicBeanDev:github/pr/2860
MagicBeanDev:github/pr/2849
MagicBeanDev:github/pr/2886
MagicBeanDev:github/pr/2794
MagicBeanDev:github/pr/2840
MagicBeanDev:github/pr/2830
MagicBeanDev:github/pr/2834
MagicBeanDev:github/pr/2719
MagicBeanDev:github/pr/2742
MagicBeanDev:github/pr/2741
MagicBeanDev:github/pr/2820
MagicBeanDev:github/pr/2771
MagicBeanDev:github/pr/2859
MagicBeanDev:github/pr/2858
MagicBeanDev:github/pr/2823
MagicBeanDev:github/pr/2757
MagicBeanDev:github/pr/2769
MagicBeanDev:github/pr/2844
MagicBeanDev:github/pr/2843
MagicBeanDev:github/pr/2673
MagicBeanDev:github/pr/2855
MagicBeanDev:github/pr/2739
MagicBeanDev:github/pr/2807
MagicBeanDev:github/pr/2851
MagicBeanDev:github/pr/2789
MagicBeanDev:github/pr/2814
MagicBeanDev:github/pr/2818
MagicBeanDev:github/pr/2774
MagicBeanDev:github/pr/2772
MagicBeanDev:github/pr/2750
MagicBeanDev:github/pr/2786
MagicBeanDev:github/pr/2785
MagicBeanDev:github/pr/2782
MagicBeanDev:github/pr/2779
MagicBeanDev:github/pr/2775
MagicBeanDev:github/pr/2706
MagicBeanDev:github/pr/2766
MagicBeanDev:github/pr/2747
MagicBeanDev:github/pr/2759
MagicBeanDev:github/pr/2745
MagicBeanDev:github/pr/2740
MagicBeanDev:github/pr/2733
MagicBeanDev:github/pr/2725
MagicBeanDev:github/pr/2727
MagicBeanDev:github/pr/2728
MagicBeanDev:github/pr/2729
MagicBeanDev:github/pr/2721
MagicBeanDev:github/pr/2722
MagicBeanDev:github/pr/2715
MagicBeanDev:github/pr/2714
MagicBeanDev:github/pr/2707
MagicBeanDev:github/pr/2703
MagicBeanDev:github/pr/2705
MagicBeanDev:github/pr/2697
MagicBeanDev:github/pr/2679
MagicBeanDev:github/pr/2676
MagicBeanDev:github/pr/2669
MagicBeanDev:docs/what-hookshot-connects-to
MagicBeanDev:fix/hdr-encode-test
MagicBeanDev:fix/main-tests
MagicBeanDev:fix/play-cache-files
MagicBeanDev:perf/game-barrier-order
MagicBeanDev:feat/heap-lazy
MagicBeanDev:feat/texture-detail
MagicBeanDev:perf/astc-opaque-bc1
MagicBeanDev:fix/fs-dir-lock
MagicBeanDev:fix/framegen-native-kept
MagicBeanDev:fix/update-no-downgrade
MagicBeanDev:port/k10-gcn-f16-mirrors
MagicBeanDev:fix/framegen-mult-cap
MagicBeanDev:chore/release-as-2.1.1
MagicBeanDev:perf/pcache-load-switch
MagicBeanDev:fix/prepare-progress-log
MagicBeanDev:fix/update-closes-stale-game
MagicBeanDev:fix/hdr-scaled-sampled
MagicBeanDev:perf/first-start-preset
MagicBeanDev:perf/zero-upload
MagicBeanDev:fix/vcore-escape-2s
MagicBeanDev:test/fake-gh-atomic
MagicBeanDev:perf/batch-idle-flush
MagicBeanDev:test/finish-stub-a
MagicBeanDev:chore/record-2.1.0
MagicBeanDev:fix/main-red-tests
MagicBeanDev:fix/test-display-startup-driver-cache
MagicBeanDev:feat/mesh-shader-mode
MagicBeanDev:fix/menu-probes-at-startup
MagicBeanDev:fix/fps-counter-classic
MagicBeanDev:fix/test-log-batch-flake
MagicBeanDev:fix/narrow-screen-hud
MagicBeanDev:ci/prereleases
MagicBeanDev:release/v2.0.15
MagicBeanDev:hotfix/v2.0.15
MagicBeanDev:fix/present-ahead-replay
MagicBeanDev:release/v2.0.13
MagicBeanDev:fix/bracket-paths-2013
MagicBeanDev:fix/hdr-overlays-2013
MagicBeanDev:fix/fps-counter-scale-2013
MagicBeanDev:fix/stick-seen-at-rest
MagicBeanDev:hotfix/menu-fits-screen
MagicBeanDev:fix/f1-always-opens-menu
MagicBeanDev:fix/ini-keep-lines
MagicBeanDev:claude/cranky-pike-7cf247
MagicBeanDev:perf/texture-answer-flat
MagicBeanDev:fix/stamp-test-modules
MagicBeanDev:fix/appimage-fonts
MagicBeanDev:fix/display-awake
MagicBeanDev:release/v2.0.12
MagicBeanDev:fix/discord-windows
MagicBeanDev:rc/v2.0.12-tests
MagicBeanDev:fix/dlss-keep-feature
MagicBeanDev:rc/v2.0.12
MagicBeanDev:button-icons
No reviewers
Labels
Clear labels
accessibility
Barrier affecting people with disabilities
autorelease: pending
autorelease: tagged
bug
Something isn't working
dependencies
Pull requests that update a dependency file
documentation
Improvements or additions to documentation
duplicate
This issue or pull request already exists
enhancement
New feature or request
github_actions
Pull requests that update GitHub Actions code
good first issue
Good for newcomers
help wanted
Extra attention is needed
invalid
This doesn't seem right
question
Further information is requested
testing wanted
wontfix
This will not be worked on
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
Milestone
Clear milestone
No items
No milestone
Assignees
Clear assignees
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!1905
Loading…
Reference in a new issue
No description provided.
Delete branch "readback-flush-only"
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?
What
When a readback waits for a GPU write-back, the held command buffer batch is flushed before the wait, so the GPU starts processing it immediately instead of waiting for the next present. This closes the ~23-28ms readback latency bubble measured in the graveyard investigation.
Why
The investigation measured 163 of 3000 reads waiting 23-28ms because results only landed when the display thread's present flushed the batch (flush reasons were 60/61 "present"). The code's own design comment at vk_replay.cpp line 132 promised a readback flush that was never wired.
Changes (one file, ~20 lines)
FR_READBACKin the batch enum, printed in the stats log linerec_outtracks the recordings' timeline value the last flush sentwait_recorded()fires only when the exact recording being waited on is still held in the batchSafety
wait_recordedcall sites hold no locks (present_mu is a leaf)RX_VK_BATCH=0the pend is always empty so it never firesRX_VK_ASYNC=1the readback goes throughwait_value()which already flushes — this fix is load-bearing on sync mode onlyTesting
Built and deployed on RX 6700 XT. With
RX_VK_ASYNC=1the readback counter reads 0 (expected — the async path already flushes). WithRX_VK_ASYNC=0(sync), the fix addresses the measured 23-28ms bubble.AI assistance disclosure: the analysis and fix were developed with AI assistance, verified and tested by a human on the affected hardware.
Would this fix the write-read wait from #1133?
Yes — this addresses the same class of problem as #1133. The readback wait in
wait_recorded()was the sync-mode path where the batch wasn't flushed before waiting (the design comment at vk_replay.cpp line 132 promised a readback flush that was never wired). WithRX_VK_ASYNC=1the async path (wait_value()) already flushes, which is why the bubble was only measured in sync mode. This fix wires the flush for the sync path, closing the gap for both configurations.I built it as AppImage and I can confirm the texture flickering that #1133 fixed returned. Does this need a rebase?
Thanks for chasing the readback bubble. The diagnosis is right, but main already has this fix: #1276 (merged yesterday, after this branch's base) put an unconditional
queue_flush_for(FR_WAIT)at the top ofwait_recorded(), so in sync mode the held batch already goes out before the wait. Against main this PR has nothing left to add, and it conflicts there (the branch is ~920 commits behind and GitHub shows it as unmergeable). No CI ran on it either.Two other things:
8716b2996(the FSR 1 EASU+RCAS commit: two shaders, their SPIR-V headers and ~170 lines invk_draw.cpp). That's #1439's work, and an older copy of it than #1439's head, so merging this would bring in the upscaler without its review. #1906 is stacked the same way: it carries this commit and the FSR one under its ownvk_memory.cppchange. Each of these should be its own branch off current main.If you still want something here after rebasing, the gating you added (flush only when
seq > rec_out, with its ownFR_READBACKreason in the stats line) could be a small follow-up on top of #1276's flush, if it measurably cuts flushes. But on main the bubble should already be gone, so I'd close this one in favour of #1276.Main has
queue_flush_for(FR_WAIT);at this point already (#1276). It flushes whenever the batch is non-empty, so theseq > rec_outcheck only narrows that. If you keep the narrowing, put it on top of main's version, and therec_out/FR_READBACKbookkeeping should replace the FR_WAIT flush rather than stack with it.Yes — rebased onto current main (
c0e8479f), sorry about that. The branch was cut before #1133 merged, so an AppImage built from it lacked the direct-buffer-write bookkeeping and capture-readback invalidation fixes — that's the flickering you saw, not something the flush introduced.One thing worth noting for the rebuild: main has since added its own unconditional batch flush in
wait_recorded()(FR_WAIT, for the RADV load hang). This PR keeps the conditionalFR_READBACKflush instead — it only fires when the waited-on recording is actually still held (seq > rec_out && !pend.cbs.empty()), so it doesn't defeat batching for unrelated held submits, and the reason stays distinguishable in the flush stats. If the flickering persists on a rebuild from the updated branch, that would be a real interaction worth digging into.Your review was of the pre-force-push branch — it is now a single commit (
c0e8479f) rebased onto main at force-push time (fab8cb37), one filegpu/vk/vk_replay.cpp+14/−5, and GitHub reports it mergeable.On the substance we agree: with #1276's unconditional
queue_flush_for(FR_WAIT)at the top ofwait_recorded(), the bubble is fixed on main and this has nothing left to carry — happy to close.The one residual from our version is the conditional gate (flush only while the recording is still held,
seq > rec_out, with its own FR_READBACK reason in the stats), so unrelated held batches aren't flushed. With #1993's idle-send on RADV, fewer spurious flushes may matter on Linux. If useful we can send a small follow-up PR with measured FR_READBACK vs FR_WAIT counts from a run; otherwise closing here is right.@DarkGhostHunter since you were testing the AppImage build: we are closing this PR in favour of #1276, whose flush in
wait_recorded()is already on main and covers the fix you were testing for — a fresh main build should carry it.