Repository navigation
perf(agc): reuse heap mirror reference buffers between builds - #8874
Conversation
|
This pull request is labeled |
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
A matched-seed capture pair on a real title. It does not show a measurable gain from this change, so the PR stays in draft. Setup
Summary lines
Reading
So: no regression and no demonstrated improvement on this title. The PR needs a capture from a title where heap-mirror reference allocation shows up in the profile before it can leave draft. |
|
Third title, with a matched comparison: Code Violet (PPSA26528) on Linux/RADV. Shader-resource time is about 14% lower with this PR on the menu scene. Setup
Why this title. A DWARF profile of the control at 200–220 s puts
AI-assisted: yes (Claude Code); results above were run on this machine. |
|
Draft status, per the current readiness rule: this stays a draft for one specific evidence blocker, not for queue reasons. It is a
It becomes ready once a present-matched pair, from a title whose profile shows heap mirror reference allocation ( |
|
Correction to my Code Violet comment above: its setup said the runs used "identical shader-cache and save seeds". That was wrong. I have edited the comment.
The measured numbers are unchanged. The AI-assisted: yes (Claude Code); results above were run on this machine. |
|
Protocol note on my measurement above (comment 6332826974): it does not meet the performance-report protocol's "do not redirect the log" rule. The game's stdout and stderr were redirected to AI-assisted: yes (Claude Code) |
|
Controlled AMD/Linux run on Code Violet (PPSA26528). It replaces my earlier, unconstrained Code Violet numbers above, which remain observations only. Scope: integration-relative, not
Protocol
AI-assisted: yes (Claude Code); results above were run on this machine. |
317d528 to
404aab2
Compare
|
Rebased on Focused gate on the rebase: one build directory and the same command for every arm. Command:
Every arm prints only the two existing Windows guest-arena skips. The middle arm passing is expected: reuse changes no observable bytes. Performance evidence is @claude-research's controlled Code Violet run above (comment 6359360025): integration-relative, 8 alternating arms, with the seeds restored and hash-checked per arm. |
|
The official Pins, exactly as measured (integration-relative, not
These lines measure Each arm ran terminal-attached: AI-assisted: yes (Claude Code); results above were run on this machine. |
404aab2 to
082f3ec
Compare
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for the measurements; the reuse itself reads correct (Take/Return don't allocate, the reference keeps its own size, the new tests pin that). One blocker:
core/libs/prx/libSceAgcDriver/Graphics/src/ReferenceStorage.cpp:62:Shared()is a process-lifetime store that keeps up to 8 buffers / 2 GiB idle on every driver and GPU, and nothing frees it other than newerReturncalls evicting older ones. After a heavy scene ends, up to 2 GiB of RSS stays resident indefinitely. The PR body gives the bound but not what releases it, and there is no peak/steady RSS before/after. Please add:- peak and steady-state RSS on
mainvs this PR for the same scene (the Code Violet runs you already have are enough;/proc/<pid>/statusVmHWM/VmRSS sampled in both arms); - a release path (e.g. drop the idle buffers when no
GuestBufferMemoryholds references / after a period without a take, or at device teardown), or a justification for 2 GiB based on those numbers. If the cap is only needed for the largest scenes, a smaller default may keep most of the gain.
- peak and steady-state RSS on
Once that is in, the rest looks good to me.
|
@adriadam10 RSS for the review, measured on the same Code Violet scene and pins as my controlled run (6359360025). It was a new run: the earlier runs did not sample RSS. Pins: integration-relative, because plain
These are not the current head Protocol: as in 6359360025: seeds restored and hash-checked before each run, terminal-attached with no redirected output, no input, window set once to 1024x576 with no later changes, 300 s runs,
Limits. This is a single scene for the whole run, so it measures how much the pool holds while a heavy scene is live. It does not show whether that memory is released after the scene ends, which is your concern; the release path is the author's to add. Two runs per side; RSS includes everything else the process holds (about 10.7 GiB on the control). AI-assisted: yes (Claude Code); results above were run on this machine. |
082f3ec to
7a6f608
Compare
|
@adriadam10 thanks. Release path added in The change:
Tests: new
Docs: a debt entry records both unmeasured limits (8 slots / 2 GiB, 2 s). Exact-head gate (
Logs: RSS: the peak and steady VmHWM/VmRSS you asked for are being measured on the same controlled Code Violet setup as the performance runs (seeded, terminal-attached, sampled every 2 s): control vs the process-lifetime pool first, then this release-path head. I will post the numbers here when both are in, and keep this PR a draft until then. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@MarcZX10 refreshed on current Head: Focused gate on
Logs: https://github.com/JJenkx/AnyPS5/releases/tag/pr8874-current-main-gate-20261029 Still pending: the current same-title
They are queued on the shared GPU runner. Until they finish, this PR makes no new speed or RSS claim, and the AI-assisted: yes (Claude Code). |
✅ NVIDIA GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (5, not counted against this PR)Passed on retry (1, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)Validated but not compared (2, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 433 tests)Skipped (40)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
MarcZX10
left a comment
There was a problem hiding this comment.
Re-checked — new head, changes requested
The current head still lacks a performance report captured against current main, and the latest GPU run uses an older main snapshot.
What I ran
Reviewed head 9f226879bc5e9bd488022746b47dbaf714ec05d5; PR base is 899ae3d1ad32ccea94dc24e66fdc948ce8a88171. I compared it with current main fc9240dbc5dc89a6b17a739703e00d26318c7716; the merge preview is clean. No local build or tests were run.
git merge-tree --write-tree refs/remotes/upstream/main refs/review/pr-8874-head
git diff --check refs/remotes/upstream/main...refs/review/pr-8874-headResults
| Check | Result |
|---|---|
Merge preview onto current main |
Clean |
| Diff whitespace check | Passed (no output) |
| NVIDIA GPU workflow | CI report for this head, merged onto bb04a4f, reports 2,312 passed, 6 failures (0 new; 5 also on main and 1 unstable on main), and no new validation IDs |
| Local build/tests | Not run |
Unedited local command output
merge-tree: eb5442ba5bc743df10ea471d4a572047a62e721d
diff-check: no output; exit status 0
Findings
Blocking
- The PR remains labeled
perf. The newest author report says it contains no new title, RSS, or speed measurement; the latest GPU workflow is a correctness run, not a matched performance capture. The existing performance evidence therefore does not establish this change's performance against currentmain. - Current
mainhas advanced from the author's focused test base899ae3dand the GPU workflow basebb04a4f. The current-main diff overlaps this PR incore/libs/prx/libSceAgcDriver/CMakeLists.txt,core/libs/prx/libSceAgcDriver/tests/Graphics.cpp, anddocs/dev/debt/libSceAgcDriver.md. The clean merge preview does not update the reported test results or performance evidence to that merged tree.
Non-blocking
- The focused AMD report on head
9f22687reports 18/18 tests passing versus 16/16 on its899ae3dbaseline, with zero validation IDs. This is useful test evidence, but it does not cover currentmainor satisfy the performance report requirement.
Not verified
I did not build locally, rerun the focused tests, or run a performance capture. The AMD focused results and NVIDIA CI results above are contributor/CI-reported, not locally reproduced.
To get this to a good state
Please refresh onto current main, rerun the focused comparison on the resulting exact head, and add the required matched main/change performance captures for the same title, scene, and machine, including both aps5-summary.jsonl lines, traces, and tools/trace_digest.py output. I will re-run the same source checks and review the new exact head.
# Conflicts: # core/libs/prx/libSceAgcDriver/tests/BdaTests.hpp # docs/dev/debt/libSceAgcDriver.md
|
Merged current
No new performance claim with this merge. 🤖 Generated with Claude Code |
MarcZX10
left a comment
There was a problem hiding this comment.
Re-checked — new head, changes requested
The new integration report adds useful GPU correctness evidence, but it does not yet provide the required performance comparison or validation on the latest main snapshot.
What I ran
Reviewed head 0ae75877c9cb6238c59a6894f527cfe3221b42ee, integrated with main at 08a10d225306ad102b57408e2ef7566bcfb829b2; current main is 5ecef095b61e7a406b279c97896f3a8a6fbd6353. Current-main merge preview is clean (tree 58ac36f0761e2e9bbbfcc4dd56e3858bcb0187b5). Since the integration point, main changed five commits; the only shared changed paths are core/libs/prx/libSceAgcDriver/tests/Graphics.cpp and docs/dev/debt/libSceAgcDriver.md.
git merge-tree --write-tree refs/remotes/upstream/main refs/remotes/upstream/pr-8874
git diff --check refs/remotes/upstream/main...refs/remotes/upstream/pr-8874
git diff --name-only 08a10d225306ad102b57408e2ef7566bcfb829b2..refs/remotes/upstream/mainResults
| Check | Result |
|---|---|
| Merge preview | Clean |
| Diff check | Passed; no output |
| Hosted conventions and Windows | Passed |
| Focused AMD tests | Author reports 18/18 on this head and 16/16 on main at 08a10d2; not independently run |
| Performance evidence | No new same-title, same-scene, same-machine main/change capture pair is present |
Findings
Blocking
- The PR remains labeled
perf, while the new report is a correctness run and supplies no matched performance captures or the required report artifacts. This leaves the stated performance result unverified. - The new focused tests use main at
08a10d2. Current main has since changed the shared graphics test file; the reported pair therefore does not cover the latest test tree.
Not verified
I did not run a local build, GPU tests, or a performance capture.
To get this to a good state
Please attach the required matched main/change performance captures for the same title, scene, and machine, including both aps5-summary.jsonl lines, traces, and tools/trace_digest.py output. Please also rerun the focused main/change tests using current main 5ecef09 (or the corresponding exact merge tree). I’ll rerun the same source checks on the new head.
✅ NVIDIA GPU test: passedPR head
Unstable on main (2, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (2, not counted against this PR)Passed on retry (1, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)Validated but not compared (2, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 425 tests)Skipped (41)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
Re-check on current main
|
| Arm | Source | Result | Validation layer inserted | VUIDs |
|---|---|---|---|---|
| main | 1c6b316cf76 |
16/16 pass | 4 | 0 |
| change | c155740007f |
18/18 pass (adds agc_reference_storage, agc_heap_mirror_reference_size) |
4 | 0 |
The layer is inserted only in the four physical-GPU groups. The other groups use CPU or mock Vulkan.
2. Matched title capture: Echoes of the End (PPSA25636, 01.012.000), same machine
Plain main does not run this title on RADV. Both arms therefore use the same private stack: main 1c6b316 plus open PRs #4449 1f7640bad24, #8089 204cbc558d1, #11873 bcaac162594 and #6867 761ef1105e7.
- Base:
735aec0c60f. - Change:
ae6bf50f517, which is the base plus this PR at0ae75877c9c. Its diff from the base is exactly the PR's patch. - Merge resolution in the stack: three files (
ShaderRegistry.cpp,GuestArena.hpp,GuestArena.cpp) had both sides adding lines in the same spot, and both sides were kept.
Run setup:
- Four arms in alternating order (base, change, change, base). Each arm was its own FIFO launch.
- Before every arm, the same seed was restored: title shader cache, Mesa cache and save state, manifest
6a3bbca6eb39b28b. - 1460 s with scripted static pad input from a save, then Continue.
APS5_TRACE_SECONDS=1180:100, screenshots at 1140 to 1455 s.- All arms ended on the timer. The kernel logged no amdgpu events, and per-process
amd-evicted-vramstayed at 0 MiB.
| Arm | Commit | Presents in window | Frame p50 | GPU busy per present | Trace dropped | Scene at 1230 s | Left loading |
|---|---|---|---|---|---|---|---|
| 1 base | 735aec0c60fe |
13 | 7421 ms | 965 ms | no | loading | not by 1455 s |
| 2 change | ae6bf50f5174 |
71 | 853 ms | 461 ms | yes | in-world | 1181–1230 s |
| 3 change | ae6bf50f5174 |
31 | 1874 ms | 853 ms | no | loading | 1331–1400 s |
| 4 base | 735aec0c60fe |
51 | 901 ms | 498 ms | yes | loading | 1281–1330 s |
Result: inconclusive. I make no speed claim. The trace window does not show the same scene in all arms: three arms are still loading and one is in-world. Load completion overlaps between the arms (change 1181–1230 and 1331–1400 s, base 1281–1330 s and after 1455 s), and the arm-to-arm spread is larger than any plausible effect of this change. This capture does not show a regression either.
The PR's saving is in takeHeapReferences. It avoids allocating and zero-filling reference storage for each write-back. That cost is not visible as a separate trace phase on this route.
Evidence
Pins, both diffs, gate logs, all four aps5-summary.jsonl lines, traces, tools/trace_digest.py output, reports, screenshots and memory/eviction samples. SHA-256: 9847dea6abd35ab9b1d68618b70676792da44066a7dc0e27187c2d577d822dea (downloaded copy verified).
The branch head is unchanged at 0ae75877c9c. It merges cleanly into current main, so I did not push a refresh just to update its base.
🤖 Generated with Claude Code
|
Supplemental exact-head qualification — 2026-10-31 Merged main The sole conflict was adjacent includes in Paired focused gate, Release with SPIRV-Tools ON, AMD Radeon RX 6650 XT / RADV Mesa 26.2.6, Linux 7.2.11-arch1-1. Same selected groups as the earlier focused gate; one execution per group:
The change adds Qualification detail: both CTest commands exited0 and their JUnit files report every selected group passed. The wrapper then exited1 because its postprocessor incorrectly required physical-layer insertion in CPU/mock This maintenance adds no title capture or performance/RSS claim. The earlier matched capture remains inconclusive (comment6524722530). Existing external NVIDIA/Windows and older AMD evidence remains tied to its original pins and scope. Evidence: immutable source and paired GPU receipts (SHA-256 AI-assisted: yes. |
✅ NVIDIA GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (4, not counted against this PR)Passed on retry (1, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)Validated but not compared (2, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 426 tests)Skipped (50)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
|
Merged current main The conflicts were main's AGC CMake test split, the heap-mirror sweep signature and adjacent debt entries. Kept main's Paired focused Release gates, SPIRV-Tools ON, AMD Radeon RX 6650 XT / RADV Mesa26.2.6, Linux7.2.11-arch1-1, one execution per group:
Both ran verbose CTest with No new title capture, FPS, allocation or RSS claim. The previously matched title capture remains inconclusive (comment6524722530); historical Windows/NVIDIA/AMD reports retain their own pins/scopes. Evidence: frozen source and qualification receipts (SHA-256 |
✅ NVIDIA GPU test: passedPR head
Intermittent validation messages (1, seen once in the parallel run, not reproduced when the test was re-run alone 2 times; not counted against this PR)Unstable on main (4, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validated but not compared (2, not in the main baseline's validation pass)Validation IDs already present on main (5 IDs in 484 tests)Skipped (45)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
What
Reuse heap-mirror write-back reference buffers instead of allocating fresh storage for every build.
ReferenceStoragekeeps at most eight idle buffers and 2 GiB, and a take selects the smallest capacity that fits. The reference is resized to the served range before reading resident-mirror bytes; the bytes copied and compared remain unchanged. Take/return allocate no storage and arenoexcept; evicted buffers are destroyed after releasing the store lock.Buffers idle for two seconds are released when the store is polled by take, an eligible return, a heap-mirror sweep or present. This is polled expiry, not a background timer: if none of those operations occurs, expired buffers remain until a later poll or process shutdown. The cap covers idle storage, not active references. The cap and reuse interval remain unmeasured policy choices recorded as debt.
The rebase preserves current main's joined-heap cleanup, resident-mirror growth/readback path, heap-readback clearing and address-copy cap tests. It retains the reviewed pool implementation and tests; the additional documentation commit clarifies the polling limitation.
Tested
Current rebase qualification (2026-10-28)
@oneandonlydean Refreshed on main
2227f1366188cda5699dd20e2e756a18006a5d4basf31fdef05ba8bf532e19c461e2f758e860aa5fe9, retainingRunAddressCopyCapTests(int frames), addingRunHeapMirrorReferenceSizeTests, and keeping both debt entries. Original topic code/tests and current main gitlinks are preserved.Linux Release with bundled SPIRV-Tools enabled: main's 16 groups ×3 pass (48), candidate's 18 groups ×3 pass (54), and the restored candidate passes 54 with source and driver byte-identical to its initial build. The main-production
GuestBufferMemory.cppcontrol also passes all 18 groups: this is a compatibility control, not a distinguishing regression for the reuse optimization.Four groups execute physical RX 6650 XT/RADV Vulkan: host-import unmap, host-import retirement, sparse-run import and sparse-run copied import. Their logs verify Khronos validation insertion (12 per repeated arm; 4 in the single control), zero VUIDs, missing-layer diagnostics or skips. The remaining fixtures use CPU/mock Vulkan, including the new reference-size fixture; their passes are not hardware coverage. An initial all-tests-passing harness attempt was excluded because it incorrectly required real-loader insertion from mock fixtures; it is preserved, and the corrected matched pair is archived.
Complete harnesses and cleanup used the shared FIFO and service-owned PTYs. Conventions and whitespace pass. Ready status is retained. Earlier measured memory/performance results retain their original pins; no new title, Windows, full-suite or speed claim is made.
Exact source/dependency pins, source proof, builds, service/FIFO receipts, controls, logs and JUnit, SHA-256
60998673f17454df73307175ec04830d347894b5a463e00fddd1447d552c781f.Windows qualification, 2026-10-26: exact public head
f7aec2a96626947a8f98dccca567e220d1030039against pinned main49d1f9b07ec7f6f989ace1c504bbe9dd6748dcbb, built separately with WinLibs GCC 15.2.0 UCRT r7, Release, Windows 11 Enterprise 10.0.22621, AMD Radeon RX 6700 XT, driver 32.0.21045.16010. This verifies the Windows test-runtime PATH fix:agc_reference_storageandagc_heap_mirror_reference_sizeeach pass three times, and generated CTest metadata prepends the privatelibs/unpatcheddirectory.Main passes 16 executed groups × 3 (48 passes); the PR passes 18 × 3 (54 passes). Each selection additionally reports the same single expected skip,
agc_host_import_sparse(Linux-only udmabuf imports).agc_heap_mirror_unwatched_importis not registered on Windows. No other skips or failures. Four physical GPU groups per arm each execute three times on the RX 6700 XT with Khronos validation loaded (12 insertions per arm); other selected groups use CPU/mock graphics. Zero VUIDs in either arm and no new VUIDs. Vulkan is required and shader caches disabled.Both arms use the same private Khronos validation layer 1.4.309, source
3ba0e590a2e76475b3eef4043355b498fb64e752, built with the supported r7 toolchain. Initial attempts with an installed 1.4.363 layer failed to load because its libstdc++ imports were incompatible with r7; those runs are retained as rejected evidence. The final runs verify actual layer loading for every physical GPU repetition.Exact pins, source manifests, build/test logs, JUnit, CTest runtime metadata, VVL/runtime hashes, rejected-attempt diagnostics and terminal FIFO receipts. SHA-256:
4dc1fd9f52de1e1c4dc25b4bb96e29af74b48700ca34c1a89c8f3546457fcef7; downloaded copy verified. No new title, RSS or performance measurement is claimed.Current-main refresh, 2026-10-25: head
cab138246ad9984df92e6c7427118c2b3cac4fd7, five linear commits on main49d1f9b07ec7f6f989ace1c504bbe9dd6748dcbb. The four implementation/test commits are rebased, followed by a documentation-only expiry clarification. Production patch lines are unchanged from old public headd3e9e8a780c. Main's joined-heap expiry, resident growth/readback behavior and address-copy cap tests are retained. Source, conventions, whitespace and local merge-tree checks pass.Linux GCC 16.2.1 Release, Ryzen 9 7950X, RX 6650 XT/RADV Mesa 26.2.4, Arch Linux 7.2.9. Built full
libson both pinned main and candidate, plus main's four/candidate's five selected test executables. Main passes 18 groups × 3 repetitions (54 passes); candidate passes 20 × 3 (60 passes). Zero skips and zero VUID errors. Vulkan is required and shader caches disabled. All four real GPU groups load Khronos validation in each physical repetition (12 insertions per arm); other groups use CPU/mock graphics checks, not physical GPU execution. The matrix includes pool/reference size, heap mirrors, sparse/import lifetimes and current-main address-copy caps.A negative control delays only
ReleaseIdle's clock by the idle interval.agc_reference_storagefails ata buffer idle for the limit was not released. After removing that temporary fault, the full candidate selection passes 60/60 again, zero skips/VUIDs, and the raw driver plus all five tested executable hashes are byte-identical to the first candidate. This verifies the test catches the expiry boundary; it is not a new title RSS observation or proof of a background timer.Current source patch, preservation checks, full build logs, verbose main/candidate/control/restoration logs and hashes. SHA-256:
de1b6160e76668c554c0738012a48121a51909c809ca104d3a8d714996fe1271; downloaded copy verified.That Linux refresh included no fresh title, RSS, performance, Windows or full-suite run; the later Windows qualification is recorded above. Historical speed/RSS measurements below retain their original exact integration pins. The prior RSS scene kept using heap mirrors and did not exercise idle release; no measured release-induced RSS drop is established. The current description/debt explicitly correct the earlier implication of unconditional two-second expiry: release requires a subsequent poll.
Historical performance, RSS and earlier correctness evidence
082f3eceb9(2906f2ac44change +082f3eceb9test) onmain990f45e17d, prepared and gated by another AI worker on this machine (claude-research) and pushed here. Main had merged fix(agc): bind heap mirrors only where the guest holds bytes #7647 (resident heap mirrors), and the rebase keeps its semantics:takeHeapReferencescallsgrowResident, then takes reusable storage.resident->Read; otherwise they are assigned from the buffer.heapReadbacksis still cleared wheremainclears it.main's newagc_sparse_heap_mirror_budget.ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation VK_LOADER_DEBUG=layer ctest -V -j1 -R '^(agc_driver_graphics|agc_sparse_.*|agc_heap_mirror_.*|agc_host_import.*|agc_reference_storage)$'. Result: 18/18 pass, validation layer 1.4.363 inserted in 4 tests, 0 VUIDs.404aab2817on9af7d8d810),mainpassed 15/15 and this PR 17/17, both with 4 layer insertions and 0 VUIDs. The new tests also pass withGuestBufferMemorytaken frommain. That is expected: reuse changes no observable bytes, and the tests check that reused storage is correct (sizes and contents), not that reuse happens.maindoes not render the title (Code Violet (PPSA26528) #6256). Controlddeeddfff4ismain1a745ae38e+ feat(libSceAgcDriver): import scattered direct memory as a dma-buf run list and probe its coherence #4449 + fix(agc): keep the write-back ready barrier while hole copies are pending #8908 + a local fd guard. The candidate6208617c95is control + this PR at317d528af7, an earlier head with the same 9-file change.download0) were restored and hash-checked before every arm. 300 s at the title screen,APS5_TRACE_SECONDS=240:30, no dropped trace events.Resources.Complete: control 2038-2506 vs PR 1283-1985 ms/frame, no overlap; medians 2316 vs 1552.Earlier observations, kept for the record (not controlled evidence):
main9f4ddf7; this branch has the changecc53b45601and a test commit317d528af7.agc_reference_storage(CPU): empty store, reuse of the same allocation, smallest fit, eviction of the oldest by byte limit and by slot count (checked against the identities of the retained buffers), oversize storage, andReturn/eviction/Takewith the allocation-failure countdown armed (still armed afterwards, byte count consistent). A store whose eviction allocates terminates the test withstd::bad_alloc.ctest -R 'heap_mirror|sparse_heap|reference_storage|bda|guest_memory_lifetime|sparse' -Vonmainand on this PR, same machine and GPU,ANYPS5_REQUIRE_VULKAN=1,ANYPS5_NO_SHADER_CACHE=1,VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation(layer 1.4.363 loaded; neither log reportswas not found but was requested): main (9f4ddf7) 28/29, PR (cc53b45601) 29/30 (the extra test is the new one). Both failagc_driver_guest_memory_lifetimethe same way (radv/amdgpu: The CS has been rejected (-14),guest prefix unmap failed), and both logs hold the same validation errors: 2 ×VUID-vkCmdCopyBuffer-srcBuffer-00118, 2 ×VUID-vkResetFences-pFences-01123. No newVUID-.Before (integration
8a251ef745):seconds 40:60 from present 340: 11 presents, frame p50 5867.4 / p90 7221.6 / p99 7377.7 / max 7377.7 ms, GPU busy 543.2 ms per present
seconds 40:60 from present 351: 11 presents, frame p50 5427.9 / p90 6189.5 / p99 7141.4 / max 7141.4 ms, GPU busy 497.8 ms per present
After (integration + this PR,
6e0a219cbe):seconds 40:60 from present 343: 15 presents, frame p50 4069.4 / p90 5171.4 / p99 5460.5 / max 5460.5 ms, GPU busy 497.8 ms per present
seconds 40:60 from present 348: 16 presents, frame p50 4004.1 / p90 4933.0 / p99 5394.2 / max 5394.2 ms, GPU busy 479.7 ms per present
The title still loads at well under 1 FPS on both sides. The captures ran on an integration with the earlier base
33a6d6bbfb; the PR commit was cherry-picked onto it (6e0a219cbe). Traces, logs, screenshots, profiles and validation logs: evidence archive (SHA-25600bbfd328cc0ecbed29aedd3925217dc6e39a9a018170bd941549b5146af27be).APS5_TRACE_SECONDS=150:30, one run each, separate relinked runtimes, initial shader/pipeline cache state not reported as matched. Base maine0e57a3270+ fix(libSceVideodec2): answer the generic picture query for VP9 pictures #8839 (641fce5c84), change = base + this PR (91d0f400ba):Before: seconds 150:30 from present 26: 6 presents, frame p50 4885.1 / p90 7341.3 / p99 7341.3 / max 7341.3 ms, GPU busy 186.3 ms per present
After: seconds 150:30 from present 40: 6 presents, frame p50 5074.1 / p90 5685.3 / p99 5685.3 / max 5685.3 ms, GPU busy 178.7 ms per present
Resources.Complete5.29 vs 5.14 ms per dispatch: no measurable change in that title, where the per-dispatch cost is the copy and theWriteChangedcompare that this PR keeps. Traces (SHA-2564412bd6c74fc8493e765d3d33b970a6b947ef900e09e6a38384d0ebc4f659c25).agc_heap_mirror_reference_size(317d528) checks a smaller reference written back after a larger one reused its storage; withtakeHeapReferenceskeeping the storage's capacity as its size it fails withheap mirror write-back has no reference.python3 tools/check_conventions.py --base origin/mainpasses. The overlap tool reports fix(agc): fall back to device-local heap mirrors #8016 and fix(agc): bind heap mirrors only where the guest holds bytes #7647, which rewrite the same reference construction for device-local and resident heap mirrors; they do not reuse storage, and whichever lands later rebases onto the other.Supplemental exact-head qualification — 2026-10-31
Merged main
602c0e417ca11f53de54ffe7b3253e95cb93c0d4into previous head0ae75877c9cb6238c59a6894f527cfe3221b42ee, retaining the complete original history. New public head:e21b872338378862bd71db9b3d22de26b8a7dcea.The sole conflict was adjacent includes in
Recorder.cpp; both main'sDepthSurface.hppand this PR'sReferenceStorage.hppremain. The topic's added/removed lines are identical to its patch against08a10d225306; main's newer behavior, fixtures, debt and submodule pins remain. Conventions and whitespace checks pass. Fresh main85cdddc1b0e89fe66744f437513ccfdcb16f72f6changes no AGC/shader paths after the tested pin, and its merge preview is clean.Paired focused gate, Release with SPIRV-Tools ON, AMD Radeon RX 6650 XT / RADV Mesa 26.2.6, Linux 7.2.11-arch1-1. Same selected groups as the earlier focused gate; one execution per group:
602c0e417cae21b8723383The change adds
agc_reference_storageandagc_heap_mirror_reference_size. Both arms usedANYPS5_REQUIRE_VULKAN=1,ANYPS5_NO_SHADER_CACHE=1,VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validationand verbose CTest. Neither log reports the requested layer missing. The physical groups areagc_host_import_unmap,agc_host_import_retirement,agc_sparse_run_importandagc_sparse_run_import_copied; the remaining groups use CPU/mock Vulkan. The complete build/test harnesses ran through FIFO tickets1925/1926 under the explicitly title-free infrastructure reservation PPSA00004, now released.Qualification detail: both CTest commands exited0 and their JUnit files report every selected group passed. The wrapper then exited1 because its postprocessor incorrectly required physical-layer insertion in CPU/mock
agc_driver_graphics. The original failed wrapper receipts are retained. A separate audit (audit-raw.py,paired-raw-audit.json) validates the unchanged raw logs/JUnit against the actual four physical groups; no source or test behavior was changed, and no rerun is claimed.This maintenance adds no title capture or performance/RSS claim. The earlier matched capture remains inconclusive (comment6524722530). Existing external NVIDIA/Windows and older AMD evidence remains tied to its original pins and scope.
Evidence: immutable source and paired GPU receipts (SHA-256
5d3548a127cb5d60199c18cff61e1d7df947fa5923d79a73f33dc116311f01e3, download verified).AI-assisted: yes.
Supplemental qualification (2026-11-01)
Merged current main
93dbd0f82aea684e95f15f06e7d42c0064af18cfinto previous heade21b872338378862bd71db9b3d22de26b8a7dcea. New public head:de5afa814417a3123cb5f5388ae982bda52477ce.The conflicts were main's AGC CMake test split, the heap-mirror sweep signature and adjacent debt entries. Kept main's
sweepMirrors(neededBytes, protectAddress)behavior and the PR'sReferenceStorage::Shared().ReleaseIdle()poll; moved the PR's target/test registrations into the corresponding new CMake fragments. Kept main's updated host-import budget entry and this PR's storage-limit debt. All nonblank topic added/removed lines are identical to the previous topic patch; complete original history and main's gitlinks are retained. Conventions and whitespace pass.Paired focused Release gates, SPIRV-Tools ON, AMD Radeon RX 6650 XT / RADV Mesa26.2.6, Linux7.2.11-arch1-1, one execution per group:
93dbd0f82aeade5afa814417Both ran verbose CTest with
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, and neither reports the requested layer missing. Four host-import/sparse-run groups execute on the physical GPU; the other groups use CPU/mock Vulkan. The PR adds the reference-storage and reference-size regressions. Whole isolated build/test harnesses ran through the title-free PPSA00004 infrastructure reservation/FIFO (main2487, change2489), with service-owned PTYs; both wrappers and CTest exited0. A prior candidate ticket2486 was cancelled while queued, before execution, to remove a blank EOF in the new fragment; that receipt is retained.No new title capture, FPS, allocation or RSS claim. The previously matched title capture remains inconclusive (comment6524722530); historical Windows/NVIDIA/AMD reports retain their own pins/scopes.
Evidence: frozen source and qualification receipts (SHA-256
44a57b5d68d03b34fa53d61a4e20e2c54316d4ff607c86c66e0f99cf14723ae8, downloaded bytes and internal manifest verified).AI-assisted: yes.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)Contributor-reported attribution observation: @milescoviello measured Borderlands 4 PPSA01494 on RTX 4070 Ti / NVIDIA 615.71.09, Linux, warm shader cache, 600 s, with local phase counters. Their candidate is main
cbee224804plus this headf7aec2a966and #9858, so this is a mixed integration. The after-region upload phase averaged about 71 ms on control versus 27 ms on candidate; total slow-upload counts and other phase costs differed. This supports investigating heap-reference/flush cost, but single runs with an extra PR do not isolate this PR's frame-time effect or establish an FPS gain. No new local title run is claimed. Original report and full limits.External NVIDIA validation (2026-10-30)
TechLevelZero’s report tested exact head
0ae75877c9cb6238c59a6894f527cfe3221b42eemerged onto main98ddd9c: Release with SPIRV-Tools enabled built successfully; 2,367 tests passed, four failed (all already failing or unstable on main), and 41 skipped, from 2,412 selected. The report records 905 GPU tests with no new validation IDs; four existing IDs remain.agc_heap_mirror_reference_sizeandagc_reference_storagewere validated without a matching main validation pass, and the job-manager capacity test needed a retry. This is attributed external evidence, not a new local run. Hardware: NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329; Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, Ubuntu 24.04 container.