Skip to content

perf(agc): copy moved draw words into the draw upload ring - #11142

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
imellag:perf/agc-moved-words-upload
Oct 27, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
imellag:perf/agc-moved-words-upload

Conversation

@imellag

@imellag imellag commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

What

ShaderResources::PrepareDrawBindings copies a draw's moved words into a slice of the recorder's draw upload ring (Recorder::DrawUpload) instead of a Buffer of their own.

  • Before, each moved-word allocation that missed the 8-entry movedWordBuffers cache made a new Buffer (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT). The buffer pool usually hands back a slot whose VkBuffer has another size, so the constructor destroys it and binds a new one (BindExactBuffer), and the buffer is destroyed again when the draw retires.
  • The slice is filled the same way (words, then the data patches) and the descriptor gets the slice's offset. The guest-memory snapshots of up to 4096 bytes already go through this ring.
  • The movedWordBuffers cache goes away: a ring slice is only written once, but caching it per ShaderResources would keep its 1 MiB chunk alive for as long as the entry lives.
  • agc_driver_graphics checked that a moved-word descriptor starts at offset 0; it now checks the snapshot's offset and reads the words from there.

Why: with #11130's mimalloc on, the draw committer paces Planet of Lana on macOS. In a 15 s Time Profiler capture it spends 626 samples in Buffer::Buffer and 471 in vkDestroyBuffer called from it, out of 10,921, all from this call site.

Tested

macOS 27, M4 Pro, Rosetta 2, MoltenVK 1.4.2. main does not boot a title on macOS yet, so both sides are main 61fc572 plus the macOS changes needed to build and boot one: open macOS PRs (among them #10366, #10552, #7631, #7804, #10889, #10898, #11047, #11048 and #11049) and, for the AGC driver files and a few tests that no open PR covers yet, local patches taken from #8658's branch. #11130 is on both sides, with APS5_MIMALLOC=1; the change side adds this PR. The base commit below is that whole tree, so its exact diff against main is public.

Planet of Lana (PPSA19450), village gameplay from New Game with the same scripted pad input, 120 s per run, fps from 85 s, runs alternated in one session. These fps runs were on the same PRs uncommitted, plus a local experiment active on both sides (a DrawTail pool, neutral when measured), which the clean commits below leave out:

fps mean
base 33.04, 33.82, 33.73, 33.04, 33.56, 33.69, 33.46, 33.63 33.50
this PR 34.01, 34.07, 34.05 34.04 (+1.6%)

Every run with this PR is above every base run. Driver.Packet goes from 21 to 22 ms per frame to 19 ms.

tools/trace_digest.py of APS5_TRACE_SECONDS=95:10 APS5_TRACE_EVENTS=1048576 captures, same machine and scene, from two clean commits:

base:     seconds 95:10 from present 4314: 335 presents, frame p50 29.7 / p90 31.5 / p99 35.0 / max 49.6 ms, GPU busy 20.2 ms per present
this PR:  seconds 95:10 from present 4348: 343 presents, frame p50 28.9 / p90 31.0 / p99 37.2 / max 46.9 ms, GPU busy 19.4 ms per present
Trace Summary Digest
base lana-moved-words-clean-base.json.gz lana-moved-words-clean-base-summary.json lana-moved-words-clean-base-digest.md
this PR lana-moved-words-clean-change.json.gz lana-moved-words-clean-change-summary.json lana-moved-words-clean-change-digest.md
aps5-summary.jsonl lines

base:

{"commit":"7f2e300c68dc","dirty":false,"env":{"APS5_ASYNC_PIPELINES":"1","APS5_MIMALLOC":"1","APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_SECONDS":"95:10","APS5_VIDEOOUT_TELEMETRY_DIR":"<path>"},"gpu":"Apple M4 Pro","driver":"MoltenVK 1.4.2","os":"Darwin 27.0.0","cpu":"VirtualApple @ 2.50GHz","cpu_threads":12,"memory_mib":24576,"title_id":"PPSA19450","title":"Planet of Lana","content_version":"01.010.000","resolution":"3840x2160","window":{"spec":"seconds 95:10","first_present":4314,"ms":10006.822},"presents":335,"frame_ms":{"p50":29.699,"p90":31.546,"p99":35.005,"max":49.648},"gpu_busy_ms_per_present":20.229,"worker_busy_pct":{"queue worker 0x0":74.217},"top_phases_ms_per_frame":{"Driver.Packet":21.741,"Driver.Packet.draw":16.331,"Driver.Draw":16.173,"Graphics.Draw":16.158,"Graphics.Draw.draw_and_resource_release":12.321,"Driver.Draw.shader_compile_and_link":9.298,"VideoOut.Flip":7.205,"Driver.Present":6.389},"trace_dropped":false,"trace":"aps5-trace-7f2e300c68dc-24308.json.gz"}

this PR:

{"commit":"84cf9d0f359e","dirty":false,"env":{"APS5_ASYNC_PIPELINES":"1","APS5_MIMALLOC":"1","APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_SECONDS":"95:10","APS5_VIDEOOUT_TELEMETRY_DIR":"<path>"},"gpu":"Apple M4 Pro","driver":"MoltenVK 1.4.2","os":"Darwin 27.0.0","cpu":"VirtualApple @ 2.50GHz","cpu_threads":12,"memory_mib":24576,"title_id":"PPSA19450","title":"Planet of Lana","content_version":"01.010.000","resolution":"3840x2160","window":{"spec":"seconds 95:10","first_present":4348,"ms":10010.079},"presents":343,"frame_ms":{"p50":28.891,"p90":31.006,"p99":37.188,"max":46.898},"gpu_busy_ms_per_present":19.400,"worker_busy_pct":{"queue worker 0x0":66.822},"top_phases_ms_per_frame":{"Driver.Packet":19.199,"Driver.Packet.draw":14.585,"Driver.Draw":14.437,"Graphics.Draw":13.030,"Graphics.Draw.draw_and_resource_release":9.421,"VideoOut.Flip":9.220,"Driver.Draw.shader_compile_and_link":8.939,"Driver.Present":8.414},"trace_dropped":false,"trace":"aps5-trace-84cf9d0f359e-27576.json.gz"}

Driver.Packet goes from 21.7 to 19.2 ms per frame and Graphics.Draw from 16.2 to 13.0; the draw committer's busy time goes from 9.4 to 5.3 ms, and VideoOut.Flip grows from 7.2 to 9.2 ms, since the frame now waits on the GPU. A second capture of this PR's commit gave 342 presents and p50 29.0 ms; the base capture before it was not written because Rosetta was still translating the new libraries when the window opened.

AGC tests, same machine and GPU, base and this PR, with ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1 and VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (Vulkan SDK 1.4.363), ctest -R 'agc_draw_snapshot|agc_driver_graphics$|agc_recorder|agc_pending_write_snapshot|agc_shader_table_snapshot|agc_driver_partially_resident_snapshot|agc_snapshot|agc_driver_prepared_graphics' -V:

  • 19 tests, 16 pass and 3 skip on both sides (agc_driver_prepared_graphics_prebuild_*).
  • Neither log has was not found but was requested by env var VK_INSTANCE_LAYERS.
  • Both logs have the same validation output: 18 VUID-VkDeviceCreateInfo-pProperties-04451 (MoltenVK's portability subset at device creation) and no other VUID-.
  • Without the test change, agc_driver_graphics fails at the offset check described above.

Full ctest -R '^agc_' -j6 with ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1 and the validation layer, on the base and on this PR with 44c6919b64: the same 44 of 992 fail on both sides and the same 80 skip; no test fails only with this PR. An earlier run without ANYPS5_REQUIRE_VULKAN=1 had skipped agc_draw_descriptors, which SeaSunPT found failing on Windows; 44c6919b64 fixes its expectation.

Not built on Linux or Windows.

pr_overlap.py reports #8963 and #9508, which edit lines next to the removed movedWordBuffers members in ShaderResources.hpp. #8913 changes how the buffer pool picks a slot and helps the old path (33.91 fps on the same bench); after this PR that call site no longer makes buffers, and #8913 still applies to the other callers.

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: Apple M4 Pro, MoltenVK 1.4.2, macOS 27 (x86_64 build under Rosetta 2)
  • 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 25, 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.

@imellag

imellag commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor Author

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

The ring-slice change and descriptor offset handling look consistent in the PR-specific diff. I am requesting changes only for the required performance-report provenance.

Both pasted aps5-summary.jsonl records identify commit 61fc572ceef8 and set dirty:true; only their trace filenames/window values differ. CONTRIBUTING.md requires two valid summary lines from different commits, one on main and one with the change. As written, these records do not identify a clean base commit and a clean commit containing this PR, so the automated perf numbers missing label is correct even though the traces compare two configurations.

Please provide clean, different base/change commit summaries and the associated traces/digests, or ask maintainers to decide whether this dependency-stack/toggle comparison is an accepted exception and update the classification accordingly. I did not rerun the reported hardware Vulkan suite because this host has no matching macOS/MoltenVK GPU setup; the PR reports the required same-machine base/change validation runs.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

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.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 11451 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp L5646-5660
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp L6255-6256
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp L4346-4347

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/tests/Recorder.cpp
PR 1395 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 4040 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5021 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 5925 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6187 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6188 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6192 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6194 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6209 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6223 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6235 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6280 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6412 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6481 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6548 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6804 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6808 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6959 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6970 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6971 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7048 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7256 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7410 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7457 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7604 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 8395 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8484 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 8963 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9012 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9020 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9335 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9356 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9387 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9489 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9508 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 9592 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9674 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9675 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9748 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9852 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9897 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 10000 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10049 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 10064 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10193 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 10333 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 10348 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 10435 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 10442 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 10489 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10556 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 11485 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 11557 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp

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

imellag commented Oct 25, 2026

Copy link
Copy Markdown
Contributor Author

@MarcZX10 Thanks, that's fair. The description now has two captures from clean, different commits. The files are in the comment above and the summary lines are pasted in the description:

base:     seconds 95:10: 335 presents, frame p50 29.7 / p99 35.0 ms, Driver.Packet 21.7, Graphics.Draw 16.2 ms per frame
this PR:  seconds 95:10: 343 presents, frame p50 28.9 / p99 37.2 ms, Driver.Packet 19.2, Graphics.Draw 13.0 ms per frame

The base cannot be a commit on main. main does not boot a title on macOS, and macOS is the only machine where I can show this path (the draw committer is the busy thread there). So whether a comparison on top of the macOS stack counts as the main line is a call for the maintainers. The earlier fps runs in the description were on the same PRs, uncommitted, plus a local experiment that was active on both sides (a DrawTail pool, neutral when measured); the clean commits leave it out.

@MarcZX10

Copy link
Copy Markdown
Contributor

Correction to my earlier review rationale: the author has now supplied clean, distinct base/change commits, the two trace attachments, summary lines and digests, so my earlier statement that both records pointed to the same dirty commit is no longer current. The remaining question is narrower: the base capture is a combined dependency stack rather than a commit on current main. The author has explained why main cannot boot this title on the only machine that exercises this path and has asked maintainers whether to accept that exception. I am leaving the performance-evidence request unresolved for that maintainer decision; I do not want the earlier, superseded same-commit finding treated as current.

@klosixgaming-arch klosixgaming-arch 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.

Reviewed head 159007bd43 by reading the diff and the existing review thread. I did not build or run this, so everything below is from the code, not from a test of mine.

What it does. Moved-word snapshots no longer go through the per-ShaderResources 8-slot movedWordBuffers cache. They are copied into the recorder's draw upload ring with recorder.DrawUpload(size), and the descriptor uses the slice's own buffer and offset. The tests are adjusted for a non-zero offset (item.offset, .subspan(offset)), which is the right place to touch them.

What I checked. DrawUpload aligns to max(minStorageBufferOffsetAlignment, 16), so a storage-buffer descriptor at that offset is legal, and the std::shared_ptr<Buffer> in the slice keeps the ring buffer alive for the draw. Removing the mutable cache from ShaderResources also removes shared mutable state from a const method, which is a good thing independent of speed.

Concerns:

  1. No size bound on this path. The other DrawUpload call site is guarded by DrawUploadLimit() (4096 bytes by default). The moved-word path has no such limit, and DrawUpload allocates a fresh max(1 MiB, bytes) buffer whenever the ring is full or the request does not fit. The old code bounded this to 8 retained buffers. If override->size can be large, one draw per frame can now allocate a dedicated buffer where it used to reuse one. Please state the maximum override->size or add the same limit and fallback.
  2. Dedup is gone. The old cache returned the same buffer when allocation, size and words were equal, so a repeated draw with identical moved data created no new buffer. Now every such draw copies the words again. The perf numbers in the thread are what justifies that trade, and I can't verify them. They come from the author's captures and MarcZX10 has asked for clean base and change commits, which the author supplied. I take them as given.
  3. patch.adjustment is still written as a single byte (static_cast<std::byte>). That is carried over unchanged, so I'm not blaming this PR.

Leaving a comment: point 1 is a question I'd like answered; the rest is fine.

AI-assisted: yes. Written with AI assistance and reviewed by me.

@github-actions github-actions Bot added the agc libSceAgc* label Oct 25, 2026
@imellag

imellag commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

@klosixgaming Thanks for the review.

  1. The size is bounded before this path. Moved words come only from MovedReadOnlyBuffers, for ShaderData and FlattenedSrt bindings of a draw that hit the shared resource cache, and that function requires item.size to equal the words' size. A template enters the cache only when Reusable(), and noteReusable refuses one whose non-guest data buffer is over MaxRefreshBytes, 64 KiB (ShaderResources.cpp:2600). So override->size is at most 64 KiB, well under the 1 MiB DrawUploadChunk: a request never gets a buffer of its own; at most it starts the next chunk early, as any upload does when the ring is full. The old path created an exact-size Buffer on every miss. With the debug switch APS5_NO_TEMPLATE_DATA_REFRESH the 64 KiB check is off, and a request over 1 MiB then gets its own buffer, as every miss did before.
  2. Right, a repeated draw now copies its words again: at most 64 KiB of memcpy into mapped memory, in place of the compare plus a VkBuffer create and destroy on each miss, which was the hot spot (about 10% of the committer). The fps and trace numbers in the description are the evidence for that trade.
  3. Agreed, unchanged here.

@SeaSunPT

Copy link
Copy Markdown
Contributor

A Windows/NVIDIA run, since this was tested on macOS only. One test fails with this PR: agc_draw_descriptors.

Windows 11 Pro 26200, Intel Core i5-14600K, NVIDIA GeForce RTX 5070 Ti (driver 610.88), WinLibs GCC 15.2.0 r7, Release. Head 159007bd4 merged onto main cbaacd2910 (clean), compared with that main.

  • Your set (-R 'agc_draw_snapshot|agc_driver_graphics$|agc_recorder|agc_pending_write_snapshot|agc_shader_table_snapshot|agc_driver_partially_resident_snapshot|agc_snapshot|agc_driver_prepared_graphics' -V) with ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, 3 runs each: 19 of 19 pass on both sides, none skipped (the three agc_driver_prepared_graphics_prebuild_* run here). 0 VUID- lines and no missing-layer line.
  • agc_draw_descriptors (agc_driver_recorder_tests --draw-descriptors-only): fails 20 of 20 runs with this PR and passes 20 of 20 on main, with AGC graphics: snapshot update replaced the wrong buffer or changed its range. In two ctest -j 8 -R '^agc_' runs it is the only failure that main does not also have.

The check is tests/Recorder.cpp:4239 in drawDescriptorWriteTests, which still expects the replaced moved-word descriptor to keep the original descriptor's offset. With the ring slice it now has slice.offset, the same thing you changed in tests/Graphics.cpp. Expecting the snapshot's offset for the replaced binding makes it pass 20 of 20, with the validation layer and 0 VUID- lines:

const bool replaced = key.first == (allocation == 0 ? 2u : 7u);
const auto expected = replaced ? draw->snapshots.front().buffer->Handle() : before.buffer;
const auto expectedOffset = replaced ? draw->snapshots.front().offset : before.offset;
Require(after.buffer == expected && after.offset == expectedOffset && after.range == before.range, "snapshot update replaced the wrong buffer or changed its range");

agc_draw_descriptors isn't in the list of 11 failures from your macOS run, so I can't tell why it passed there.

Full ctest -j 8 with ANYPS5_REQUIRE_VULKAN=1: 2449 of 2452 pass. Besides agc_draw_descriptors, the two failures, agc_host_import_cut_lifetime (#10746) and agc_driver_depth_plane_partial_store (#10664), fail on main on this machine too.

…escriptor

Co-authored-by: SeaSunPT <24361469+SeaSunPT@users.noreply.github.com>
@imellag

imellag commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

@SeaSunPT Thanks, you're right. I reproduced it on macOS with MoltenVK: agc_draw_descriptors fails the same way. My full-suite run had been without ANYPS5_REQUIRE_VULKAN=1, so the test was skipped and ctest counted it as passed. I took your expectation as is in 44c6919b64, with you as co-author. With it, agc_draw_descriptors and agc_driver_graphics pass 3 of 3 here with the validation layer (only MoltenVK's usual VUID-VkDeviceCreateInfo-pProperties-04451). I reran the full ^agc_ suite with Vulkan required on the base and on this PR: the same 44 of 992 fail on both sides and the same 80 skip, and no test fails only with this PR. Tested is updated.

@imellag

imellag commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

Correction to the description and to my comment above: the base is not only the six PRs I listed. To build and boot on macOS it also carries other open macOS PRs and, for the AGC driver files and a few tests that no open PR covers yet, local patches from #8658's branch. The description now says so; the base commit 7f2e300c68dc is the whole tree, so the exact diff against main is public.

@adriadam10 adriadam10 self-assigned this Oct 27, 2026
@adriadam10
adriadam10 dismissed MarcZX10’s stale review October 27, 2026 03:21

Dismissing a stale review: the requested changes were addressed after it (new head) and the merge queue blocks on it. Please request changes again if anything is still open.

@adriadam10
adriadam10 merged commit 49f600f into boykopovar:main Oct 27, 2026
13 of 14 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the diff against Recorder::DrawUpload (slice aligned to minStorageBufferOffsetAlignment, descriptor uses slice.offset, data patches applied as before), the size bound (moved words come only from reusable templates, ≤ 64 KiB, below the 1 MiB chunk), and that the updated tests read at the slice offset instead of 0. The performance capture is on a macOS stack rather than plain main; accepted given main does not boot a title there. Related to #11451, which touches the same lines; whichever merges second needs a rebase. Full Build run by the merge queue; merged.

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

Labels

agc libSceAgc* perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants