Skip to content

perf(agc): reserve the storage cache's budget and held textures, not an eighth, from the sampled budget - #6783

Closed
Pipodi wants to merge 2 commits into
boykopovar:mainfrom
Pipodi:perf/sampled-budget-headroom
Closed

Pipodi wants to merge 2 commits into
boykopovar:mainfrom
Pipodi:perf/sampled-budget-headroom

Conversation

@Pipodi

@Pipodi Pipodi commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

What

SampledTextureBudget gave the sampled texture cache what VK_EXT_memory_budget left on the device-local heap. It subtracted the memory used outside sampled textures and cached storage images, the storage cache's static quarter of the heap (TextureCacheBudget) and an eighth of the heap budget. On a 24 GB card that held back about 8.8 GB. Ghost of Yōtei's tree scene has one draw that binds 33,677 textures (about 8.4 GB) through a cache of about 6.2 GB. So about 8k of them were refused and made again on every frame, and that draw took 9–10 s.

The reserve is now:

  • the memory used outside sampled textures and cached storage images, as before;
  • the larger of the storage cache's own budget (StorageTextureBudget, instead of the static quarter) and the storage images it holds, so a storage budget grown past StorageTextureBudget (fix(agc): grow the storage cache budget while it evicts under pressure #6194) is reserved once the cache fills it;
  • the sampled textures held outside the cache, which the old formula counted as free;
  • a thirty-second of the heap budget as headroom instead of an eighth.

SampledTextureBudget now takes the sampled and the cached storage bytes separately. Graphics.cpp and SampledCacheBudget.cpp expectations follow the new formula, with cases for:

  • 2 GiB of sampled textures held outside the cache;
  • a storage cache below its base budget, which still reserves the base budget;
  • a 6 GiB storage cache above its 3 GiB 768 MiB base budget, which is reserved at 6 GiB, so the sampled budget, both caches, the other usage and the headroom stay within the heap budget.

Measured

Ghost of Yōtei (PPSA26344), RTX 4090 (driver 617.42), Windows 11, warm shader cache, same local integration tree (main 0dab493 + #5815 #5781 #5405 #6402 #6174 #6492 + local patches). run172's tree is run165's plus this commit and three local ones: a pad-input polling change, and a debug knob that forces the sampled budget plus its logging, which was unset in run172. run165 held Cross from frame 866 to get past the menus, and run172 tapped it. Values come from the [gpu] sampled texture cache budget lines (device-local heap 0, VK_EXT_memory_budget budget about 22.9–23.1 GB) and from [resources] images took for draws with at least 33,000 textures.

Run This PR 33,677-texture draw, median / p90 (n) Sampled budget, median (min–max) Max heap 0 use Readings over budget Frames
run165 no 9,731 / 20,558 ms (102) 6,788 MiB (5,650–14,300) 22,695 MiB 0 of 99 818 at 307 s, 840 at 612 s, 878 at 1,220 s; stopped at 1,747 s on the brightness screen (frame 903)
run172 yes 1,946 / 4,522 ms (229) 8,861 MiB (7,277–16,683) 23,371 MiB 2 of 40, by up to ~0.35 GB 821 at 341 s, 884 at 623 s, the next scene (frame 945) at 904 s, 1,000 at 1,186 s; stopped at 1,200 s

run172 was measured before the storage-bytes fix (9dc2c12). On main the storage cache stays within StorageTextureBudget, except for a single image larger than the budget or a budget that shrinks between inserts, so that fix does not change these numbers and the game was not rerun.

Context
  • With the sampled budget forced to 9 GiB by a local knob (run170 and run171, not part of this PR), the same draw took about 450–500 ms. The heap used about 22.05 of 23.0 GB, with no reading over budget. The thirty-second headroom was chosen from that.
  • Both runs used APS5_HOST_IMPORT_MIB=16384, APS5_STAGING_POOL_MIB=2048, APS5_PREPARED_SPIRV_MIB=6144 and APS5_NO_SNAPSHOT_CHECK=1.

Technical debt

The existing entry "Sampled texture cache budget" in docs/dev/debt/libSceAgcDriver.md now records:

  • the thirty-second headroom is a choice from one title on one GPU;
  • run172 read 2 of 40 budget lines over the heap budget, by up to about 0.35 GB, so the headroom is too thin there; a larger headroom or a floor has not been measured;
  • the storage cache's budget is reserved even while that cache holds less, and a storage cache holding more is reserved at what it holds, so a grown storage budget is taken out of the sampled budget only once the cache fills it;
  • usage is read at most once a second, so a burst between reads can still go over;
  • a frame whose sampled textures fit no budget still remakes the refused ones on each use.

Tested

Windows 11 Pro 26200, RTX 4090, driver 617.42. This branch at 9dc2c12 on main 896e1b2:

  • Full suite: 1318 of 1321 pass, including agc_driver_graphics, agc_driver_sampled_cache_budget, agc_driver_sampled_cache_budget_memory and agc_driver_storage_cache_budget.
    • agc_driver_pixel_lds fails on main too (vkWaitForFences returns 2 after the wave32 bounded case).
    • guest_shader_link timed out under --parallel 8 and in a rerun right after agc_driver_pixel_lds. Alone it passes three times in 0.01–0.04 s, as it does on main.
    • misaligned_writer_ahead is not built: main's GpuIndirectArgumentsMisalignedWriterAhead.cpp needs 65536-byte alignment, which MinGW's object format does not allow.
  • In game: run172 above, measured before 9dc2c12.

Related

#6194 (@Thunderhawkk) lets the storage cache's budget grow past StorageTextureBudget while it evicts. This formula reserves the storage images the cache actually holds when they exceed StorageTextureBudget, so with both changes a grown storage cache comes out of the sampled budget instead of its headroom. The signature changed: #6194's SampledTextureBudget(memory, reported, caches) in storageBudgetCap no longer compiles with this branch and would become SampledTextureBudget(memory, reported, sampled, storageCacheBytes()).

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none (measured together with fix(agc): drop resource-cache entries that hold released sampled textures #6492)
  • Unblocks: PPSA26344 Ghost of Yōtei (PPSA26344) #675
  • GPUs tested: NVIDIA GeForce RTX 4090, driver 617.42, Windows 11
  • AI-assisted: yes

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 1395 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 2434 docs/dev/debt/libSceAgcDriver.md
PR 4040 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 4448 docs/dev/debt/libSceAgcDriver.md
PR 4449 docs/dev/debt/libSceAgcDriver.md
PR 4650 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5021 core/libs/prx/libSceAgcDriver/tests/execution/SampledCacheBudget.cpp
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5372 docs/dev/debt/libSceAgcDriver.md
PR 5441 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5499 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5500 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5925 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5926 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5987 docs/dev/debt/libSceAgcDriver.md
PR 5998 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 5999 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6012 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6014 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6054 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6082 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6122 docs/dev/debt/libSceAgcDriver.md
PR 6129 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6146 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6160 docs/dev/debt/libSceAgcDriver.md
PR 6177 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6192 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6194 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6196 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6202 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6212 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6215 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6218 docs/dev/debt/libSceAgcDriver.md
PR 6222 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampledCacheBudget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6223 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6234 docs/dev/debt/libSceAgcDriver.md
PR 6235 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6252 docs/dev/debt/libSceAgcDriver.md
PR 6255 docs/dev/debt/libSceAgcDriver.md
PR 6273 docs/dev/debt/libSceAgcDriver.md
PR 6280 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6292 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6297 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6300 docs/dev/debt/libSceAgcDriver.md
PR 6312 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6320 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6340 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6365 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6373 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6412 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6414 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6445 docs/dev/debt/libSceAgcDriver.md
PR 6451 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6454 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6457 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6464 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6470 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6472 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6479 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6481 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6486 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6498 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6523 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6529 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6530 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6535 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6543 docs/dev/debt/libSceAgcDriver.md
PR 6548 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6557 docs/dev/debt/libSceAgcDriver.md
PR 6563 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6566 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6567 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6571 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6572 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6588 docs/dev/debt/libSceAgcDriver.md
PR 6601 docs/dev/debt/libSceAgcDriver.md
PR 6612 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6615 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6635 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6636 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6639 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6646 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6647 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6661 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6669 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6683 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6708 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6718 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6723 docs/dev/debt/libSceAgcDriver.md
PR 6725 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6727 docs/dev/debt/libSceAgcDriver.md
PR 6730 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6741 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6760 docs/dev/debt/libSceAgcDriver.md
PR 6762 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6772 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6773 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6785 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6786 docs/dev/debt/libSceAgcDriver.md
PR 6801 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6804 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6808 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6820 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6821 docs/dev/debt/libSceAgcDriver.md
PR 6868 docs/dev/debt/libSceAgcDriver.md
PR 6887 docs/dev/debt/libSceAgcDriver.md
PR 6914 docs/dev/debt/libSceAgcDriver.md
PR 6921 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6926 docs/dev/debt/libSceAgcDriver.md
PR 6937 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampledCacheBudget.cpp
PR 6941 docs/dev/debt/libSceAgcDriver.md
PR 6944 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6946 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6947 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6959 docs/dev/debt/libSceAgcDriver.md
PR 6965 docs/dev/debt/libSceAgcDriver.md
PR 6966 docs/dev/debt/libSceAgcDriver.md
PR 6970 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6972 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6973 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6977 docs/dev/debt/libSceAgcDriver.md
PR 6982 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6987 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6989 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6995 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7002 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7008 docs/dev/debt/libSceAgcDriver.md
PR 7050 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7085 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7137 docs/dev/debt/libSceAgcDriver.md
PR 7154 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7169 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7194 docs/dev/debt/libSceAgcDriver.md
PR 7243 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7250 docs/dev/debt/libSceAgcDriver.md
PR 7254 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7256 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7261 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7296 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7307 docs/dev/debt/libSceAgcDriver.md
PR 7310 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7332 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/execution/SampledCacheBudget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7340 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7368 docs/dev/debt/libSceAgcDriver.md
PR 7377 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7390 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7410 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7413 docs/dev/debt/libSceAgcDriver.md
PR 7426 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7432 docs/dev/debt/libSceAgcDriver.md
PR 7445 docs/dev/debt/libSceAgcDriver.md
PR 7446 docs/dev/debt/libSceAgcDriver.md
PR 7449 docs/dev/debt/libSceAgcDriver.md
PR 7480 docs/dev/debt/libSceAgcDriver.md
PR 7484 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7505 docs/dev/debt/libSceAgcDriver.md
PR 7515 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7533 docs/dev/debt/libSceAgcDriver.md

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formula has a composition gap with #6194. It subtracts the actual sampled plus cached-storage bytes from reported heap usage, then reserves only StorageTextureBudget(...). If #6194 grows the storage cache above that fixed value, the excess storage bytes disappear from both terms, so this sampled budget stays too high by the growth amount. Re-reading the heap budget does not correct it: the actual cache bytes are subtracted again while the reserve remains fixed. That can let the sampled and storage caches collectively consume more than the available budget.

Could the sampled budget reserve the greater of the base storage budget and actual cached storage bytes (or otherwise account for #6194's dynamic storage budget), with a regression covering a storage cache above the base budget? The PR description already calls out this interaction, so documenting it as debt leaves the combined behavior knowingly overcommitted.

@github-actions github-actions Bot added docs agc libSceAgc* labels Oct 16, 2026
Pipodi and others added 2 commits October 16, 2026 17:07
…an eighth, from the sampled budget

The sampled texture cache got what the heap budget left after other usage, the storage cache's static quarter of the heap and an eighth of the heap budget. On a 24 GB card that kept about 8.8 GB back while one draw of Ghost of Yotei binds 33,677 textures (about 8.4 GB) through a 6.2 GB cache, so about 8k of them were made again on every frame.

The reserve is now the storage cache's own budget, the sampled textures held outside the cache, and a thirty-second of the heap budget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d its budget

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Pipodi
Pipodi force-pushed the perf/sampled-budget-headroom branch from 6b42d9f to 9dc2c12 Compare October 16, 2026 15:40
@Pipodi

Pipodi commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, fixed in 9dc2c12. SampledTextureBudget now takes the sampled and cached storage bytes separately, and reserves the larger of StorageTextureBudget and the storage images the cache holds. A storage cache grown past its base budget now comes out of the sampled budget once it holds the extra bytes, and a re-read doesn't change that.

The regression in Graphics.cpp (15 GiB budget, 9 GiB used, 3 GiB 768 MiB base storage budget):

  • 2 GiB sampled and 3 GiB storage, below the base budget: still 6 GiB 800 MiB, so the base budget is still reserved;
  • 1 GiB sampled and 6 GiB storage, above the base budget: 6 GiB 544 MiB, against 8 GiB 800 MiB before this fix;
  • that budget, the 6 GiB storage cache, the 2 GiB used outside both caches and the 480 MiB headroom add up to no more than the 15 GiB heap budget.

The signature changed, so #6194's SampledTextureBudget(memory, reported, caches) in storageBudgetCap no longer compiles with this. It would become SampledTextureBudget(memory, reported, sampled, storageCacheBytes()). I listed that under Related.

On main the storage cache stays within StorageTextureBudget, except for a single image larger than the budget or a budget that shrinks between inserts. So run172's in-game numbers are unchanged by this fix, and I didn't rerun the game.

🤖 Generated with Claude Code

@parl0v

parl0v commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Data point from a CPU-bound scene on Windows: RTX 3060 12 GB (NVIDIA 617.42), i5-12400F, Windows 10 19045, MinGW GCC Release. Minecraft Dungeons II (PPSA16064 01.100.100), title screen, no input, 200 s rows, APS5_PROFILE_DRAW=1 APS5_PROFILE_GPU=1; main c842491 vs main + this PR, interleaved with three other PRs in one batch, two rounds. FPS is the mean of the last 10 [present] windows, GPU busy and idle gaps per frame over the last 8. This scene is CPU-bound on this machine (45-48 ms of idle gaps per frame).

libs FPS GPU busy idle gaps
main 6.60 / 6.60 105 / 104 ms 46 / 48 ms
+ this PR (9dc2c12) 6.50 / 6.69 (-0.1 %) 106 / 105 ms 47 / 45 ms

Flat within the run-to-run spread (about ±1.5 % here), 0 fatal. A 12 GB card at a title screen doesn't press on the sampled or storage budgets, so this is only a no-regression check; I'll repeat it on my RTX 4060 8 GB in a world load, where the budgets are what decides placements.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 17, 2026
@Pipodi

Pipodi commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

Closing this one. #7071 on main now sizes the storage budget against the sampled side, and the reservation this PR changed no longer fits with it: with both in, the two budgets push each other down until storage sits at its 512 MiB floor.

I reworked it to reserve the storage cache's fixed cap, max(512 MiB, min(TextureCacheBudget, budget/4)), instead of its current budget. In Ghost of Yōtei on an RTX 4090 (warm 1-hour runs, baseline / rework / baseline again) it showed no gain: the rework presented 906 frames, against 932 and 991 for two baseline runs. The sampled budget stayed in the same range in all three. Thanks @parl0v for the RTX 3060 data, which was flat too.

AI-assisted: yes (Claude Code)

@Pipodi Pipodi closed this Oct 18, 2026
TheBlenDed pushed a commit to TheBlenDed/AnyPS5 that referenced this pull request Oct 25, 2026
…texture budget

The service evicted idle entries above a budget fixed at device creation (half the
sampled budget then: 4,158 MiB on the 16 GB card). In long5 at the intro (frame 840)
pinned reached it while 97 tables (1.0M records) were primed: 286,325 entries were
evicted down to 3/4, the next serves re-primed them (primer 44.6 s, serve 60.8 s).
By then the texture budgets had moved too (share 7.3 GB, sampled budget 5.0 GB).

Unless APS5_BINDLESS_BUDGET_MIB forces a size, the budget is now read at each
present from the texture caches' budgets: the share of the VRAM that sampled
textures may take (target less the storage reserve). The service's textures are
sampled textures, counted there already: in the cache (in use, never evicted) or
outside it (SampledTextureMemory), so boykopovar#6492/boykopovar#6783's accounting (sets holding
released textures dropped, textures held outside the cache reserved, storage
reserved at max(budget, held)) covers them; e0e3c93 has that part.
The frame line names the budget; new case in agc_driver_texture_service.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs needs rebase Conflicts with main, rebase needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants