Skip to content

AGC: the resource cache's 1,024-entry bound pins storage images past their budget until device memory runs out #3256

Closed

Description

@SleglJan

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:

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 a VK_EXT_memory_budget of 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. SurfaceKey includes 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_MEMORY for 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:

AI-assisted: yes (Claude Code)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions