Repository navigation
fix(agc): drop resource-cache entries that hold released sampled textures - #6492
Conversation
…ures A resource-cache entry keeps every sampled texture of its descriptor sets alive. The sampled texture cache passes over textures something else holds and, past its ceiling, drops them anyway; textures it makes without caching are never in it. Entries holding either kept them alive with no budget counting them, bounded only by the 1,024-entry and 65,536-element counts, until device memory ran out. The texture cache now marks such textures released. ResourceCache::Insert refuses descriptor sets holding one and hands the entries that hold one back to the caller, like RemoveImage does for evicted storage images. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed textures Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
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.
|
|
Death Stranding 2 (PPSA02015) reaches this on its loading screen, and with this PR it still runs out of device memory, only later. This is a local stack, since the title needs several unmerged PRs and a few local skips of refusals to get that far. Linux, RTX 5080, NVIDIA 615.78.08. I counted live At 405 s with the PR, allocations made by |
|
Another data point from today, from a different integration base, so not a clean A/B:
The two bases also differ in #6416 and a few local commits, so this only supports the earlier run162 and run165 comparison in the description. It doesn't replace it. 🤖 Generated with Claude Code |
Hot Wheels Infinite Rush (PPSA22408): still runs out of device memory on the loading screen with this PR, VRAM split by allocating call siteSetup
Result
Device-local memory (type 1) held by the driver at the failed allocation: 7.0 GB
Observations
AI-assisted: this comment was drafted with the help of Claude Code and checked against the logs by us. |
|
Thanks for splitting it by call site, that answers the question this PR can't. By your table, sampled textures ( Of the four holders, only the sampled texture cache reads
They react only once I'd treat that as its own issue: no device-memory budget across holders, so a 12 GB card runs out where a 24 GB one doesn't. It's a different change from this PR. Your table and the churn numbers (26,130 slabs and 11,501 storage textures made in one loading) are exactly what that issue needs. Do you want to open it, or should I, quoting your comment? AI-assisted: yes (Claude Code) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks, this is ready apart from one line. The project keeps specific game titles out of its docs, and the new |
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…with the full walk The fast proof of a cached ShaderResources proves each sampled texture from write stamps, keys and the pending registry. It never asks whether the sampled lookup would still return the bound Texture, so a template whose surface memory is unchanged keeps binding an old object: - After the sampled cache drops or replaces the entry (boykopovar#6492 marks the texture released), Find keeps serving the template until the next Insert, and its fast proof passes. - When the lookup's answer changes without any lookup running (a snapshot whose surface became host-imported is viewed through its storage image from then on), nothing replaces the entry and the template keeps the snapshot until it leaves the resource cache. The fast proof now fails with 'replaced texture' when a bound texture is released. A template whose last full walk is older than APS5_TEMPLATE_AUDIT_MS (default 1000, 0 turns it off) takes the full walk instead of the fast proof ('audit'), so a different lookup answer fails the proof and the template is rebuilt.
…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.
What
A
ResourceCacheentry keeps every sampled texture of its descriptor sets alive. The sampled texture cache passes over textures something else still holds, and once it is a quarter over its budget it drops them anyway. Textures it makes without caching (a first use while the least recently used entry was used this frame or the last) are never in it at all. In both cases the only owner left is the resource-cache entry, so the texture stays in device memory with no budget counting it. Nothing limits that except the 1,024-entry and 65,536-table-element counts. This is the sampled-texture side of #3256, which #3473 and #3474 fixed for storage images.Texturegets a released flag.eraseTexturesets it on a texture something else still holds, and the sampled lookup sets it on a textureadmitTexturerefused.ResourceCache::Insertrefuses descriptor sets that hold a released texture. When a texture was released since the last insert, it also removes the entries holding one and hands them back throughevicted, likeRemoveImagedoes for evicted storage images. The caller then passes them to the recorder.releasedTestsinagc_driver_sampled_cache_budget: an entry whose texture the cache drops is handed back and stops keeping the texture alive, and a descriptor set holding a released texture is not admitted. Without the change toShaderResources.cpp, the test fails at "the sampled texture cache dropped a texture the resource cache holds without marking it released".Technical debt
New entry "Resource cache entries holding released textures" in
docs/dev/debt/libSceAgcDriver.md:Findcan still return those entries until then;Tested
Windows 11, NVIDIA GeForce RTX 4090, driver 617.42.
mainec1193d), fullBUILD_TESTING=ONbuild: 1295/1296 pass. The other one isagc_driver_gpu_indirect_arguments_misaligned_writer_ahead, whose source fails to compile with MinGW onmaintoo (requested alignment '65536' exceeds object file maximum 8192,GpuIndirectArgumentsMisalignedWriterAhead.cpp:25).[gpu] sampled texture cache budgetlines (device-local heap 0,VK_EXT_memory_budgetbudget about 22.9 GB).vkAllocateMemoryreturnsVK_ERROR_OUT_OF_DEVICE_MEMORYrun165 frames and memory
[texture-cache]at frame 841: 1,662 cached, 7,001 used uncached, 1,154 evicted, 5,407 held ones passed over in 10 s; 6,572 MiB in 26,466 entries, budget 6,432 MiB. run162 passed over 72,852 to 166,319 held textures per 10 s at frame 824.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code