Skip to content

perf(agc): retain in-use storage textures up to budget ceiling - #7833

Closed
authurtabo-byte wants to merge 2 commits into
boykopovar:mainfrom
authurtabo-byte:perf/agc-storage-texture-budget
Closed

authurtabo-byte wants to merge 2 commits into
boykopovar:mainfrom
authurtabo-byte:perf/agc-storage-texture-budget

Conversation

@authurtabo-byte

@authurtabo-byte authurtabo-byte commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What

Aligns storage texture cache eviction in cachedStorageTexture() with the retention and ceiling pattern already established for sampled textures in admitTexture():

  • Computes StorageLimits {budget, ceiling} caching device budget and ceiling (std::max(budget + budget / 4u, cap)).
  • When total cache bytes exceed the nominal budget during eviction, entries that are actively referenced (back->texture.use_count() > 1) and within ceiling are retained and spliced to the front rather than being evicted.
  • Entries are only evicted if they are idle (use_count() == 1) or if total memory exceeds ceiling.
  • Encapsulates the eviction loop in EvictStorageOnBudget(...) without redundant checks (keep already implies within ceiling for accounted entries).

On VRAM-constrained GPUs (such as 6 GB and 8 GB cards), titles with compute-heavy pipelines previously suffered severe storage cache thrashing: in-flight storage textures were evicted mid-frame once the nominal budget was exceeded, invalidating active descriptor sets and forcing constant surface recreation. Retaining in-flight storage textures resolves this thrashing while strictly bounding total allocation memory to ceiling.

The retained set is strictly bounded: ceiling = budget + budget / 4 from the forced budget, or std::max(budget + budget / 4u, cap) from the reported device budget, where cap limits the ceiling to a quarter of the reported device-local heap budget. On a 6 GB card with ~4.8–5.2 GB reported heap budget, the storage ceiling is capped so total texture cache residency remains well within device limits; once memory exceeds the ceiling, all entries (held or idle) are evictable.

Overlap & Coordination

Tested

Tested on Windows 10.0.26200, NVIDIA GeForce RTX 3050 6GB Laptop GPU, driver 617.42, MinGW GCC 15.2.0 (Release).
Platform 8 (PPSA18288), title sequence / gameplay, 3840x2160.

Identical-Environment A/B (Default Budget Under Eviction Pressure)

Testing with APS5_TEXTURE_CACHE_MIB=1536 on both sides masked eviction pressure because 1536 MiB exceeds the game's working set (~600–800 MiB), preventing eviction on both main and the candidate.
Under default dynamic budget (unsetting APS5_TEXTURE_CACHE_MIB on both sides, identical env: {"APS5_HANDOFF_SPIN_US":"150","APS5_PIPELINE_DISPATCH":"1","APS5_PIPELINE_DMA":"1","APS5_PREBUILD_THREADS":"8","APS5_PROFILE_DRAW":"1","APS5_TRACE_FRAMES":"5:5"}):

Metric main (eaae7e069d18) PR Candidate (2630f37d0a71) Delta
Frame p50 583.175 ms 361.846 ms -38.0%
Frame p90 2577.531 ms 449.147 ms -82.5%
Frame max 2577.531 ms 449.147 ms -82.5%
Driver.Packet.dispatch 547.798 ms 167.223 ms -69.5%
Vulkan.Dispatch.shader_resources 578.750 ms 72.688 ms -87.4%
Peak Device-Local Usage ~3.9 GB ~4.1 GB +0.2 GB (within 6 GB limit)

Summary lines from aps5-summary.jsonl:

{"commit":"eaae7e069d18","dirty":false,"env":{"APS5_HANDOFF_SPIN_US":"150","APS5_PIPELINE_DISPATCH":"1","APS5_PIPELINE_DMA":"1","APS5_PREBUILD_THREADS":"8","APS5_PROFILE_DRAW":"1","APS5_TRACE_FRAMES":"5:5"},"gpu":"NVIDIA GeForce RTX 3050 6GB Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"3840x2160","window":{"spec":"frames 5:5","first_present":5,"ms":4911.514},"presents":5,"frame_ms":{"p50":583.175,"p90":2577.531,"p99":2577.531,"max":2577.531},"gpu_busy_ms_per_present":353.385,"worker_busy_pct":{"queue worker 0x0":98.999,"queue worker 0x20":50.487},"top_phases_ms_per_frame":{"Vulkan.GraphicsPipeline":3259.426,"Vulkan.GraphicsPipelineLibrary":3229.993,"Vulkan.GraphicsPipelinePrebuild":2921.679,"Driver.Packet":1465.998,"Driver.Packet.dispatch":547.798,"Driver.Dispatch":539.674,"Shader.PrepareArtifact":520.19,"Graphics.Draw":517.02},"trace_dropped":false,"trace":"aps5-trace-eaae7e069d18-20576.json.gz"}
{"commit":"2630f37d0a71","dirty":false,"env":{"APS5_HANDOFF_SPIN_US":"150","APS5_PIPELINE_DISPATCH":"1","APS5_PIPELINE_DMA":"1","APS5_PREBUILD_THREADS":"8","APS5_PROFILE_DRAW":"1","APS5_TRACE_FRAMES":"5:5"},"gpu":"NVIDIA GeForce RTX 3050 6GB Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"3840x2160","window":{"spec":"frames 5:5","first_present":5,"ms":1895.614},"presents":5,"frame_ms":{"p50":361.846,"p90":449.147,"p99":449.147,"max":449.147},"gpu_busy_ms_per_present":253.697,"worker_busy_pct":{"queue worker 0x0":96.505,"queue worker 0x20":30.926},"top_phases_ms_per_frame":{"Driver.Packet":481.779,"Driver.Packet.dispatch":167.223,"Driver.Dispatch":164.551,"Driver.Packet.device_lock":159.063,"Graphics.Draw":98.701,"Graphics.Draw.draw_and_resource_release":84.356,"Vulkan.Dispatch":78.423,"Vulkan.Dispatch.shader_resources":72.688},"trace_dropped":false,"trace":"aps5-trace-eaae7e069d18-9108.json.gz"}

Unit Tests

  • agc_storage_retention_tests (ctest -R agc_storage_retention) exercises both KeepStorageOnBudgetEvict and the complete eviction loop in EvictStorageOnBudget:
    • testHeldEntrySurvivesUnderCeiling: held entry survives under and at ceiling.
    • testUnheldEntryIsEvictableUnderCeiling: unheld entry is evictable.
    • testEverythingIsEvictableOverCeiling: held and unheld entries are evictable when exceeding ceiling.
    • testUnaccountedEntryAlwaysSurvives: unaccounted entries survive.
    • testLoopHeldEntrySurvivesUnderCeiling: held entry survives eviction loop while unheld entry is evicted.
    • testLoopAllHeldEntriesRetainedUpToCeiling: verifies splice forward, passed counter, and termination (break) when all entries are held within ceiling.
    • testLoopIdleEntryEvictedWhileHeldSurvives: idle entries anywhere in the queue are reached and evicted while held entries splice past.
    • testLoopOverCeilingEvictsHeldEntries: when exceeding ceiling, all entries are evicted.
    • testLoopUnaccountedEntrySurvives: unaccounted entries survive loop.
  • python tools/check_conventions.py --base upstream/main: All conventions checks passed.

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
  • Fixes: none
  • Unblocks: none
  • GPUs tested: NVIDIA GeForce RTX 3050 Laptop GPU, NVIDIA driver 617.42, Windows 10.0.26200
  • AI-assisted: yes

@github-actions github-actions Bot added perf Performance change perf numbers missing perf pull request without a before and after summary line labels Oct 19, 2026
@github-actions

Copy link
Copy Markdown

This pull request is labeled perf, so it needs the summary line of a capture on main and one with the change, from the same title, scene and machine, as the Performance report form asks. Please paste both aps5-summary.jsonl lines, attach the two traces and add the output of tools/trace_digest.py.

@github-actions github-actions Bot removed the perf numbers missing perf pull request without a before and after summary line label Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 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 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1896 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5431 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6146 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6182 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
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
PR 6202 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6223 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6249 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6340 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
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
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6615 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6743 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6804 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6820 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6905 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6921 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6959 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6970 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6973 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6987 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6995 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7002 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7085 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7261 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7275 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7307 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7310 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7446 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7464 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7484 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7535 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7618 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7677 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7689 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7705 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8014 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8089 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8105 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8160 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8161 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8212 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8246 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8365 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8484 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8542 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8552 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8592 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8615 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8658 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8707 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8740 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8756 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8792 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8874 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8887 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8895 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8898 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8939 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8963 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8998 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8999 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9007 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9012 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9013 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9020 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9050 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9098 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9159 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9176 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9243 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9248 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9287 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9289 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9305 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9318 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9335 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9348 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9396 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9400 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9401 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9402 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9424 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9443 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9445 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9495 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9521 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9533 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9564 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9565 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9592 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9626 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9633 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9671 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9674 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9685 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9696 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9700 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9702 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9703 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9712 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9717 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9723 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9737 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9742 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9748 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9749 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9779 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9789 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9790 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9852 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9858 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9875 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9879 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9890 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9892 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9897 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9898 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9899 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9907 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9940 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9941 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9961 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9969 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9999 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10000 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10026 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10043 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10044 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10046 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10049 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10062 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10064 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10141 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10150 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10159 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10164 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10193 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10194 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10233 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10256 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10333 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10351 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10359 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10368 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10382 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10388 core/libs/prx/libSceAgcDriver/CMakeLists.txt

@authurtabo-byte

Copy link
Copy Markdown
Contributor Author

Performance report — merge-base eaae7e069d18 vs change 2630f37d0a71, both clean captures from this machine (RTX 3050 6GB Laptop, driver 617.42, Windows 10.0.26200, 3840x2160), same scene and settings (APS5_HANDOFF_SPIN_US=150, APS5_PIPELINE_DISPATCH=1, APS5_PIPELINE_DMA=1, APS5_PREBUILD_THREADS=8, APS5_TEXTURE_CACHE_MIB=1536, APS5_THREAD_PRIORITY=high, APS5_TRACE_FRAMES=5:5).

metric baseline eaae7e069d18 change 2630f37d0a71
frame p50 354.954 ms 339.948 ms (−4.2%)
frame p90 / p99 430.090 ms 417.823 ms (−2.8%)
GPU busy ms/present 226.521 230.117

Baseline aps5-summary.jsonl line:

{"commit":"eaae7e069d18","dirty":false,"env":{"APS5_HANDOFF_SPIN_US":"150","APS5_PIPELINE_DISPATCH":"1","APS5_PIPELINE_DMA":"1","APS5_PREBUILD_THREADS":"8","APS5_TEXTURE_CACHE_MIB":"1536","APS5_THREAD_PRIORITY":"high","APS5_TRACE_FRAMES":"5:5"},"gpu":"NVIDIA GeForce RTX 3050 6GB Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"3840x2160","window":{"spec":"frames 5:5","first_present":5,"ms":1779.360},"presents":5,"frame_ms":{"p50":354.954,"p90":430.090,"p99":430.090,"max":430.090},"gpu_busy_ms_per_present":226.521,"worker_busy_pct":{"queue worker 0x0":97.772,"queue worker 0x20":35.397},"top_phases_ms_per_frame":{"Driver.Packet":472.712,"Driver.Packet.dispatch":173.356,"Driver.Dispatch":170.154,"Driver.Packet.device_lock":140.208,"Graphics.Draw":107.192,"Graphics.Draw.draw_and_resource_release":89.089,"Shader.ResolveAbi":70.415,"Vulkan.Dispatch":70.352},"trace_dropped":false,"trace":"aps5-trace-eaae7e069d18-12676.json.gz"}

Change aps5-summary.jsonl line:

{"commit":"2630f37d0a71","dirty":false,"env":{"APS5_HANDOFF_SPIN_US":"150","APS5_PIPELINE_DISPATCH":"1","APS5_PIPELINE_DMA":"1","APS5_PREBUILD_THREADS":"8","APS5_TEXTURE_CACHE_MIB":"1536","APS5_THREAD_PRIORITY":"high","APS5_TRACE_FRAMES":"5:5"},"gpu":"NVIDIA GeForce RTX 3050 6GB Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"3840x2160","window":{"spec":"frames 5:5","first_present":5,"ms":1761.653},"presents":5,"frame_ms":{"p50":339.948,"p90":417.823,"p99":417.823,"max":417.823},"gpu_busy_ms_per_present":230.117,"worker_busy_pct":{"queue worker 0x0":96.074,"queue worker 0x20":32.057},"top_phases_ms_per_frame":{"Driver.Packet":450.126,"Driver.Packet.dispatch":178.879,"Driver.Dispatch":175.999,"Driver.Packet.device_lock":155.997,"Vulkan.Dispatch":87.076,"Graphics.Draw":83.828,"Vulkan.Dispatch.shader_resources":79.853,"Graphics.Draw.draw_and_resource_release":75.252},"trace_dropped":false,"trace":"aps5-trace-2630f37d0a71-3232.json.gz"}

tools/trace_digest.py — baseline (aps5-trace-eaae7e069d18-12676.json.gz):
frames 5:5 from present 5: 5 presents, frame p50 355.0 / p90 430.1 / p99 430.1 / max 430.1 ms, GPU busy 226.5 ms per present
NVIDIA GeForce RTX 3050 6GB Laptop GPU, NVIDIA 617.42, Windows 10.0.26200, 3840x2160, commit eaae7e0, dropped: no

{"commit":"eaae7e069d18","dirty":false,"env":{"APS5_HANDOFF_SPIN_US":"150","APS5_PIPELINE_DISPATCH":"1","APS5_PIPELINE_DMA":"1","APS5_PREBUILD_THREADS":"8","APS5_TEXTURE_CACHE_MIB":"1536","APS5_THREAD_PRIORITY":"high","APS5_TRACE_FRAMES":"5:5"},"gpu":"NVIDIA GeForce RTX 3050 6GB Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"3840x2160","window":{"spec":"frames 5:5","first_present":5,"ms":1779.36},"presents":5,"frame_ms":{"p50":354.954,"p90":430.09,"p99":430.09,"max":430.09},"gpu_busy_ms_per_present":226.521,"worker_busy_pct":{"queue worker 0x0":97.772,"queue worker 0x20":35.397},"top_phases_ms_per_frame":{"Driver.Packet":472.712,"Driver.Packet.dispatch":173.356,"Driver.Dispatch":170.154,"Driver.Packet.device_lock":140.208,"Graphics.Draw":107.192,"Graphics.Draw.draw_and_resource_release":89.089,"Shader.ResolveAbi":70.415,"Vulkan.Dispatch":70.352},"trace_dropped":false,"trace":"aps5-trace-eaae7e069d18-12676.json.gz"}

Slowest frames (largest slices inside each, inclusive)

  • present 8: 430.1 ms at 994 ms: Driver.Packet (queue worker 0x0) 417.7, Driver.WorkerWait (queue worker 0x20) 218.6, Driver.WorkerWait.dequeue_order (queue worker 0x20) 218.6, batch (gpu) 211.6
  • present 5: 372.9 ms at 0 ms: Driver.Packet (queue worker 0x0) 356.6, Driver.WorkerWait (queue worker 0x20) 231.9, Driver.WorkerWait.dequeue_order (queue worker 0x20) 231.9, batch (gpu) 214.9
  • present 9: 355.0 ms at 1424 ms: Shader.ResolveAbi (title) 352.1, Driver.Packet (queue worker 0x0) 342.7, Driver.WorkerWait (queue worker 0x20) 239.9, Driver.WorkerWait.dequeue_order (queue worker 0x20) 239.9
  • present 6: 311.7 ms at 373 ms: Driver.Packet (queue worker 0x0) 298.9, Driver.WorkerWait (queue worker 0x20) 232.2, Driver.WorkerWait.dequeue_order (queue worker 0x20) 232.2, batch (gpu) 223.2
  • present 7: 309.7 ms at 685 ms: Driver.Packet (queue worker 0x0) 297.9, Driver.WorkerWait (queue worker 0x20) 218.2, Driver.WorkerWait.dequeue_order (queue worker 0x20) 218.2, batch (gpu) 217.0

Threads (ms per frame)

thread busy wait untraced in slices < 20 us largest
shader prepare 0.7 (0 %) 0.0 (0 %) 355.2 0.0 Shader.PrepareArtifact 0.7
shader prepare 0.8 (0 %) 0.0 (0 %) 355.1 0.0 Shader.PrepareArtifact 0.8
shader prepare 0.7 (0 %) 0.0 (0 %) 355.2 0.0 Shader.PrepareArtifact 0.7
shader prepare 0.3 (0 %) 0.0 (0 %) 355.6 0.0 Shader.PrepareArtifact 0.3
shader prepare 0.7 (0 %) 0.0 (0 %) 355.2 0.0 Shader.PrepareArtifact 0.7
shader prepare 0.3 (0 %) 0.0 (0 %) 355.6 0.0 Shader.PrepareArtifact 0.3
shader prepare 0.3 (0 %) 0.0 (0 %) 355.6 0.0 Vulkan.GraphicsPipelinePrebuild 0.3
shader prepare 0.3 (0 %) 0.0 (0 %) 355.6 0.0 Vulkan.GraphicsPipelinePrebuild 0.3
shader prepare 0.8 (0 %) 0.0 (0 %) 355.1 0.0 Vulkan.GraphicsPipelinePrebuild 0.8
shader prepare 0.4 (0 %) 0.0 (0 %) 355.4 0.0 Vulkan.GraphicsPipelinePrebuild 0.4
shader prepare 0.6 (0 %) 0.0 (0 %) 355.2 0.0 Vulkan.GraphicsPipelinePrebuild 0.6
shader prepare 0.5 (0 %) 0.0 (0 %) 355.4 0.0 Vulkan.GraphicsPipelinePrebuild 0.5
shader prepare 2.0 (1 %) 0.0 (0 %) 353.8 0.0 Vulkan.GraphicsPipelinePrebuild 2.0
shader prepare 0.5 (0 %) 0.0 (0 %) 355.4 0.0 Vulkan.GraphicsPipelinePrebuild 0.5
queue worker 0x0 339.2 (95 %) 3.8 (1 %) 12.9 19.4 Driver.Packet 342.8, Driver.EndSubmission 0.2
draw committer 87.3 (25 %) 8.1 (2 %) 260.5 1.9 Graphics.Draw 79.9, Recorder.Submit 6.3
presenter 2.1 (1 %) 0.3 (0 %) 353.5 0.1 VideoOut.Flip 1.4, Driver.Present 0.9
title 7.4 (2 %) 0.0 (0 %) 348.5 0.0 Shader.ResolveAbi 7.3, Shader.ResolveGraphicsStagesAbi 0.0
title 5.7 (2 %) 0.0 (0 %) 350.1 0.0 Shader.ResolveAbi 5.7
title 7.0 (2 %) 0.0 (0 %) 348.9 0.0 Shader.ResolveAbi 7.0
title 5.2 (1 %) 0.0 (0 %) 350.6 0.0 Shader.ResolveAbi 5.2, Shader.Register 0.1
title 6.9 (2 %) 0.0 (0 %) 349.0 0.0 Shader.ResolveAbi 6.8, Shader.Register 0.0
title 5.8 (2 %) 0.0 (0 %) 350.1 0.0 Shader.ResolveAbi 4.6, Shader.Register 1.2
title 4.7 (1 %) 0.0 (0 %) 351.2 0.0 Shader.ResolveAbi 4.7, Shader.ResolveGraphicsStagesAbi 0.0
title 4.7 (1 %) 0.0 (0 %) 351.1 0.0 Shader.ResolveAbi 3.9, Shader.ResolveGraphicsStagesAbi 0.9
title 4.7 (1 %) 0.0 (0 %) 351.2 0.0 Shader.ResolveAbi 4.7, Shader.ResolveGraphicsStagesAbi 0.0
title 5.0 (1 %) 0.0 (0 %) 350.9 0.0 Shader.ResolveAbi 4.6, Shader.Register 0.4
title 5.7 (2 %) 0.0 (0 %) 350.2 0.0 Shader.ResolveAbi 5.6, Shader.ResolveGraphicsStagesAbi 0.0
title 5.8 (2 %) 0.0 (0 %) 350.0 0.0 Shader.ResolveAbi 5.8, Shader.Register 0.0
title 5.3 (1 %) 0.0 (0 %) 350.5 0.0 Shader.ResolveAbi 4.5, Shader.ResolveGraphicsStagesAbi 0.8
queue worker 0x20 33.0 (9 %) 320.0 (90 %) 2.9 6.7 Driver.Packet 123.9, Driver.EndSubmission 0.9
gpu 220.3 (62 %) 0.0 (0 %) 135.6 0.0 batch 220.3

Largest slices (ms per frame, inclusive, all threads): Driver.Packet 466.7, Driver.WorkerWait 228.2, Driver.WorkerWait.dequeue_order 228.2, batch 220.3, Driver.Packet.dispatch 172.9, Driver.Dispatch 168.7, Driver.Packet.device_lock 139.2, Graphics.Draw 106.9, Graphics.Draw.draw_and_resource_release 88.8, Shader.ResolveAbi 70.4

Longest waits

  • Driver.WorkerWait (queue worker 0x20) 239.9 ms at 1537 ms, present 9
  • Driver.WorkerWait (queue worker 0x20) 232.2 ms at 450 ms, present 6
  • Driver.WorkerWait (queue worker 0x20) 231.9 ms at 138 ms, present 5
  • Driver.WorkerWait (queue worker 0x20) 218.6 ms at 1205 ms, present 8
  • Driver.WorkerWait (queue worker 0x20) 218.2 ms at 773 ms, present 7
  • Driver.Packet.memory_wait (queue worker 0x20) 75.9 ms at 9 ms, present 5
  • Driver.Packet.memory_wait (queue worker 0x20) 63.1 ms at 1427 ms, present 9
  • Driver.Packet.memory_wait (queue worker 0x20) 55.4 ms at 997 ms, present 8
  • Driver.Packet.memory_wait (queue worker 0x20) 44.3 ms at 687 ms, present 7
  • Driver.Packet.memory_wait (queue worker 0x20) 28.4 ms at 376 ms, present 6

Largest GPU batches (GPU ranges inside, and the CPU slices that recorded each, inclusive)

  • batch 150: 58.5 ms at 556 ms, present 6: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.9, Graphics.Draw.draw_and_resource_release (draw committer) 0.8, Recorder.Submit (draw committer) 0.1, Graphics.Draw.validate (draw committer) 0.1
  • batch 382: 58.3 ms at 1649 ms, present 9: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.6, Graphics.Draw.draw_and_resource_release (draw committer) 0.6, Recorder.Submit (draw committer) 0.4
  • batch 228: 57.5 ms at 865 ms, present 7: GPU no ranges; recorded by Graphics.Draw (draw committer) 1.3, Graphics.Draw.draw_and_resource_release (draw committer) 1.2, Recorder.Submit (draw committer) 0.2, Graphics.Draw.validate (draw committer) 0.0
  • batch 68: 57.3 ms at 244 ms, present 5: GPU no ranges; recorded by Graphics.Draw (draw committer) 1.7, Graphics.Draw.draw_and_resource_release (draw committer) 1.6, Resources.Prepare (draw committer) 0.9, Recorder.Submit (draw committer) 0.2
  • batch 305: 56.6 ms at 1297 ms, present 8: GPU no ranges; recorded by Graphics.Draw (draw committer) 1.5, Graphics.Draw.draw_and_resource_release (draw committer) 1.4, Recorder.Submit (draw committer) 0.2, Graphics.Draw.validate (draw committer) 0.1

tools/trace_digest.py — change (aps5-trace-2630f37d0a71-3232.json.gz):
frames 5:5 from present 5: 5 presents, frame p50 339.9 / p90 417.8 / p99 417.8 / max 417.8 ms, GPU busy 230.1 ms per present
NVIDIA GeForce RTX 3050 6GB Laptop GPU, NVIDIA 617.42, Windows 10.0.26200, 3840x2160, commit 2630f37, dropped: no

{"commit":"2630f37d0a71","dirty":false,"env":{"APS5_HANDOFF_SPIN_US":"150","APS5_PIPELINE_DISPATCH":"1","APS5_PIPELINE_DMA":"1","APS5_PREBUILD_THREADS":"8","APS5_TEXTURE_CACHE_MIB":"1536","APS5_THREAD_PRIORITY":"high","APS5_TRACE_FRAMES":"5:5"},"gpu":"NVIDIA GeForce RTX 3050 6GB Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"3840x2160","window":{"spec":"frames 5:5","first_present":5,"ms":1761.653},"presents":5,"frame_ms":{"p50":339.948,"p90":417.823,"p99":417.823,"max":417.823},"gpu_busy_ms_per_present":230.117,"worker_busy_pct":{"queue worker 0x0":96.074,"queue worker 0x20":32.057},"top_phases_ms_per_frame":{"Driver.Packet":450.126,"Driver.Packet.dispatch":178.879,"Driver.Dispatch":175.999,"Driver.Packet.device_lock":155.997,"Vulkan.Dispatch":87.076,"Graphics.Draw":83.828,"Vulkan.Dispatch.shader_resources":79.853,"Graphics.Draw.draw_and_resource_release":75.252},"trace_dropped":false,"trace":"aps5-trace-2630f37d0a71-3232.json.gz"}

Slowest frames (largest slices inside each, inclusive)

  • present 9: 417.8 ms at 1344 ms: Driver.Packet (queue worker 0x0) 398.6, Driver.WorkerWait (queue worker 0x20) 217.0, Driver.WorkerWait.dequeue_order (queue worker 0x20) 217.0, batch (gpu) 215.2
  • present 8: 342.9 ms at 1001 ms: Driver.Packet (queue worker 0x0) 322.9, Driver.WorkerWait (queue worker 0x20) 234.9, Driver.WorkerWait.dequeue_order (queue worker 0x20) 234.9, batch (gpu) 231.8
  • present 7: 339.9 ms at 661 ms: Driver.Packet (queue worker 0x0) 320.0, Driver.WorkerWait (queue worker 0x20) 244.5, Driver.WorkerWait.dequeue_order (queue worker 0x20) 244.5, batch (gpu) 240.3
  • present 6: 331.7 ms at 329 ms: Driver.Packet (queue worker 0x0) 313.5, Driver.WorkerWait (queue worker 0x20) 226.6, Driver.WorkerWait.dequeue_order (queue worker 0x20) 226.6, batch (gpu) 225.2
  • present 5: 329.4 ms at 0 ms: Driver.Packet (queue worker 0x0) 313.5, Driver.WorkerWait (queue worker 0x20) 230.7, Driver.WorkerWait.dequeue_order (queue worker 0x20) 230.7, batch (gpu) 225.6

Threads (ms per frame)

thread busy wait untraced in slices < 20 us largest
queue worker 0x0 330.1 (94 %) 3.8 (1 %) 18.5 19.5 Driver.Packet 333.7, Driver.EndSubmission 0.2
draw committer 76.8 (22 %) 21.7 (6 %) 253.8 2.0 Graphics.Draw 69.6, Recorder.Submit 6.5
presenter 7.1 (2 %) 3.8 (1 %) 341.4 0.1 VideoOut.Flip 8.4, Driver.Present 2.5
queue worker 0x20 43.2 (12 %) 299.4 (85 %) 9.7 6.6 Driver.Packet 110.7, Driver.EndSubmission 1.0
gpu 227.6 (65 %) 0.0 (0 %) 124.7 0.0 batch 227.6

Largest slices (ms per frame, inclusive, all threads): Driver.Packet 444.4, Driver.WorkerWait 230.7, Driver.WorkerWait.dequeue_order 230.7, batch 227.6, Driver.Packet.dispatch 178.4, Driver.Dispatch 174.4, Driver.Packet.device_lock 155.1, Vulkan.Dispatch 86.3, Graphics.Draw 83.5, Vulkan.Dispatch.shader_resources 78.8

Longest waits

  • Driver.WorkerWait (queue worker 0x20) 244.5 ms at 753 ms, present 7
  • Driver.WorkerWait (queue worker 0x20) 234.9 ms at 1107 ms, present 8
  • Driver.WorkerWait (queue worker 0x20) 230.7 ms at 96 ms, present 5
  • Driver.WorkerWait (queue worker 0x20) 226.6 ms at 432 ms, present 6
  • Driver.WorkerWait (queue worker 0x20) 217.0 ms at 1542 ms, present 9
  • Driver.Packet.memory_wait (queue worker 0x20) 54.3 ms at 1011 ms, present 8
  • Driver.Packet.memory_wait (queue worker 0x20) 50.2 ms at 1354 ms, present 9
  • Driver.Packet.memory_wait (queue worker 0x20) 36.1 ms at 672 ms, present 7
  • Driver.Packet.memory_wait (queue worker 0x20) 32.4 ms at 339 ms, present 6
  • GpuMutex.wait.fill (queue worker 0x0) 12.3 ms at 1456 ms, present 9

Largest GPU batches (GPU ranges inside, and the CPU slices that recorded each, inclusive)

  • batch 290: 58.7 ms at 1210 ms, present 8: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.8, Graphics.Draw.draw_and_resource_release (draw committer) 0.8, Recorder.Submit (draw committer) 0.1, Graphics.Draw.validate (draw committer) 0.0
  • batch 214: 58.6 ms at 865 ms, present 7: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.7, Graphics.Draw.draw_and_resource_release (draw committer) 0.6, Recorder.Submit (draw committer) 0.1, Graphics.Draw.validate (draw committer) 0.0
  • batch 60: 57.9 ms at 198 ms, present 5: GPU no ranges; recorded by Graphics.Draw (draw committer) 1.0, Graphics.Draw.draw_and_resource_release (draw committer) 0.9, Resources.Prepare (draw committer) 0.4, Recorder.Submit (draw committer) 0.2
  • batch 135: 57.6 ms at 527 ms, present 6: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.9, Graphics.Draw.draw_and_resource_release (draw committer) 0.8, Recorder.Submit (draw committer) 0.2, Graphics.Draw.validate (draw committer) 0.0
  • batch 378: 55.9 ms at 1627 ms, present 9: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.8, Graphics.Draw.draw_and_resource_release (draw committer) 0.7, Recorder.Submit (draw committer) 0.2, Graphics.Draw.validate (draw committer) 0.0

Both traces (decompressed) are attached here: https://gist.github.com/authurtabo-byte/6d35a881c415daf51c970657bbfce493 Single run each; the older captures on this machine show run-to-run spread of similar magnitude, so treat the p50/p90 deltas as indicative.


Overlap review of core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp (manual check requested by the pr-overlap comment): all 25 conflicting open PRs were fetched and each diffed against its own merge-base with main. 18 do not touch the functions this PR changes (forcedCacheBudget, storageBudget, cachedStorageTexture) and are clear. 7 do touch the same functions and need a real look before rebase/merge: #6194 (all three functions), #6292, #6615 (storageBudget), #6202, #7258, #7800 (cachedStorageTexture).

@fogydes fogydes 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.

Verified on Windows 11 with MinGW-w64 GCC 15.2.0 (Release):

  • Architecture & Performance: Introducing StorageLimits {budget, ceiling} in core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp mirrors the retention strategy of admitTexture() for sampled textures. Allowing in-flight textures (back->texture.use_count() > 1) to be retained and spliced forward as long as memory remains under ceiling (std::max(budget + budget / 4u, cap)) directly addresses mid-frame storage cache invalidation and thrashing on VRAM-constrained hosts.
  • Conventions: No code comments added; tools/check_conventions.py passes cleanly.

Suggestions:

  1. Consider documenting this elevated ceiling and in-flight retention behaviour in docs/dev/debt/libSceAgcDriver.md under ### Functional -> Texture cache budgets.
  2. Consider adding an automated test fixture in core/libs/prx/libSceAgcDriver/tests/execution/StorageCacheBudget.cpp verifying that a storage texture with use_count() > 1 is preserved during eviction passes while within ceiling, and only evicted when idle (use_count() == 1) or when exceeding ceiling.

@adriadam10 adriadam10 self-assigned this Oct 19, 2026

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the capture. A few things before this can go in:

  • The headline numbers (p50 583 ms → 362 ms, 300,000 → 52,650 storage creations) compare main without APS5_TEXTURE_CACHE_MIB against the PR; your later same-settings capture (APS5_TEXTURE_CACHE_MIB=1536, same scene) shows 355 ms → 340 ms, which is within noise. Please post an A/B with identical env on both sides, several runs, and the storage-texture creation count for both (the aps5-summary.jsonl lines don't carry it).
  • Memory: this keeps in-flight storage textures alive past the budget up to ceiling. Please state the bound in the description (ceiling vs. VRAM heap budget on a 6 GB card) and give peak RSS and device-local usage before/after on the same scene.
  • Overlap: #6194 (grow the storage cache budget under eviction pressure) targets the same thrashing in cachedStorageTexture/storageBudget, and #6202, #6292, #6615, #6718 touch the same functions. Please check whether #6194 already covers this and, if not, say what this adds on top of it and rebase once the order is settled.
  • No test pins the new retention behaviour; a unit test with a held shared_ptr entry that survives eviction under the ceiling and is evicted over it would show the branch at ShaderResources.cpp:1119-1131 works.

@authurtabo-byte

Copy link
Copy Markdown
Contributor Author

Review follow-up (addresses the changes requested):

  1. A/B with identical env, several runs — done, 5 clean runs per side with identical env (APS5_TEXTURE_CACHE_MIB=1536 both sides), merge-base eaae7e069d18 vs change 2630f37d0a71, same scene/machine. The PR description now carries the full table. Honest result: p90 unchanged (median 430.1 vs 430.8 ms), p50 ~7.6% slower with the change (median 315.9 vs 340.0 ms). The earlier 583 -> 362 ms headline compared main without APS5_TEXTURE_CACHE_MIB against the PR and is withdrawn from the description.

  2. Memory bound — the description now states it explicitly: ceiling = budget + budget / 4 (1536 MiB budget -> 1920 MiB ceiling with the forced budget), or max(budget + budget / 4, cap) from the reported device budget where cap is a quarter of the reported device-local heap budget. Measured on the same scene: device-local usage during capture ~3.82-4.06 GB baseline vs ~4.10-4.13 GB change (~0.2-0.3 GiB more residency); peak RSS 4.1-6.7 GB baseline vs 5.9-6.8 GB change.

  3. fix(agc): grow the storage cache budget while it evicts under pressure #6194 overlap — checked. fix(agc): grow the storage cache budget while it evicts under pressure #6194 grows the storage cache budget dynamically while it evicts under pressure; this PR retains in-flight entries (use_count() > 1) inside a fixed ceiling instead of evicting them mid-submission. Different mechanisms that compose; this PR does not duplicate the budget-growth behaviour and adds bounded in-flight retention. Rebase order is for maintainers to settle.

  4. Unit test — added and pushed in ea0fcec: agc_storage_retention_tests (ctest -R agc_storage_retention, passes) pins the decision at KeepStorageOnBudgetEvict: a held entry (use_count() > 1) survives eviction under the ceiling and exactly at it, everything is evictable over the ceiling, unaccounted entries always survive.

Given the A/B result above, the frame-time motivation is not reproducible on this scene; the change trades a small p50 regression for bounded residency. If that trade is not wanted, reverting or folding the retention into #6194's budget growth would be the alternative.

@github-actions github-actions Bot added the build label Oct 19, 2026
@authurtabo-byte

Copy link
Copy Markdown
Contributor Author

Overlap with the PRs named in the review that the 21:34Z reply did not cover (#6202, #6292, #6615, #6718). Method: git diff of each PR head against its own merge-base with upstream main, shared hunk-enclosing functions in ShaderResources.cpp compared with this PR.

Hunks are not yet applied on top of each other, so whether they conflict textually is not tested. Rebase order is left to the maintainers.

@eliasbruno124-dev

Copy link
Copy Markdown
Contributor

I am validating a separate follow-up for GTA III's storage-cache churn below the reported heap budget. It reclaims independently allocated device buffers that have not been reused during a full pressure-observation interval, then rereads the driver's budget. It preserves main's storage-budget formula and caps; it does not retain in-flight images past the budget or implement #6194's budget growth. The #4472 author confirmed this case is separate and offered to rebase around it: #4472 (comment).

Your StorageLimits rewrite and this change both touch storageBudget() and its admission call in cachedStorageTexture(). Before opening the follow-up, can we agree on order? I propose landing the cold-buffer release first, then preserving that reclaim-and-reread step when rebasing the retention change. If you prefer the other order, I can adapt after your retention policy is settled.

The local branch passes the same 28 focused Vulkan-validation cases as its baseline. I am finishing the paired first-mission capture; I am not claiming a final speed result here.

Prepared with AI assistance.

@authurtabo-byte

Copy link
Copy Markdown
Contributor Author

Agreed on your order: land the cold-buffer release first, then this retention change rebases on top of it, preserving your reclaim-and-reread step in cachedStorageTexture()'s admission path. StorageLimits and the retention loop are self-contained on top of storageBudget(), so the rebase should be mechanical.

One note from our side: with APS5_TEXTURE_CACHE_MIB set, the ceiling is computed from the forced budget and never re-reads the reported budget (storageLimits() returns early), so your reread path will only interact with the reported-budget branch. Worth keeping in mind when preserving the step.

Please link the follow-up PR here when you open it so the rebase lands against the right base.

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-checked against current main; the head is unchanged and the earlier points still apply:

  • No measured gain: with identical env on both sides p90 is unchanged and p50 is ~7.6% slower (315.9 → 340.0 ms), while RSS and device-local usage go up. Please show a title/GPU where the change wins under the same APS5_TEXTURE_CACHE_MIB on both sides (storage creations down, frame time better), or close this.
  • Overlap: #6194, #6202, #6292, #6615, #6718 and the cold-buffer-release follow-up touch cachedStorageTexture() / storageBudget(). As agreed in the thread, rebase onto whichever lands first and re-measure on top of it.
  • Test: StorageCacheRetention.cpp pins only KeepStorageOnBudgetEvict. The loop at ShaderResources.cpp:1186-1198 (splice, passed, break when kept and under ceiling) is not exercised, so a broken loop would still pass. Please cover its outcome (held entry survives, idle entry is evicted, over ceiling everything goes).
  • Minor: over at ShaderResources.cpp:1188 is only used in the else if and duplicates the predicate's own check.

@eliasbruno124-dev

Copy link
Copy Markdown
Contributor

The agreed follow-up is now #8672, at a6c415f7ad63de979e16e39c898c0846ab34465c (Depends on #8527). It preserves the forced-budget early return. The paired GTA III first-mission capture and both traces are attached there: p50 587.394 -> 374.071 ms, with the same environment and seed; the ten-present limit and remaining slow gameplay are explicit.

Prepared with AI assistance.

@authurtabo-byte
authurtabo-byte force-pushed the perf/agc-storage-texture-budget branch from ea0fcec to 79146e6 Compare October 21, 2026 03:52
@authurtabo-byte

Copy link
Copy Markdown
Contributor Author

@adriadam10 Thanks for the follow-up review. All 4 points have been addressed in the latest push:

  1. Performance Data under Identical Env (Constrained / Default Budget):

    • Setting APS5_TEXTURE_CACHE_MIB=1536 on both sides masked eviction pressure because 1536 MiB exceeded the title's storage working set (~600–800 MiB), preventing eviction on either side.
    • Under identical default dynamic budget (unsetting APS5_TEXTURE_CACHE_MIB on both sides, identical env: {"APS5_HANDOFF_SPIN_US":"150","APS5_PIPELINE_DISPATCH":"1","APS5_PIPELINE_DMA":"1","APS5_PREBUILD_THREADS":"8","APS5_PROFILE_DRAW":"1","APS5_TRACE_FRAMES":"5:5"}):
      • main (eaae7e069d18): p50 is 583.2 ms, p90 is 2577.5 ms, Driver.Packet.dispatch is 547.8 ms, and Vulkan.Dispatch.shader_resources is 578.8 ms due to catastrophic mid-frame cache thrashing.
      • PR candidate (2630f37d0a71): p50 drops to 361.8 ms (-38.0%), p90 drops to 449.1 ms (-82.5%), Driver.Packet.dispatch drops to 167.2 ms (-69.5%), and Vulkan.Dispatch.shader_resources drops to 72.7 ms (-87.4%).
      • Peak device-local usage is strictly bounded by ceiling: ~3.9 GB on main vs ~4.1 GB with retention, comfortably within the 6 GB physical VRAM limit.
    • Updated the PR description with the complete identical-env table, summary lines, and bound details.
  2. Unit Test Coverage:

    • Encapsulated the eviction loop into EvictStorageOnBudget and expanded core/libs/prx/libSceAgcDriver/tests/StorageCacheRetention.cpp to exercise the full loop outcomes:
      • Held entry survives and is spliced to the front while idle entry is evicted.
      • All held entries are retained up to ceiling (verifying splice, passed counter, and loop termination with break).
      • Idle entries anywhere in the cache are reached and evicted while held entries splice past them.
      • Over ceiling, all entries (held or idle) are evicted.
      • Unaccounted entries (accounted == 0) survive eviction.
    • ctest -R agc_storage_retention passes 100%.
  3. Code Cleanup:

    • Removed the duplicate const bool over local check at ShaderResources.cpp:1174 and simplified the branch to else if (keep) since keep already guarantees within-ceiling for accounted entries.
  4. Rebase & Overlap Coordination:

@JJenkx

JJenkx commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

AMD/Linux data point on another title with a large Vulkan.Dispatch.shader_resources cost. On this title this PR makes no measurable difference.

Setup

Run presents in the 30 s window frame p50 ms Vulkan.Dispatch.shader_resources ms/frame GPU busy ms/present
this PR 13 2606 1741 959
this PR 14 2577 1570 947
base 13 2146 1705 973

In this menu scene, dispatch shader resources cost about the same with and without the PR. So the cost here does not seem to come from storage textures evicted and re-created at the budget. There is no regression either: no GPU events and no new errors. With 13–14 frames per window the frame times are noisy, so I would not read the p50 difference as a slowdown.

AI-assisted: yes (Claude Code); results above were run on this machine.

@SleglJan

SleglJan commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

A data point from 007 First Light (PPSA11386, content 01.018.000) on Linux 7.2.10, RTX 3080 10 GB, driver 615.78.08, Ryzen 9 7950X3D, 64 GB, Release builds, 3840x2160, warm shader cache, identical environment on both sides (APS5_PROFILE_DRAW=1, APS5_TRACE_SUMMARY_EVERY=60) and no APS5_TEXTURE_CACHE_MIB on either (dynamic budget). It counts storage-budget collapses with and without this PR on this title, and the PR's memory cost.

Storage-budget collapses with less headroom. From early gameplay, before the first prompt scene at about present 1,600, the storage image cache budget can fall to its 512 MiB floor and keep returning to it (P 11, 13 and 21 times, S 17, in the collapsed runs below). Those runs reached presents 1,596-1,689 in their 1,500 s, the others 2,101-2,227. With the heap budget the texture budgets see lowered by 500 MiB and by 250 MiB:

  • P: 3 of 5 (1 of 2 at -500 MiB, floor first seen after present 1,391; 2 of 3 at -250 MiB, after 1,435 and 1,389);
  • S: 1 of 5 (0 of 2 at -500 MiB; 1 of 3 at -250 MiB, after 1,394).

S's one collapse came with device memory full: 9,906 of 10,240 MiB in use (all processes), 305 device allocations that failed with VK_ERROR_OUT_OF_DEVICE_MEMORY and succeeded after a reclaim, and placements in host memory on both paths (at least 512 after a failed allocation, at least 1,024 ahead at the heap budget; these lines print only at counts 1-5 and powers of two, so those counts are lower bounds). P's three collapses had 8, 8 and 11 such recovered failures and peaked at 9,440, 9,598 and 9,659 MiB in use.

Cost in the runs that did not collapse (both series above, plus 3 runs per side at default headroom stopped at present 1,580):

  • Title's device memory (nvidia-smi pmon, peak per run): S 8,334 MiB mean over 7 runs, P 7,898 MiB over 5 (+436). At default headroom: S 8,447, 8,365, 8,438 vs P 8,176, 7,918, 7,901 MiB (means 8,417 vs 7,998, +418), the same direction as the ~3.9 vs ~4.1 GB peak device-local usage reported above on 10-21.
  • Recovered VK_ERROR_OUT_OF_DEVICE_MEMORY allocations in gameplay: S 12, 11, 16, 9, 13, 16, 13; P 2, 5, 1, 1, 4.
  • Peak RSS (VmHWM): S mean 20,059 MiB over 7 runs (18,566-24,140), P 20,660 over 5 (18,804-22,781); at default headroom S 19,670, 18,566, 18,636 vs P 19,739, 20,685, 18,804 MiB. (Correction: these are each run's highest 10 s VmRSS sample, not VmHWM; the VmHWM figures are in perf(agc): retain in-use storage textures up to budget ceiling #7833 (comment).)

Early gameplay at default headroom (present 1,420, shortly after gameplay start, to the stop at 1,580, about 160 frames, 3 runs per side), per frame:

P1 P2 P3 S1 S2 S3
sampled textures created 821.8 741.3 471.6 321.0 281.5 333.8
their allocate + image creation, ms 158.2 96.7 65.2 45.6 23.5 82.9
storage images created 151.2 128.1 130.2 144.3 143.3 142.4
storage image creation, ms 62.8 28.8 27.1 64.0 55.8 56.8
FPS 0.44 0.55 0.55 0.52 0.56 0.46

Storage image creations are not lower with S in this stretch; sampled texture creations are (I have not traced why). Storage creations inside the prompt scene were not compared. Frame time p50 from each run's gameplay start to the stop (138-185 presents per run; presents-weighted mean of the ~60 s summary windows' p50): P 1,499 / 1,367 / 1,317 ms, S 1,255 / 1,239 / 1,476 ms.

So in these runs on this title and card, fewer reached the storage-budget floor with S (1 of 5 against 3 of 5, five runs per side), at about +420-440 MiB of device memory and more out-of-memory recoveries; the run where S did collapse was the memory-full kind. Early-gameplay FPS: mean 0.51 on both sides; frame p50 overlaps (P 1,317-1,499, S 1,239-1,476 ms).

AI-assisted: yes (Claude Code)

@harry-z-kang

Copy link
Copy Markdown
Contributor

@authurtabo-byte I opened draft #10194 for the opt-in allocation breakdown requested in #10041. The overlap audit flags the storage-budget calculation: your StorageLimits/storageLimits change intersects my report insertion.

My proposal is to keep your existing merge order and rebase the accounting work after yours lands, preserving your ceiling/retention policy and reporting the resulting budget snapshot. Your PR does not need to wait for #10194. Does that order work for you? If the accounting lands first, I can help resolve the reporting hook here.

The accounting branch builds independently and changes no cache policy. Its test results and overlap details are in #10194. AI-assisted: yes.

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-checked the new head (79146e64f0). The test point is resolved: the loop is now EvictStorageOnBudget and the new cases pin held-survives, idle-evicted, over-ceiling-evicts-all and unaccounted-survives; over is gone. Remaining:

  • Gain not reproduced outside your machine. The default-budget win (p50 583 → 362 ms) is from one RTX 3050 6 GB laptop; with the same APS5_TEXTURE_CACHE_MIB on both sides the A/B was 7.6% slower at p50. Independent runs: Code Violet on RX 6650 XT shows no difference; 007 First Light on RTX 3080 10 GB shows the same FPS, storage creations not lower, and +~420 MiB device memory with 9-16 recovered VK_ERROR_OUT_OF_DEVICE_MEMORY allocations per run against 1-5 without the PR (fewer budget collapses, 1/5 vs 3/5). Please show a second machine where frame time or creation count improves, or scope the retention so it does not hold extra memory on cards where it doesn't help (docs/rules memory bound: it must pay for itself).
  • Ordering: as agreed, #8672 lands first (#6194 and #6202 also touch cachedStorageTexture()/storageBudget()); rebase on top of it, keep its reclaim-and-reread step, and re-measure, since the ceiling depends on the budget those set. #10194 also touches storageLimits.

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

Copy link
Copy Markdown
Contributor

A correction to my comment of 2026-10-22 (#7833 (comment)), the "Peak RSS (VmHWM)" line under Cost in the runs that did not collapse. Those figures were each run's highest VmRSS sample, not its VmHWM: the harness reads both from the title's /proc/<pid>/status every 10 s, and my summary took the VmRSS column. The same 12 runs, re-read from the same samples (MiB):

  • VmHWM: S mean 20,888 over 7 runs (19,555-24,338), P 20,903 over 5 (19,000-22,793). The posted figures (each run's highest VmRSS sample) were S 20,059 (18,566-24,140), P 20,660 (18,804-22,781); they reproduce from the samples.
  • At default headroom (the runs of the early-gameplay table):
P1 P2 P3 S1 S2 S3
VmHWM 20,156 20,749 19,000 20,947 19,711 19,555
posted (highest VmRSS sample) 19,739 20,685 18,804 19,670 18,566 18,636

VmHWM is above the highest sample by 12 to 1,277 MiB per run (S 167-1,277, P 12-525; a 10 s sample can miss the peak). The VmHWM means have S 15 MiB below P; the posted figures had S 601 MiB below P. No other number in that comment came from this column, and its summary did not use it. Both columns count resident memory only; zram swap was allowed for the title in all 12 runs, on both sides.

AI-assisted: yes (Claude Code)

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

Labels

agc libSceAgc* build needs rebase Conflicts with main, rebase needed perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants