fix(vk): give back the import of a retired pool whose mirror was refused #2795
Closed
github-sync
wants to merge 2 commits from
github/pr/2795 into main
pull from: github/pr/2795
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!2795
Loading…
Reference in a new issue
No description provided.
Delete branch "github/pr/2795"
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?
Players report shared GPU memory that only grows over a session. A retired pool's import is given back only when its mirror state is
MIRROR_NONE, so a pool whose mirror was refused kept its import, pinned system memory the driver counts as the GPU's shared memory, for the rest of the session. On current main that is a pool over 1 GB, or one whose mirror's VRAM allocation failed (mirror_make); a pool turned away by the mirror budget becomesMIRROR_NONEand was already given back. So in normal play this frees fewer pools than the A/B below, which needed a test patch to make them.Change.
gpu/vk/vk_memory.cpp,retired_imports_give_back: aMIRROR_REFUSEDpool's import goes as aMIRROR_NONEpool's does, after the same waits.imports_give_backalready treats the two alike ((p.mstate == Pool::MIRROR_NONE || p.mstate == Pool::MIRROR_REFUSED)a few functions below). A refused pool has no mirror and is neverinherit_pending, so nothing else reaches its import once the GPU is pastretired_valueandlast_value, as for aMIRROR_NONEone.Tested in the game. RTX 4070 SUPER 12 GB (617.42), Windows 11, DLAA 2560x1440, unattended. This card never has a mirror refused (no pool over 1 GB, no failed allocation), so both builds carried a test-only patch that makes every budget refusal
MIRROR_REFUSED, run withRX_VK_MIRROR_MB=256so that most pools were refused. The last "vk: imports:" line of each run:No device lost and no error in any run. Row added to
docs/tested-configurations.md.Tests.
tests/test_retired_give_back.pychecks the condition; it fails on main and passes here.With #2618 (open). #2618 turns a mirror that found no VRAM into
MIRROR_NONEand asks again, so after it landsMIRROR_REFUSEDis left for pools over 1 GB (andRX_VK_MIRROR_NO_RETRY=1): this still gives their imports back. The two touch different functions; they conflict only indocs/rows, if at all.Not tested. AMD and Intel on Windows, where
retired_modewaits before giving retired imports back and where refused mirrors happen without a patch; a real card with VRAM full.Part of #993.
🤖 Generated with Claude Code
I merged this into current main and ran test_retired_give_back, test_import_buffer_binding and test_import_write_watch. All pass, and CI is green. The change at vk_memory.cpp:3187 matches what imports_give_back already does for live pools: it treats MIRROR_NONE and MIRROR_REFUSED alike. A refused pool never has a mirror, so it can never be inherit_pending, and the existing retired_value and last_value checks against mem_completed still guard the GPU side. I don't see a path that touches a refused retired pool's import after those values pass.
One clarification for the description: on current main, a budget refusal in mirror_make sets MIRROR_NONE. Only a pool over 1 GB, or a failed create_device_buffer, becomes MIRROR_REFUSED. So in normal play this frees fewer pools than the patched A/B suggests, and that's why you needed the test patch. The fix is still right, and it's cheap. With #2618 it only conflicts in docs/development.md, and with #2794 only in docs/tested-configurations.md.
github-sync referenced this pull request2026-11-12 16:54:48 +00:00
Thanks, that's right: on current main a budget refusal is
MIRROR_NONE, and only a pool over 1 GB or a failedcreate_device_bufferisMIRROR_REFUSED. I've corrected the description to say so, and that in normal play it frees fewer pools than the patched A/B.Thanks, this looks right to me, and I agree with Joey-Magnus's review. Your corrected description (budget refusals are
MIRROR_NONEon main, so this only reaches pools over 1 GB or a failed mirror allocation) answers his one point.What I checked:
MIRROR_NONEone:retired_valueandlast_valueboth at or belowmem_completed, then the free itself waits indead_importsformax(mem_rec_value, last_value).retired_valueis set at retirement to at least the recording being made then, so a binding made in that recording is covered. That matters a bit more for refused pools than forMIRROR_NONEones, since with mirrors on they are the onesgpu_buffer_bindhands out from the per-thread cache without the lock. Butretire_poolbumpspools_gen, and the retired node is no longer inimported, so no new binding can reach it after that.memoryis already null, and the give-back nullsbuffer/memoryand movespiecesout. A retired node lives only inretired_pools, never inevicted_pools, soimports_give_backcan't free it as well. A refused pool never gets a mirror again (gpu_buffer_binddoesn't queue it, andretire_pooltakes pools out ofmirror_wanted), and it is neverinherit_pending, somirrors_give_backand the inherit copy inmirror_makedon't touch it either.Not blocking: on Windows AMD and Intel, retired imports go back only after the wait, and those are the vendors where give-backs once came right before device losses (309, 571). This adds the same kind of give-back with the same wait, nothing new, but a log from an AMD or Intel card with full VRAM would be good to have once one turns up.
Ordering: this is independent of #2618 and of #2759. #2759 retires more pools through
retire_pool, so the two go well together, and this one is small enough to go first. Others only clash on the new row at the top ofdocs/tested-configurations.md.