Repository navigation
Description
What
ResourceCache::Insert (core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp, around line 2486 on main 961b25f) bounds the cache by entry count only: 1,024 entries by default, APS5_RESOURCE_CACHE_ENTRIES. Its comment says the entries "pin their textures and storage images past the texture caches' budgets". The storage-image cache evicts at its own budget (2,560 MiB on a 10 GB card). An image it evicts stays alive, though, while a resource-cache entry references it. When that entry is looked up again, its check fails because the image was evicted, and the entry is replaced. But entries whose key never comes back, for example a draw at an old extent, keep their images until the 1,024-entry bound pushes them out. No budget counts those pinned bytes. They only shrink the sampled-texture budget (which subtracts the heap's other use) down to its 2,048 MiB floor.
When a title keeps producing new storage images, the pinned set grows until vkAllocateMemory fails. Two examples of new images are different extents from dynamic resolution, and surfaces at new addresses. The failed allocation throws: in Texture.cpp (the Check after vkAllocateMemory) for a storage texture, and in Resources.cpp for a render target. The title stops. Nothing frees cached resources and retries first.
Seen with
007 First Light (PPSA11386) on Linux:
- Setup. RTX 3080 (10 GB, NVIDIA 615.71.09), Release with SPIRV-Tools off,
APS5_PROFILE_DRAW=1, warm shader and pipeline caches. - Stack. The 007 First Light (PPSA11386) on Linux: start-up stops in order and the PRs that pass them #2523 integration stack (Scramblrrrr's 79dd488 with fix(agc): copy a sparse descriptor heap only up to its last backed byte #2992, fix(agc): keep polling unsatisfied memory waits after diagnostics #2985 and the commits listed there). 007 doesn't reach this point on
main, which stops at 007 First Light (PPSA11386) on Linux: start-up stops in order and the PRs that pass them #2523 row 4/5. On that stack theResourceCache::Insertbound and its comment are the same as onmain.
| Setting (one run each) | Result |
|---|---|
| default (1,024 entries) | vkAllocateMemory storage texture: Vulkan result -2 (VK_ERROR_OUT_OF_DEVICE_MEMORY) after about 110 s, with 1,112 storage textures created |
APS5_NO_DRAW_RESOURCE_CACHE=1 |
vkAllocateMemory render target: Vulkan result -2 after about 89 s |
APS5_RESOURCE_CACHE_ENTRIES=64 |
no failure in 600 s, with 6,389 storage textures created (this doesn't show that memory levels off) |
- Default run. The driver's
[gpu]budget lines show device-local use rising: 2,919, 4,518, 5,999 and then 6,901 MiB, against aVK_EXT_memory_budgetof about 8,178 MiB. The storage-image cache reaches its 2,560 MiB cap in the last two of those lines. - Storage textures. 1,112 are created at 760 distinct addresses before the failure. 113 addresses get more than one extent, up to 16. The extents step down like dynamic resolution: 1920×1080, 1856×1044, 1792×1008, 1728×972.
- Key.
SurfaceKeyincludes the extent, so each step is a new image.
Details are in #2523.
Possible directions
- Count the bytes the resource cache keeps alive that the texture caches have already evicted, and bound the entries by bytes as well as by count.
- When an image is evicted from the storage cache, drop the resource-cache entries that reference it right away, instead of waiting for their next lookup.
- On
VK_ERROR_OUT_OF_DEVICE_MEMORYfor a texture or render target, release the resource cache and the evicted images, then retry once.
A test could follow tests/execution/StorageCacheBudget.cpp, with a dispatch that does get a resource-cache entry, which that test's dispatch doesn't, and a small APS5_TEXTURE_CACHE_MIB. It would check that a storage image evicted from the cache is actually destroyed, through a weak_ptr, since StorageTexture::FindLive ignores images that are no longer cached.
Related:
- Pixel shader reading a parameter the vertex shader never exports: rect-list draws zero-fill it, ordinary draws fail validation #2975: the same
vkAllocateMemory storage texture: Vulkan result -2in Wolverine, mentioned there as a separate problem and not filed. - fix(agc): reclaim idle buffers on allocation OOM #2828: an earlier reclaim-and-retry on out-of-memory, for buffers only. The intake pause closed it.
AI-assisted: yes (Claude Code)
Activity