WIP: fix(vk): cap the render-target image pool and count it in the texture budget #518
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/tooling
area/upscaling
beanstalk: approved
beanstalk: needs approval
beanstalk: running
ci: approved
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/macos
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
regression
risk
high
risk
low
risk
medium
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
ci: approved
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!518
Loading…
Reference in a new issue
No description provided.
Delete branch "Amateurwizrd/Longshot:fix/target-pool-cap"
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?
Type: fix · Risk: medium · Tested on: Windows 11, RTX 5070 Ti 16 GB (game-free checks; an earlier version in the game) · Needs: an 8 GB card (NVIDIA or AMD), Windows; Linux build
Why
The render targets' image pool took every evicted render target's image whatever its size and gave them back only 16 a
present, outside the texture budget: a sweep of several hundred targets could leave gigabytes of images in VRAM that the
budget never saw, and an 8 GB card pays for that with evicted textures and uploads.
How to reproduce
Seen on: by reading the code (found beside Hookshot-old's 7bba12ad); the new game-free check shows it on main
Settings and switches: defaults (
RX_VK_TARGET_POOL_MB256)Steps: on an 8 GB card, play through an area load that sweeps many render targets (Hyrule Field, Castle Town), with the log's target pool line in view; or run
python -I -B tests/test_target_pool_cap.pywith this PR's test on mainExpected: the pool never holds more than 256 MB, and what it holds counts against the texture budget
Actual: on main the pool takes every gone target whatever its size and is trimmed only 16 images a present, outside the budget
What changed
The render targets' image pool now has a hard cap at the moment an image is offered, and what it holds comes off the texture budget, so pooled targets can no longer push live textures out unseen. Whether VRAM is short is worked out every present, before the pool takes anything.
pool_offeringpu/vk/vk_texture.cpprefuses an image that would take the pool past its cap(
RX_VK_TARGET_POOL_MB, 256 MB by default), and any image while VRAM is short; a refused image is destroyed with itsviews as before the pool. The pool's log line counts the images it refused.
texture_frameworks out whether VRAM is short each present,before the dead list's offers to the pool and its trim, not every tenth present.
so what that freed is not taken for an excess and no live texture is evicted for it.
tests/test_target_pool_cap.pyand.cpp(new) runpool_offer,pool_trimand the frame's slice from thefirst look to the budget's rules with a stand-in driver count;
tests/test_target_image_pool.py's source checksfollow the new order (offer first, then destroy) and still pin the per-present trim.
docs/development.mddocumentsRX_VK_TARGET_POOL_MB.Measurements
Verdict: the new check fails on main and passes here (2 interleaved runs each, measured again on main @
13e8b6da); no in-game numbers yet: the case it fixes needs a card short of VRAM, which this PC is not.Hardware: RTX 5070 Ti 16 GB, driver 621.01, Ryzen 7 7800X3D, 32 GB, Windows 11 Pro 26200
Scene: none (game-free check)
Method: the new test, run 2 times on each side, interleaved (main, this PR, main, this PR); main gets this PR's test files only
How to reproduce:
python -I -B tests/run_all.py target_pool_capon this branch, and on main withtests/test_target_pool_cap.pyand.cppcopied in13e8b6daf827ee53On main the check stops at the frame's order (VRAM pressure is looked at every tenth present, after the offers), before
it reaches the cap: main has no cap at the offer, so a pool past 256 MB is only trimmed later, 16 images a present.
Flags and settings
No new switch;
RX_VK_TARGET_POOL_MBbecomes a hard cap and is documented.RX_VK_TARGET_POOL_MB=<MB>0: no pool)Testing
Tested: on Windows 11, RTX 5070 Ti 16 GB, driver 621.01.
9e6f231d(now17376190); the conflicts ingpu/vk/vk_texture.cppwere with main's new texture-budget rule (texture_rule::), kept as main has it, with this PR's second VRAM look andbudget_less_poolon top. clangd reports no error in the merged file.python -I -B tests/test_target_pool_cap.pyandtests/test_target_image_pool.pypass.python -I -B tests/run_all.pywith the pinned llvm-mingw 20261104 (tools.lock): 541 passed, 18 failed, 35 skipped; main @9e6f231don the same PC: 540 passed and the same 18 failing (environment checks: portable builder, game font, a few that need tools this PC lacks). None new. The renderer (longshot_vk.dll) builds with llvm-mingw at17376190.159def68):run_allwith llvm-mingw, 532 passed and the 5 failing on main @13e8b6da; the renderer built. In the game, an earlier version of this change (built with other changes not in this PR) ran 3 rounds at Kokiri Forest and on a Hyrule Field walk with no device loss; that is not a measurement of this PR.Not tested: a card short of VRAM, where the cap and the refusals matter; a Linux build.
Must be tested:
gpu/vk/vk_texture.cpp(Test Farm: @Beanstalk linux, build only)Risks
What could break: more render-target images are destroyed and made again instead of pooled when the pool is full or VRAM is short, which could add a little CPU time in a scene that sweeps many targets; the budget's rules now look at VRAM after the dead list is freed, so eviction decisions on the tenth present can differ from main.
Turning it off:
RX_VK_TARGET_POOL_MB=0turns the pool off; reverting the commit restores the old pool.Compatibility: Nothing changes (no save, options, cache or ABI change).
Checklist
Everyone
type(scope): description) of the status line's type.main.python -I -B tests/run_all.pypasses (any failure that also fails onmainis named).third_party/untouched (a new folder with aPROVENANCE.mdinstead).When it applies
Assisted-by:/Co-Authored-By:trailers.mainand passing here.tests/that reads changed source updated in this PR, not weakened.17376190: builds; Linux is under Must be tested)159def68e21737619000Rebased onto main
9e6f231d(now17376190). The vk_texture.cpp conflicts were main's new texture-budget rule (texture_rule::); kept main's rule, with this PR's second VRAM look and budget_less_pool on top. Description moved to the new template. Pool tests pass; run_all (g++) shows no failure main doesn't also have on this PC. Still WIP: needs a run on an 8 GB card and a Linux build.Re-ran with the pinned llvm-mingw (the earlier run_all was g++): 541 passed, the same 18 failing as main
9e6f231don this PC, none new; the renderer builds at17376190.Hi, this conflicts with
mainagain, in gpu/vk/vk_texture.cpp (texture_frame, where the pool's offer and the driver's count are read) and docs/development.md. Main's changes there are #771 and #223. Thetexture_framehunk has both sides changing the same logic (the pressure test and the budget look), so I haven't guessed at it. Please rebase onto currentmain.173761900013f95b24b0@HumanBean rebased by hand onto
main@b8d2b04e(head13f95b24). On this main thetexture_framehunk merged on its own; checked it by reading: main's pressure block (by_blocks, the compaction'sreclaim,kept_only) is the one this PR moves intolook(),look()runs each present for the pool and again before the budget's rules every tenth, andbudget_less_poolnow comes after main's card-based budget (#735). One conflict indocs/development.md: main's newRX_VK_ASTC_CPUrow and this PR'sRX_VK_TARGET_POOL_MBrow, both kept.Checks that read this diff, one at a time with the pinned llvm-mingw: 37 run, 26 passed; the 11 that fail also fail on main
b8d2b04ehere. One more needed a change:test_readback_timeout_source(from #553) cutstexture_frame's dead list, which now callspool_offer, so its stub moved frompool_puttopool_offerin13f95b24; it passes with g++, and with llvm-mingw it fails the same way main does.test_target_pool_cappasses.Still WIP: the measurements are from main
9c9d69edand need a new run, plus the 8 GB card run and the Linux build (T-2KFX).13f95b24b0f827ee53afRebased onto main @
13e8b6da(f827ee53), no conflicts, and measured again there:test_target_pool_capfails on main twice and passes here twice; the 38 checks that read this diff all pass. The log excerpt in Measurements is from the earlier run on9c9d69ed; the failing step on main is the same. Still WIP for the 8 GB run and the Linux build (T-2KFX). @HumanBean could you add thetesting wantedlabel so T-2KFX can be claimed? It shows as waiting for a maintainer.@Beanstalk linux, build the renderer at this head: it should build with no error in the files this PR changes; no change in play expected from the build alone.
@Amateurwizrd only members of
BigBeanscan start the farm. One of them can approve this request by reacting 👍 to it.@Beanstalk windows, an 8 GB NVIDIA or AMD card: Hyrule Field and Castle Town for a few minutes on main and on this PR, comparing the log's render target pool line (it should stay under 256 MB here) and the texture eviction count. (This replaces test request T-2KFX, now closed: test requests gave way to the Test Farm in #953, so the label I asked about is no longer needed.)
@Amateurwizrd only members of
BigBeanscan start the farm. One of them can approve this request by reacting 👍 to it.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.