Skip to content

perf(agc): relocate cached draws across user words that only reach the shader as values - #6539

Open
TheAggie wants to merge 17 commits into
boykopovar:mainfrom
TheAggie:perf/agc-draw-forwarded-words
Open

TheAggie wants to merge 17 commits into
boykopovar:mainfrom
TheAggie:perf/agc-draw-forwarded-words

Conversation

@TheAggie

@TheAggie TheAggie commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What

Third step for #4054, stacked on #5609. A user-data word that the resource walk never reads, and that the compiled stage only receives as a pushed value, still took part in the draw key and in the relocation alias. RADV's base-vertex SGPR is one: it changes on every draw, so a title whose draws would otherwise relocate across its moved pointers missed on every draw anyway. On Ratchet & Clank under RetroArch's PCSX2 core, 0.1% of draws hit the cache.

  • A stage's capture now also records which of its pushed user words (shaderDataUserWords) the resource walk did not read at all: DispatchVariant::forwardedWords.
  • When a shader set's relocation is learned and it has at least one read-through pointer word, those forwarded words are learned beside the pointers, marked forwarded. They stay out of the alias key, a relocation accepts any change to them, and the new value is patched into the pushed data the same way a moved pointer's value is.
  • A shader set whose user words are all plain values is left to main's data-only path (perf(agc): cache a draw key the second time it is seen #5216's shape reuse), which already owns that case. A relocation that finds the draw's decode but not every stage also gives way to that path when it applies, instead of claiming the draw with an incomplete entry.
  • The variants and entries a relocation clones come from a small pool that keeps their vectors' capacity (returned when the last reference drops), and the per-stage move and patch lists are thread-local scratch: a draw whose pointers move every draw no longer pays nine heap allocations a stage for its clones.
  • APS5_NO_FORWARDED_RELOCATION=1 turns the forwarded words off; APS5_NO_DRAW_RELOCATION=1 still turns the whole thing off.

Related: #5656 (on #494) lets a data-only hit reuse a stage whose changed user words it never reads; it counts the words a layout forwards into shader data as read, so a changed forwarded word still recompiles the stage there. This PR patches such a word on the relocation path instead. The two touch different paths and no shared code.

Only the commits after #5609's head are this PR.

Tested

Windows 11, NVIDIA GeForce RTX 5070 Ti, MinGW-w64 GCC 15.2.0, on main 940eba9a2 with #4943 and #5609.

  • ctest: 1271 of 1292 pass, 14 skipped. guest_call_trace_abort, windows_backtrace_report and agc_driver_store_over_untracked fail, and fail the same way on plain main here; agc_driver_prepared_graphics_prebuild_0/_1 and undeliverable_host_exception fail under my test runner because it skips their environment changes and pass pattern, and pass run with those; agc_driver_multisample_fill_host_only failed once in the parallel run and passes alone.
  • New case in agc_driver_draw_cache_relocation: a pixel shader reads its red channel through a user-data pointer and its green channel from a user word it gets as a value. Eight draws with the same contents at moving addresses and a changing green value hit the cached draw from the fifth on (0 hits with APS5_NO_FORWARDED_RELOCATION=1), and a hit given green 1.0 writes 255 to the target (64 if the value is not patched: checked by removing the patch).
  • main's agc_driver_draw_cache_reuse cases pass unchanged: their user words are plain values, which still go through the data-only path.
  • RetroArch (PPSA99169) with its PCSX2 core running Ratchet & Clank's intro, pipelined draws, immediate present, audio muted, same build with and without: draw-cache hits from 0.1% to 99.8% of lookups, captures per 10 s from about 460,000 to 950, queue worker from 24.8 to 13.0 µs per draw packet, audio produced in the heavy intro scenes from about 17% of real time to 24-25%. The rest of the gap is the draw pipeline draining on RADV's per-draw cache prefetches, which perf(agc): a DMA_DATA prefetch keeps the draw pipeline #6538 addresses; with both, the same scenes reach 37-43% and the lighter ones real time.
  • The pool, same title, same build with and without it, two alternating runs each: heap allocations per draw (counted with a hook on the driver's operator new imports) 167 to 136, audio produced in the heavy intro scenes 41-43% of real time to 45-47%.
  • Same title with APS5_VERIFY_DRAW_ENTRIES=1, which captures every hit again and compares: 0 stages differed; the last four 10 s windows of the run captured 868,744 hits again.

Checklist

🤖 Generated with Claude Code

TheAggie and others added 17 commits October 15, 2026 09:26
…y reads through

The SRT evaluator records every raw read with the user-data word its address is
based on, and marks a word used as a plain value. The result also names the
user-data word behind each shader-data dword.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A draw whose user-data words differ only in pointers the capture read through
looks up an alias key built from the contents behind them, shifts the cached
variant's runs by the pointer delta, validates them by value and patches the
forwarded shader-data words.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pixel shader loads its colour through a user-data pointer. Drawn from a third address with the same contents it hits the cached draw; with other contents it does not; the addresses seen before still hit exactly.

AI-assisted (Claude Code).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… user words

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

With APS5_VERIFY_DRAW_ENTRIES=1 every hit is captured again, so drawHit is false and no relocated hit counted for its shader set's trial, which judged every set unproductive and turned the relocation off under the very mode meant to check it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…; patch relocated push constants without copying the result

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…prepared shader

A stage's donor is found by its prepared shader, its own user words and the
contents behind its relocatable words, so a texture learned under one state
serves every state. A draw whose first stages validate reuses them when a later
stage misses, and a known decode is reused on a miss.

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

The recompiler reports the captured words that are a buffer descriptor's base
address and nothing else (never an operand of the walk), and where each lands in
the result. Validation masks them, and a hit that differs only there patches the
new addresses into a copy of the result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…thout a copy

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…utside merged programs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pixel shader loads a buffer descriptor through a user-data pointer and reads its colour from that buffer. Drawn again with the descriptor's base address changed, with the same or other contents, it hits the cached draw; with APS5_NO_DRAW_RELOCATION=1 it does not.

AI-assisted (Claude Code).

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e shader as values

A pushed user word the resource walk never reads (RADV's base-vertex SGPR, new on every draw) took part in the draw key and the relocation alias, so a shader set whose pointers moved could never match. Such words are learned beside a set's pointer words as forwarded: left out of the alias, accepted on a relocation and patched into the pushed data like a moved pointer. A set without any pointer word, and a relocation that cannot reuse every stage, leave the draw to main's data-only path.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… draw with the word patched

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every relocated stage was deep-copied into a fresh variant and a fresh entry built, nine heap allocations a stage, on every draw whose pointers moved. The clones and entries now come from a small pool that keeps their vectors' capacity, returned when the last reference drops, and the per-stage move and patch lists are thread-local scratch. On Ratchet & Clank under RetroArch's PCSX2 core, 31 fewer heap allocations per draw out of 167.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 15, 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 862 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1191 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 1368 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1395 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1896 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 4072 core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/shader/recompiler/Recompiler.cpp
PR 4448 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5021 core/shader/recompiler/Recompiler.cpp
PR 5315 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
PR 5371 core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
PR 5404 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
PR 5431 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 5441 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 5941 core/shader/recompiler/Recompiler.cpp
PR 6009 core/shader/recompiler/Recompiler.cpp
PR 6010 core/shader/recompiler/Recompiler.cpp
PR 6108 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6185 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 6186 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Recompiler.hpp
PR 6197 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6202 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6218 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6235 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.hpp
PR 6249 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6280 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6292 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6412 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6481 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6488 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6501 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6612 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 6615 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6639 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.hpp
PR 6656 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Dispatch/DispatchCache.hpp
PR 6682 core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6727 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6741 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 6801 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.hpp
PR 6804 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 6820 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6848 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6858 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Optimization/include/Optimization/ResourceProgram.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6879 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6924 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6946 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6947 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Dispatch/DispatchCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Shaders.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Optimization/include/Optimization/BindingAllocator.hpp
core/shader/recompiler/Optimization/include/Optimization/ResourceProgram.hpp
core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6948 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6959 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6960 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6970 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6971 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6973 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6987 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6989 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6995 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7002 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7048 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7085 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7201 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 7223 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7233 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 7256 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7275 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 7307 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 7310 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7369 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Dispatch/DispatchCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRelocate.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/tests/execution/DrawCacheRelocation.cpp
PR 7371 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 7395 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7410 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 7446 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 7464 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 7484 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 7508 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRelocate.cpp
PR 7514 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7522 core/shader/recompiler/Recompiler.cpp
PR 7550 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7604 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7622 core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Dispatch/DispatchCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Shaders.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Optimization/include/Optimization/BindingAllocator.hpp
core/shader/recompiler/Optimization/include/Optimization/ResourceProgram.hpp
core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7644 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 7668 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7684 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7689 core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7691 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 7799 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7800 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7803 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 7816 core/shader/recompiler/Recompiler.cpp
PR 7817 core/shader/recompiler/Recompiler.cpp
PR 7831 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7888 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7893 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 7930 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7978 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 8004 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 8077 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 8083 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 8115 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 8126 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8145 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 8160 core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 8161 core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 8180 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 8212 core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
PR 8223 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 8246 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8261 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8339 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 8340 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 8372 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
PR 8374 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
PR 8429 core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
PR 8484 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8489 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 8495 core/shader/recompiler/Recompiler.hpp
PR 8518 core/shader/recompiler/Optimization/include/Optimization/SrtWalker/SrtEvaluator.hpp
core/shader/recompiler/Optimization/src/SrtWalker/SrtEvaluator.cpp
PR 8538 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 8563 core/shader/recompiler/Recompiler.hpp
PR 8564 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 8612 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 8632 core/shader/recompiler/Optimization/include/Optimization/SrtWalker/SrtEvaluator.hpp
core/shader/recompiler/Optimization/src/SrtWalker/SrtEvaluator.cpp
PR 8658 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Recompiler.hpp
PR 8707 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8713 core/shader/recompiler/Recompiler.cpp
PR 8740 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 8751 core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 8756 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 8792 core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
PR 8858 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 8881 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 8883 core/shader/recompiler/Optimization/include/Optimization/SrtWalker/SrtEvaluator.hpp
core/shader/recompiler/Optimization/src/SrtWalker/SrtEvaluator.cpp
PR 8887 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8908 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8911 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8932 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8939 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 8963 core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 8992 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 8998 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8999 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 9020 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 9049 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
core/shader/recompiler/Recompiler.cpp
PR 9050 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 9129 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
PR 9176 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 9177 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
PR 9183 core/shader/recompiler/Optimization/src/DescriptorBindingBuilder.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 9185 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 9193 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 9202 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 9243 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
PR 9248 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Dispatch/DispatchCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRelocate.cpp
PR 9274 core/shader/recompiler/Recompiler.cpp
PR 9287 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 9289 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 9335 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 9348 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 9356 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Shaders.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 9373 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 9387 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCapture.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Shaders.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 9396 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRelocate.cpp
core/libs/prx/libSceAgcDriver/tests/execution/DrawCacheRelocation.cpp
PR 9400 core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 9401 core/libs/prx/libSceAgcDriver/Graphics/include/Pipeline.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 9412 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 9424 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp

@nicolasfalesy

Copy link
Copy Markdown
Contributor

Tested on Linux (Arch), c++ (GCC) 16.2.1 20260810, Release, BUILD_TESTING=ON, main at 5d9dcc42d2ec5401aebd089028b8d4d7410a77b4. GPU tests ran on lavapipe (Mesa 26.2.2, llvmpipe with LLVM 22.1.8).

With the dependencies from the description (#4943 and #5609) merged first, agc_driver_draw_cache_relocation aborts (2 of 2):

corrupted double-linked list
agc_driver_draw_cache_relocation ...Subprocess aborted

main plus #4943 plus #5609 without this PR passes the same test (2 of 2). main alone does not have the test. glibc detects a heap corruption, so a write past a buffer or a double free happens somewhere in the code this PR changes or runs. I did not find the exact line.

AI-assisted: yes

@alfalfa-star

Copy link
Copy Markdown
Contributor

Root cause of the corrupted double-linked list abort that @nicolasfalesy reported in agc_driver_draw_cache_relocation.

Reproduced on Linux (Arch), RX 9070 XT (RADV, Mesa 26.2.4), Release, PR head 12a5f02d1: 14 of 15 runs abort. The abort is in static destruction at process exit:

#9  RelocationPool<DrawEntry>::~RelocationPool()
#10 ?? () from libc.so.6
#11 exit ()

entryPool() and variantPool() in DrawRelocate.cpp are function-local statics. relocateDrawEntry calls entryPool().Take() before cloneVariant first calls variantPool(), so the entry pool is constructed first and destroyed last. Its spare DrawEntry objects still hold stages (cleared only when an entry is taken again). Those stages hold shared_ptr<DispatchVariant> objects whose deleter calls Return on variantPool(), which is already destroyed by then. ~RelocationPool<DrawEntry> deletes the spare entries, the variant deleters push into the destroyed pool's vector, and glibc catches the heap corruption.

Fix tested on the same head: make both pools immortal, the same pattern as other process-lifetime singletons in the driver:

RelocationPool<DispatchVariant>& variantPool() {
    static auto* pool = new RelocationPool<DispatchVariant>();
    return *pool;
}

RelocationPool<DrawEntry>& entryPool() {
    static auto* pool = new RelocationPool<DrawEntry>();
    return *pool;
}

With this change agc_driver_draw_cache_relocation passes 10 of 10 runs. Clearing an entry's stages in Return would also work, but the immortal pools also cover any other object that keeps a pooled variant until exit.

AI-assisted: yes (Claude Code)

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

blawesom commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Rebase handoff + independent confirmation of the abort — rebased onto current main (both commits, authorship unchanged). The conflicts: Pipeline::Continue keeps main's optimized->Schedule() atop this PR's apply restructure, and the disk-cache static_assert is pinned to the merged tree's actual RecompileResult size (488 — main restructured it since your base).

Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release, BUILD_TESTING=ON, AMD RX 9070 XT / RADV):

  • builds; tools/check_conventions.py --base origin/main passes
  • agc_driver_draw_cache_relocation aborts with corrupted double-linked list — 1/1 on my runs, matching your root-cause analysis from this morning (the entryPool/variantPool static-destruction order). Same device class as your repro (RX 9070 XT / RADV), so this is a second confirmation on the same head 12a5f02d1 (pre-rebase) rather than new information — the rebase does not change it.
  • one more observation: agc_driver_same_queue_label_wait failed once in parallel runs and passed solo — the second draw-state-filtering PR where I have seen that test flake (also on fix(agc): refuse mesh-path draws on a device without mesh shaders before validating them #6523); if your destruction-order fix lands, that pair may be worth a look too.

To pick it up:

git fetch https://github.com/blawesom/AnyPS5 rebase/6539
git checkout <your branch>
git merge --ff-only FETCH_HEAD

Head is 51c11a856 (amended to fold in the Continue/Schedule repair).

@blawesom

Copy link
Copy Markdown
Contributor

Correction on the agc_driver_same_queue_label_wait remark above: root-caused to my machine, not this PR — the card heat-soaked after a long verification day (junction ~95°C) and that timing-sensitive test's measurement flips when hot; it passes again after four minutes idle on the same build. Not a signal about this PR or your destruction-order fix. Please disregard.

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

Copy link
Copy Markdown
Contributor

Reviewing this for a possible 007 Windows cross-test after our current loading probe. Public baseline63ec3b290 is mainca13a56a5 plus the title's carried fixes and #6616; 150 selected native checks pass, one Linux-only import case skips. Menu remains1.911FPS, GPU180.25ms/present, so there is still substantial CPU preparation cost. Recent menu report: 9.4k draw packets/10s, 14.9k captures, per-packet capture150us, recompile/materialization246us, key/lookup/validation95us, graphics-lock wait192us. These are inclusive phase labels, not proof your optimization applies. Draw-cache hits remain low; no benefit claimed from this PR yet.

GitHub reports current heads #6539=12a5f02d and #5609=09238da8 conflict with main. Do you have a newer current-main rebase/WIP to use before I duplicate that integration work? I can review/adapt meanwhile; no title data needed.

Overlap to preserve: our #7508 at858c36315 replaces the per-word tagging scan in tagVariantRuns with ForEachRelocationRun; it retains #6454's AppendSharedWords first inside each emitted partition callback. SleglJan already cross-tested that combination on Linux and noted your adjacent edit. Public integration has that same partitioning. Any combination needs both provenance/shared-word handling and the forwarded-value patches, with the existing changed-green readback control kept. I will report exact heads and native/title evidence for an actual test. AI-assisted: Codex; raw title data remains local.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks for this. Two things before it can be reviewed:

  1. agc_driver_draw_cache_relocation aborts with corrupted double-linked list on this head, the static-destruction order of entryPool/variantPool described in the thread. Could you push that fix?
  2. The branch is far behind main and conflicts in DrawRelocate.cpp, Pipeline.cpp, DrawCacheRelocation.cpp, SrtDescriptorEvaluation.cpp, SrtEvaluator.cpp and ShaderDiskCache.cpp. Relocation has changed on main since your base (stage-data patches for relocated hits, the mesh index descriptor on relocated stages, shared words recorded by run). Please rebase onto current main and say whether the value-only user-word rule still holds on top of those changes.

@JJenkx

JJenkx commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Additional local integration evidence for the pool-lifetime and current SRT metadata concerns above (AI-assisted: yes).

I combined PR head 12a5f02d10fd8bfeedf101df27cb079a3b01f5b1 with main 7526640c3c1c5ea236c33b43b854681e8d169745 and the carried HTILE integration; local integration commit 1a1f519ebfe9dce77b3f3aaf1be96f205d46d162. This is not a current-main-only comparison or a performance result.

  • An alternative to immortal pools is to give RelocationPool<T> shared ownership and capture that owning pointer in each returned object's deleter: [pool = this->shared_from_this()](T* released) { pool->Return(released); }, with each pool accessor holding a static std::shared_ptr<RelocationPool<T>>. This keeps a pool alive until its outstanding objects are returned during shutdown.
  • Address-relocated variants need their copied shared validation metadata cleared before rebuilding address-bound runs in this integration.
  • The SRT tape needs the same provenance accounting as the basic evaluator: preserve forwarded/nested operand reads, record readInstructions and descriptor sourceLeads, and roll back those additions when a tape walk refuses. Before that adaptation, agc_driver_draw_cache_moved_buffer failed on the tape path while the APS5_NO_SRT_TAPE control passed.

After these adaptations, seven focused tests passed five repetitions each (35 executions): shader disk cache, moved buffer, relocation, and draw-cache reuse/default-off/verify/inline. Linux/RADV, MALLOC_PERTURB_=165, ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1, VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation; no VUID errors, skips, or missing-layer warnings in that log.

Hades II native controls also completed, but do not establish a forwarding performance benefit or regression. An initial cold-cache run had black timed captures during a long frame stall; a later ordinary-settings repeat rendered the hub. The cache conditions differed, so the initial black captures should not be attributed to forwarding from these runs. This does not settle the general value-only rule or replace the requested current-main rebase/review.

@JJenkx

JJenkx commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

The repair source is now available on JJenkx/AnyPS5, fix/descriptor-relocation-integration, rebased onto main 2185dbf92e8d9013a1620d2dfc95de50494e19f8. Prerequisite commits from #5609 and #6539 retain their original authorship. This is a tested integration branch for review/cherry-picking, not a replacement PR or a performance claim.

The relevant repairs are:

  • 586c05cf71: retain the relocation pools in outstanding objects' deleters so cached-object cleanup cannot return an object to an already destroyed pool. Before the repair, the relocation test aborted during shutdown; after it, the test exits normally.
  • 572fe318ce: record tape readInstructions, operandReads and descriptor sourceLeads, preserve operand nesting, and roll the metadata back on tape refusal. The differential tape/interpreter regression fails without this repair (read provenance has a different size from the reads) and passes with it.
  • 4184001cff: patch moved descriptor bases when a data-only hit validates as EqualData, with moved-buffer and changed-length regression coverage. This builds on the preceding data-only integration commits in the branch; it is not a standalone patch against main.

Matched focused validation on Arch Linux / AMD Radeon RX 6650 XT / RADV 26.2.4:

  • Main 2185dbf92e: 5/5 matching tests pass.
  • Integration 572fe318ce: those five plus the dependency's new moved-buffer test pass (6/6).
  • Both logs have zero VUID- messages, missing validation-layer warnings, or skipped tests.

Both runs used:

ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 \
VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
ctest --test-dir build-full -R '^(agc_shader_memory|agc_driver_draw_(data_hit_user_words(_verify)?|cache_relocation|cache_moved_buffer)|agc_shader_disk_cache)$' -V

The moved-buffer test is absent on main; the other five test names match. Conventions checks pass. These results establish focused correctness coverage, not a title FPS improvement. AI-assisted: yes.

@JJenkx

JJenkx commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

A matched Hades II measurement is now available for the integration branch above (AI-assisted: yes). This pair does not show a speedup.

Baseline 17558c1cd1bb8b8cb6c0e44c4a7ea7af774016f5 is main 9a97ac784da5d40cc7b7d968898ffbf5b8b5377a plus the refreshed #6300 depth dependency. Candidate 64ba4ebacf38fead38f699555b2418e1c24463a6 adds the combined descriptor relocation stack and its integration repairs. This is a dependency-baseline comparison, not a main-only result or an isolated measurement of #6539.

Both legs used identical starting save hashes, the same inputs and rendered Underworld room, separate initially empty shader/Mesa caches, the same hardware and trace settings (APS5_TRACE_SECONDS=160:15, APS5_TRACE_EVENTS=1048576). Both compiled 199 shaders from cold caches, exited normally, restored the kernel setting, and produced complete traces (trace_dropped=false). Both traces were processed with tools/trace_digest.py.

Metric Baseline Combined candidate
Frame p50 (ms) 21.811 23.136
Frame p90 (ms) 27.745 28.453
Frame p99 (ms) 34.273 34.594
Presents / trace duration 656 / 15.023s 632 / 15.010s
GPU busy ms/present 10.892 10.254

The official summary reports Driver.Draw.shader_compile_and_link at 9.366 versus 10.717 ms/frame and Shader.DrawStage at 6.105 versus 6.835 ms/frame. These are inclusive scopes; they do not mean actual shader compilation continued during the window. The candidate p50 was 6.1% higher in this single pair; that is insufficient to establish regression significance, but does not support a performance claim for this scene.

The complete official summary lines, full source pins and comparison conditions are in comparison.json. Full traces are retained locally. Next I will investigate preparation/lookup costs before proposing any speed claim.

@JJenkx

JJenkx commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

A bounded-cache correctness follow-up is available in 198bca0fd0 on the existing integration branch. AI-assisted: yes. This depends on the relocation stack; it is not an isolated patch against main or a performance claim.

learnPendingRelocation() previously pruned both alias maps whenever their size reached 16,384, including when learning only refreshed an existing key. Stage donors were also checked once before inserting multiple stages, allowing the map to exceed its bound within that loop. The helper now checks each insertion and prunes only for a new key at capacity; existing donors still receive refreshed payloads.

The regression exercises both stage and decode donor maps: updates at capacity preserve every other key and replace payloads; repeated new insertions retain the newest entry, stay within the bound, and account for evictions. The unconditional-pruning negative control fails with updating an existing alias evicted unrelated donors at capacity; the fixed implementation passes.

Full Linux libs build and five focused checks pass on AMD Radeon RX 6650 XT / RADV: shader memory, moved buffer, relocation, data-hit user words and its verification variant. Vulkan required, shader caches disabled, Khronos validation enabled; zero VUIDs, skips or missing-layer warnings. Conventions pass with the existing debt-length warning. These checks validate this integration, not a fresh main-versus-candidate comparison.

Hades II PPSA36082 also reached the expected Underworld room, then closed normally after 188 seconds; PID gone and kernel setting restored. Warm shader cache: 199 hits, zero misses. The sparse screenshot shows no obvious new corruption. Instrumented timings vary, so no title speedup is claimed. Native core validation was not requested; the validation result above applies to the focused tests.

Logs, source patch and compact validation evidence.

@JJenkx

JJenkx commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Matched measurement of the integration branch on another title and platform, where the miss pattern is exactly what this stack targets. It shows no gain; the candidate is slower here. AI-assisted: yes.

Setup

  • Machine: Windows 11 22621, RX 6700 XT, AMD driver 26.10.1, Ryzen 9 5950X.
  • Scene: Spirit of the Island (PPSA13934) title screen, no input, 150 s runs, APS5_TRACE_SUMMARY_EVERY=10, steady-state intervals from 60 s on.
  • Baseline: main 71401e331, plus the test-only test(agc): align the array window test's texels at run time #8310 so the tree builds on Windows.
  • Candidate: the same main merged with fix/descriptor-relocation-integration at 572fe318c. A local, unpublished merge: the only conflict was ShaderDiskCache::FormatVersion (43 vs 42), set to 44.

This scene issues ~1,650 draws per frame. With APS5_TRACE_DRAW_CACHE, main hits only 0.5–0.8 % of ~410k lookups per 10 s; almost every miss is user words/pointers only and becomes a data-only hit that still compiles ~1.5 stages per draw.

p50 frame (median of intervals) presents / 10 s GPU busy / present Driver.Packet / frame draw-cache hits
main 71401e3 104.8 ms 96 54.6 ms 96.9 ms 0.5–0.8 %
candidate 114.0 ms 88 51.1 ms 102.2 ms 1.4–1.5 %

Candidate data-only hits per 10 s: 219k stages reused, 530k compiled, against 208k/611k on main.

So the relocation path converts a few more lookups, but on this title the per-draw cost it adds outweighs that. That matches the earlier per-draw content hashing concern. The queue worker stays ~90 % busy in both builds, and the frame is worker-bound.

Summaries are in my local evidence; I can share the aps5-summary.jsonl pair if useful.

This branch has not been deployed

No deployments
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 numbers missing perf pull request without a before and after summary line perf Performance change shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants