Skip to content

perf(libc, libkernel): keep aliased direct memory on the Linux write watch and collect stores through every alias - #12452

Open
Tehshortbus wants to merge 6 commits into
boykopovar:mainfrom
Tehshortbus:perf/watch-aliased-direct-memory
Open

Tehshortbus wants to merge 6 commits into
boykopovar:mainfrom
Tehshortbus:perf/watch-aliased-direct-memory

Conversation

@Tehshortbus

@Tehshortbus Tehshortbus commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

What

On Linux, when a title maps one direct memory block at a second guest address, WatchMapping in libkernel/DirectMemory/DirectMemory.cpp unregisters both views from the write watch. From then on the driver's tracker refuses every collect over them (GuestWriteWatchCovers is false). Textures over that memory fall back to whole-surface comparisons, and the resource caches over it to full revalidation walks.

GTA V maps direct memory this way. In the first two Story cutscenes it compares 8,000–22,000 textures per 10 s (3–9.5 GiB), and the committer pays for it per draw.

The two views share physical pages, but the userfaultfd write-protect bit and PAGEMAP_SCAN are per virtual page: a store through one view marks only that view's page written. So both views can stay registered, as long as a collect over one also scans the other and reports its stores at both addresses. This PR does that:

  • GuestWriteWatchAlias_nid_postfix(first, second, bytes) (libc): new export. It records a link in each direction between two page-aligned, watched ranges of the same size, and returns false (changing nothing) when the watch is unavailable or either range is not fully watched. It returns false on macOS and Windows.
  • Collect, CollectFresh and CollectArmed (GuestWriteWatch.cpp): over a range with links, each also walks the linked ranges. Every written page found through any view is reported at its own address and at the address of each view linked to it.
    • Ranges with no links take the same path as before, apart from one lookup in an empty map.
    • With three or more views, WatchMapping links every pair, so one level of indirection covers all of them.
  • Register and Unregister cut the links of the range they change: the linked parts outside it are kept, on both sides.
  • WatchMapping (libkernel): links an overlapping pair with GuestWriteWatchAlias_nid_postfix, and unregisters both views as before only when that returns false.
  • WindowCopy::Holds (libSceAgcDriver/Execution/src/GuestMemory.cpp): returns false for a page outside the window. A collect over an import window can now report a store at a linked page outside it. Without the check, stampWindowRuns read past hashes and GTA V crashed (SIGSEGV) in the first cutscene.
  • Debt entry for frame capture (docs/dev/debt/libSceAgcDriver.md): Linux now records a store through one alias at every alias, instead of recording none.

Tested

CachyOS Linux (kernel 7.3.0-4-cachyos), GCC 16.2.1, Release, Ryzen 7 5800X, NVIDIA GeForce RTX 4070 SUPER (615.78.08).

Tests (head 4621b11d00, main ba5b5330b3 merged into a160f789ec; range-diff of a160f789ec against the measured head d10b767163 shows both commits unchanged, and the merge preview onto main is clean):

  • guest_memory:
    • CheckDirectMemoryWriteWatchSeesWritesThroughAliases maps one physical page at three addresses: the upper page of a two-page mapping, and two one-page mappings. It checks that:
      • CollectFresh, CollectArmed and Collect each report a store through one view at every view;
      • a collect through one view leaves nothing to report through the others;
      • after the second view is unmapped, a store through the third is reported at the first and third only.
    • CheckDirectMemoryWriteWatchDropsAliasOnRemap links two views of one page, then maps other physical memory over the second with sceKernelMapDirectMemory (fixed). It checks that the second view stays watched, that a collect over the first no longer reports the second's pages, and that a store through either view is reported only at that view.
    • CheckDirectMemoryWriteWatch and CheckDirectMemoryWriteWatchFollowsRemovedMappings now expect aliased views to stay covered.
  • agc_write_tracking: CheckImportWindowOverAlias (Linux) links two views of one memfd block and imports the upper view with a window. A store through the window is reported at both views, including the lower one, outside the window.
  • Negative controls (rerun on head 4621b11d00):
    • With main's GuestWriteWatch.cpp and DirectMemory.cpp, guest_memory fails on the first coverage check of an aliased view (core/libs/tests/GuestMemory.cpp:3036).
    • Without the link cut in Register, guest_memory fails in CheckDirectMemoryWriteWatchDropsAliasOnRemap: the first view still reports the remapped view's pages.
    • Without the bound in WindowCopy::Holds, agc_write_tracking crashes (SIGSEGV) in CheckImportWindowOverAlias.
  • What the tests reach: Alias, the alias walks of all three collects, the link cut on both Register and Unregister, and the WindowCopy::Holds bound.
  • 991 of the 992 guest_* tests pass (ctest -R '^guest_'). guest_freebsd_clocks aborts, the same way on plain main (Tests: guest_freebsd_clocks aborts where the host zone is not UTC #12736, fixed by the open fix(tests): drop the guest_freebsd_clocks check that the host zone is UTC #12660 and test(libkernel): pin the zone before the kernel timezone check #12747); this PR does not touch clocks.
  • 16 write-watch, import and alias tests of the driver pass with ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, with no VUID- line or missing-layer message. They include agc_write_watch_coverage, agc_import_watch, agc_shared_write, agc_write_tracking, agc_driver_alias_copy_label and the heap mirror unwatch tests.
  • python3 tools/check_conventions.py --base origin/main and git diff --check pass.

GTA V (PPSA04264 01.011.001, 3840x2160, warm shader cache):

Cutscene 1, per 10 s:

base, round 1 PR, round 1 PR, round 2 base, round 2
fps 13.47 13.94 13.97 13.68
committer µs per commit 30.5 29.1 28.9 30.1
texture comparisons ([guestmem] compare) 8,683 (3,265 MiB) 6 6 8,542 (3,207 MiB)
full revalidation walks 10,755 4,778 4,842 10,780
collect fast-fails 6,365 0 0 6,292
revalidation time (ms) 715 490 498 717

Cutscene 2, per 10 s:

base, round 1 PR, round 1 PR, round 2 base, round 2
fps 5.65 6.38 6.43 5.92
committer µs per commit 36.2 31.8 31.3 35.5
texture comparisons 21,348 (9,410 MiB) 34 44 21,468 (9,507 MiB)
full revalidation walks 18,745 9,357 9,173 18,763
collect fast-fails 10,832 0 0 10,598
revalidation time (ms) 1,347 806 812 1,292
  • Reading:
    • Texture comparisons over aliased memory almost disappear.
    • The collects that the tracker refused go to 0, and full walks halve.
    • The committer's cost per draw drops 3–5 % in cutscene 1 and 10–14 % in cutscene 2.
    • The frame gains 2–4 % in cutscene 1 and 8–14 % in cutscene 2. Both PR runs are above both base runs in each cutscene; the base's own spread is 13.47–13.68 fps and 5.65–5.92 fps. PR, run 3 gives 14.11 and 6.38 fps.
    • The remaining full walks are not from aliased memory and are not addressed here.
  • Attachments: one zip per run (gta-alias10-*.zip) in this comment, with the summary lines, the trace, the [guestmem]/[rescache]/[draw] lines and a README with the build, switches, cutscene marks and where the trace window falls. The traces are recompressed with xz to fit GitHub's attachment limit; xz -d gives the .json that tools/trace_digest.py reads.

Summary lines and trace digests (the APS5_TRACE_SECONDS=100:60 window of each trace):

  • The pair below is the base, round 1 and PR, run 3, whose windows cover nearly the same part of cutscene 1: 37–97 s and 41–101 s after it starts.
  • Over those 60 s the base presents 829 frames (p50 71.4 ms) and the PR 832 (p50 70.6 ms). The draw committer is busy 42.1 ms per frame in the base and 40.9 ms in the PR. Cutscene 1 gains least from this change; cutscene 2, outside the trace window, gains most.
  • The other windows:
    • Base, round 2: 31–91 s, 845 presents, p50 70.7 ms.
    • PR, rounds 1 and 2: they start 29 s and 13 s before cutscene 1, so they are not compared.

Base, round 1 (b8f4e6343a: main 2960e9a6e7 + #11580):

{"commit":"b8f4e6343a96","dirty":false,"env":{"APS5_PIPELINE_STATS":"1","APS5_PROFILE_DRAW":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"4194304","APS5_TRACE_SECONDS":"100:60","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"NVIDIA GeForce RTX 4070 SUPER","driver":"NVIDIA 615.78.08","os":"Linux 7.3.0-4-cachyos","cpu":"AMD Ryzen 7 5800X 8-Core Processor","cpu_threads":16,"memory_mib":64203,"title_id":"PPSA04264","title":"Grand Theft Auto V","content_version":"01.011.001","resolution":"3840x2160","window":{"spec":"seconds 100:60","first_present":2761,"ms":60100.850},"presents":829,"frame_ms":{"p50":71.412,"p90":77.050,"p99":114.076,"max":203.223},"gpu_busy_ms_per_present":36.892,"worker_busy_pct":{"queue worker 0x0":97.246},"top_phases_ms_per_frame":{"Driver.Packet":67.123,"Graphics.Draw":38.415,"Driver.Packet.draw":35.829,"Driver.Draw":35.268,"Graphics.Draw.draw_and_resource_release":32.713,"Driver.Draw.shader_compile_and_link":24.068,"Driver.Packet.dispatch":23.982,"Shader.DrawStage":18.429},"trace_dropped":false,"trace":"aps5-trace-b8f4e6343a96-2334160.json.gz"}
tools/trace_digest.py of the base, round 1

seconds 100:60 from present 2761: 829 presents, frame p50 71.4 / p90 77.0 / p99 114.1 / max 203.2 ms, GPU busy 36.9 ms per present
NVIDIA GeForce RTX 4070 SUPER, NVIDIA 615.78.08, Linux 7.3.0-4-cachyos, 3840x2160, commit b8f4e6343a96, dropped: no

{"commit":"b8f4e6343a96","dirty":false,"env":{"APS5_PIPELINE_STATS":"1","APS5_PROFILE_DRAW":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"4194304","APS5_TRACE_SECONDS":"100:60","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"NVIDIA GeForce RTX 4070 SUPER","driver":"NVIDIA 615.78.08","os":"Linux 7.3.0-4-cachyos","cpu":"AMD Ryzen 7 5800X 8-Core Processor","cpu_threads":16,"memory_mib":64203,"title_id":"PPSA04264","title":"Grand Theft Auto V","content_version":"01.011.001","resolution":"3840x2160","window":{"spec":"seconds 100:60","first_present":2761,"ms":60100.85},"presents":829,"frame_ms":{"p50":71.412,"p90":77.05,"p99":114.076,"max":203.223},"gpu_busy_ms_per_present":36.892,"worker_busy_pct":{"queue worker 0x0":97.246},"top_phases_ms_per_frame":{"Driver.Packet":67.123,"Graphics.Draw":38.415,"Driver.Packet.draw":35.829,"Driver.Draw":35.268,"Graphics.Draw.draw_and_resource_release":32.713,"Driver.Draw.shader_compile_and_link":24.068,"Driver.Packet.dispatch":23.982,"Shader.DrawStage":18.429},"trace_dropped":false,"trace":"aps5-trace-b8f4e6343a96-2334160.json.gz"}

Slowest frames (largest slices inside each, inclusive)

  • present 3586: 203.2 ms at 59574 ms: Driver.Packet (queue worker 0x0) 175.7, Driver.Packet.draw (queue worker 0x0) 121.8, Driver.Draw (queue worker 0x0) 121.0, Graphics.Draw (draw committer) 116.6
  • present 3566: 166.8 ms at 57931 ms: Driver.Packet (queue worker 0x0) 143.3, Driver.Packet.draw (queue worker 0x0) 101.8, Driver.Draw (queue worker 0x0) 101.2, Graphics.Draw (draw committer) 85.7
  • present 3526: 137.2 ms at 54888 ms: Driver.Packet (queue worker 0x0) 105.7, Graphics.Draw (draw committer) 76.8, Driver.Packet.draw (queue worker 0x0) 65.5, Driver.Draw (queue worker 0x0) 65.0
  • present 3187: 120.2 ms at 30360 ms: Driver.Packet (queue worker 0x0) 100.7, Driver.Packet.draw (queue worker 0x0) 74.6, Driver.Draw (queue worker 0x0) 74.2, Driver.Draw.shader_compile_and_link (queue worker 0x0) 65.9
  • present 3027: 120.1 ms at 18791 ms: Driver.Packet (queue worker 0x0) 102.9, Driver.Packet.draw (queue worker 0x0) 75.8, Driver.Draw (queue worker 0x0) 75.3, Driver.Draw.shader_compile_and_link (queue worker 0x0) 66.7

Threads (ms per frame)

thread busy wait untraced in slices < 20 us largest
title 0.0 (0 %) 0.0 (0 %) 72.5 0.0 Shader.ResolveGraphicsStagesAbi 0.0
queue worker 0x0 54.8 (76 %) 1.0 (1 %) 16.7 82.4 Driver.Packet 52.8, Driver.Rewind 2.2
draw committer 42.1 (58 %) 0.1 (0 %) 30.3 25.4 Graphics.Draw 28.6, Recorder.Sync 13.1
presenter 0.4 (1 %) 13.7 (19 %) 58.3 0.1 VideoOut.Flip 14.2
gpu 36.9 (51 %) 0.0 (0 %) 35.6 0.0 batch 36.9

Largest slices (ms per frame, inclusive, all threads): Driver.Packet 52.8, batch 36.9, Graphics.Draw 28.6, Driver.Packet.draw 26.0, Driver.Draw 25.5, Driver.Packet.dispatch 23.8, Graphics.Draw.draw_and_resource_release 23.6, Recorder.Sync 15.4, Driver.Draw.shader_compile_and_link 15.4, VideoOut.Flip 14.2

Longest waits

  • Driver.Present.render_fence_wait (presenter) 16.8 ms at 5311 ms, present 2836
  • Driver.Present.render_fence_wait (presenter) 16.4 ms at 5236 ms, present 2835
  • Driver.Present.render_fence_wait (presenter) 16.4 ms at 1626 ms, present 2784
  • Driver.Present.render_fence_wait (presenter) 16.3 ms at 1554 ms, present 2783
  • Driver.Present.render_fence_wait (presenter) 16.2 ms at 5161 ms, present 2834
  • Driver.Present.render_fence_wait (presenter) 16.2 ms at 1775 ms, present 2786
  • Driver.Present.render_fence_wait (presenter) 15.9 ms at 1704 ms, present 2785
  • Driver.Present.render_fence_wait (presenter) 15.7 ms at 45829 ms, present 3398
  • Driver.Present.render_fence_wait (presenter) 15.7 ms at 1261 ms, present 2779
  • Driver.Present.render_fence_wait (presenter) 15.6 ms at 41414 ms, present 3338

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

  • batch 71567: 17.0 ms at 5311 ms, present 2835: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.4, Graphics.Draw.draw_and_resource_release (draw committer) 0.4, Recorder.Submit (draw committer) 0.0
  • batch 65786: 16.8 ms at 1626 ms, present 2783: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.4, Graphics.Draw.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.0
  • batch 66009: 16.7 ms at 1774 ms, present 2785: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.4, Graphics.Draw.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.0
  • batch 71345: 16.6 ms at 5160 ms, present 2833: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.4, Graphics.Draw.draw_and_resource_release (draw committer) 0.4, Recorder.Submit (draw committer) 0.0
  • batch 65675: 16.4 ms at 1554 ms, present 2782: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.3, Graphics.Draw.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.0

PR, run 3 (98efd2e7b2: the same + this PR at d10b767163):

{"commit":"98efd2e7b261","dirty":false,"env":{"APS5_PIPELINE_STATS":"1","APS5_PROFILE_DRAW":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"4194304","APS5_TRACE_SECONDS":"100:60","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"NVIDIA GeForce RTX 4070 SUPER","driver":"NVIDIA 615.78.08","os":"Linux 7.3.0-4-cachyos","cpu":"AMD Ryzen 7 5800X 8-Core Processor","cpu_threads":16,"memory_mib":64203,"title_id":"PPSA04264","title":"Grand Theft Auto V","content_version":"01.011.001","resolution":"3840x2160","window":{"spec":"seconds 100:60","first_present":2706,"ms":60006.587},"presents":832,"frame_ms":{"p50":70.569,"p90":77.423,"p99":114.056,"max":197.225},"gpu_busy_ms_per_present":36.331,"worker_busy_pct":{"queue worker 0x0":97.171},"top_phases_ms_per_frame":{"Driver.Packet":66.659,"Graphics.Draw":37.803,"Driver.Packet.draw":35.694,"Driver.Draw":35.107,"Graphics.Draw.draw_and_resource_release":31.991,"Driver.Draw.shader_compile_and_link":24.045,"Driver.Packet.dispatch":23.608,"Shader.DrawStage":18.446},"trace_dropped":false,"trace":"aps5-trace-98efd2e7b261-2341520.json.gz"}
tools/trace_digest.py of PR, run 3

seconds 100:60 from present 2706: 832 presents, frame p50 70.6 / p90 77.4 / p99 114.1 / max 197.2 ms, GPU busy 36.3 ms per present
NVIDIA GeForce RTX 4070 SUPER, NVIDIA 615.78.08, Linux 7.3.0-4-cachyos, 3840x2160, commit 98efd2e7b261, dropped: no

{"commit":"98efd2e7b261","dirty":false,"env":{"APS5_PIPELINE_STATS":"1","APS5_PROFILE_DRAW":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"4194304","APS5_TRACE_SECONDS":"100:60","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"NVIDIA GeForce RTX 4070 SUPER","driver":"NVIDIA 615.78.08","os":"Linux 7.3.0-4-cachyos","cpu":"AMD Ryzen 7 5800X 8-Core Processor","cpu_threads":16,"memory_mib":64203,"title_id":"PPSA04264","title":"Grand Theft Auto V","content_version":"01.011.001","resolution":"3840x2160","window":{"spec":"seconds 100:60","first_present":2706,"ms":60006.587},"presents":832,"frame_ms":{"p50":70.569,"p90":77.423,"p99":114.056,"max":197.225},"gpu_busy_ms_per_present":36.331,"worker_busy_pct":{"queue worker 0x0":97.171},"top_phases_ms_per_frame":{"Driver.Packet":66.659,"Graphics.Draw":37.803,"Driver.Packet.draw":35.694,"Driver.Draw":35.107,"Graphics.Draw.draw_and_resource_release":31.991,"Driver.Draw.shader_compile_and_link":24.045,"Driver.Packet.dispatch":23.608,"Shader.DrawStage":18.446},"trace_dropped":false,"trace":"aps5-trace-98efd2e7b261-2341520.json.gz"}

Slowest frames (largest slices inside each, inclusive)

  • present 3486: 197.2 ms at 55667 ms: Driver.Packet (queue worker 0x0) 171.8, Driver.Packet.draw (queue worker 0x0) 111.4, Driver.Draw (queue worker 0x0) 110.7, Graphics.Draw (draw committer) 110.2
  • present 3465: 151.3 ms at 53999 ms: Driver.Packet (queue worker 0x0) 123.2, Graphics.Draw (draw committer) 79.5, Driver.Packet.draw (queue worker 0x0) 66.5, Driver.Draw (queue worker 0x0) 65.9
  • present 3532: 144.9 ms at 59415 ms: Driver.Packet (queue worker 0x0) 124.7, Driver.Packet.draw (queue worker 0x0) 92.4, Driver.Draw (queue worker 0x0) 91.9, Graphics.Draw (draw committer) 87.4
  • present 3425: 144.1 ms at 51059 ms: Driver.Packet (queue worker 0x0) 118.8, Graphics.Draw (draw committer) 76.2, Driver.Packet.draw (queue worker 0x0) 61.5, Driver.Draw (queue worker 0x0) 60.8
  • present 3063: 126.7 ms at 25209 ms: Driver.Packet (queue worker 0x0) 107.9, Driver.Packet.draw (queue worker 0x0) 80.6, Driver.Draw (queue worker 0x0) 80.2, Driver.Draw.shader_compile_and_link (queue worker 0x0) 71.0

Threads (ms per frame)

thread busy wait untraced in slices < 20 us largest
title 0.0 (0 %) 0.0 (0 %) 72.1 0.0 Shader.ResolveGraphicsStagesAbi 0.0
queue worker 0x0 54.3 (75 %) 0.9 (1 %) 16.9 83.4 Driver.Packet 52.1, Driver.Rewind 2.2
draw committer 40.9 (57 %) 0.1 (0 %) 31.1 25.5 Graphics.Draw 28.0, Recorder.Sync 12.6
presenter 0.4 (1 %) 13.4 (19 %) 58.3 0.1 VideoOut.Flip 13.8
gpu 36.3 (50 %) 0.0 (0 %) 35.9 0.0 batch 36.3

Largest slices (ms per frame, inclusive, all threads): Driver.Packet 52.1, batch 36.3, Graphics.Draw 28.0, Driver.Packet.draw 25.8, Driver.Draw 25.3, Driver.Packet.dispatch 23.5, Graphics.Draw.draw_and_resource_release 22.9, Driver.Draw.shader_compile_and_link 15.2, Recorder.Sync 14.8, VideoOut.Flip 13.8

Longest waits

  • Driver.Present.render_fence_wait (presenter) 16.7 ms at 42501 ms, present 3303
  • Driver.Present.render_fence_wait (presenter) 16.5 ms at 56706 ms, present 3497
  • Driver.Present.render_fence_wait (presenter) 16.3 ms at 33623 ms, present 3178
  • Driver.Present.render_fence_wait (presenter) 15.9 ms at 36176 ms, present 3213
  • Driver.Present.render_fence_wait (presenter) 15.8 ms at 33553 ms, present 3177
  • Driver.Present.render_fence_wait (presenter) 15.6 ms at 2628 ms, present 2743
  • Driver.Present.render_fence_wait (presenter) 15.5 ms at 959 ms, present 2720
  • Driver.Present.render_fence_wait (presenter) 15.4 ms at 5706 ms, present 2784
  • Driver.Present.render_fence_wait (presenter) 15.3 ms at 27942 ms, present 3099
  • Driver.Present.render_fence_wait (presenter) 15.2 ms at 33981 ms, present 3183

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

  • batch 137630: 17.2 ms at 42500 ms, present 3302: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.5, Graphics.Draw.draw_and_resource_release (draw committer) 0.4, Recorder.Submit (draw committer) 0.0
  • batch 159617: 17.0 ms at 56706 ms, present 3496: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.4, Graphics.Draw.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.0
  • batch 123573: 16.6 ms at 33623 ms, present 3177: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.4, Graphics.Draw.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.0
  • batch 127563: 16.4 ms at 36175 ms, present 3212: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.3, Graphics.Draw.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.0
  • batch 123465: 16.2 ms at 33552 ms, present 3176: GPU no ranges; recorded by Graphics.Draw (draw committer) 0.4, Graphics.Draw.draw_and_resource_release (draw committer) 0.3, Recorder.Submit (draw committer) 0.0

Overlap:

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: fix(shader): load and store 16-bit data of converted packed images #11580 (GTA V needs it to reach the measured scenes; this merges after it)
  • Fixes: none
  • Unblocks: none
  • GPUs tested: NVIDIA GeForce RTX 4070 SUPER, driver 615.78.08, CachyOS Linux (kernel 7.3.0-4-cachyos)
  • AI-assisted: yes (Claude Code)

🤖 Generated with Claude Code

@Tehshortbus

Copy link
Copy Markdown
Contributor Author

Data for the GTA V A/B in the description, one zip per run, in run order:

Zip Build Cutscene 1 / 2 start (s after launch)
gta-alias-base-r1.zip base: main 750cf6cf48 + #11580 (48919964c6) 104 / 205
gta-alias-alias-r1.zip base + this PR (690ca44415) 72 / 178
gta-alias-alias-r2.zip base + this PR (690ca44415) 69 / 175
gta-alias-base-r2.zip base: main 750cf6cf48 + #11580 (48919964c6) 73 / 195

Each zip holds:

  • aps5-summary.jsonl: the summary lines (APS5_TRACE_SUMMARY_EVERY=10).
  • summary-stamped.txt: the same lines with the Unix time each was printed, used to line them up with the cutscene marks.
  • aps5-trace-*.json.gz: the trace (APS5_TRACE_SECONDS=75:30).
  • profile-draw-lines.txt: the [guestmem], [rescache] and [draw] lines of APS5_PROFILE_DRAW=1, printed every 10 s. The comparison, revalidation and committer figures in the tables come from these.
  • README.txt: build, switches, cutscene marks and exit status.

All four runs used APS5_PROFILE_DRAW=1 APS5_PIPELINE_STATS=1 and exited 0.

AI-assisted: yes (Claude Code)

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

@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 new GTA V A/B archives are useful: I downloaded all four, verified their README and summary metadata, and ran tools/trace_digest.py on the attached aps5-summary.jsonl files. They provide same-machine/same-scene data for main + #11580 (48919964c63c) versus the earlier PR build (690ca444159f). However, the PR is currently at b6535bf6cb6231cd39fd336234b15fbe85652692, and the report explicitly says the change capture predates the rebase onto current main; I cannot confirm that those numbers represent the current head. Also, the repository requires a perf PR description to contain two valid summary lines with different commits, and the current body has neither line; GitHub still shows perf numbers missing. Please update the description with paired current-main/current-head aps5-summary.jsonl lines, attach their traces, and include the tools/trace_digest.py output. The performance claim remains unverified for the current head until then. The overlap scan reports only the independent debt-file hunk in #10760; the hosted build and platform checks are still running. I am requesting changes for the missing current-head performance report, not alleging a code defect.

@adriadam10 adriadam10 self-assigned this Oct 28, 2026

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The change reads correctly: links are kept in both directions, cut on Register/Unregister, and the three collects report every page at each linked view. The new CheckDirectMemoryWriteWatchSeesWritesThroughAliases pins the reported pages for two and three views, and the updated expectations in the existing tests fail on main. What is left:

  • The GTA V A/B was taken before the rebase (690ca44415, base 48919964c6), and the head is now b6535bf6cb. @MarcZX10 asked for the pair on the current head and that is still open. Please rerun the base/PR pair on b6535bf6cb (or on the head after any further push), update the two aps5-summary.jsonl lines and the trace_digest.py output in the description, and attach the traces. The labels check is still pending on that.
  • WindowCopy::Holds bounds check (core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp:930) has no test: only GTA V reached it. A test where a collect over an import window reports a store at a linked page outside the window would show the crash it prevents.
  • The link cut on Register over an already linked range (GuestWriteWatch.cpp:64) is not reached by any test either; remapping a view over an aliased one and checking that no store is reported at the old partner would cover it.

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

github-actions Bot commented Oct 28, 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 12567 docs/dev/debt/libSceAgcDriver.md L144
PR 12568 docs/dev/debt/libSceAgcDriver.md L144
PR 12792 core/libs/prx/libc/src/GuestWriteWatch.cpp L110-111, L126, L137-149, L154-155

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 5021 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libkernel/DirectMemory/DirectMemory.cpp
core/libs/tests/GuestMemory.cpp
PR 5925 docs/dev/debt/libSceAgcDriver.md
PR 6186 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6187 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6192 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6194 docs/dev/debt/libSceAgcDriver.md
PR 6209 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6280 docs/dev/debt/libSceAgcDriver.md
PR 6412 docs/dev/debt/libSceAgcDriver.md
PR 6481 docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6804 docs/dev/debt/libSceAgcDriver.md
PR 6808 docs/dev/debt/libSceAgcDriver.md
PR 7085 docs/dev/debt/libSceAgcDriver.md
PR 7105 core/libs/prx/libkernel/DirectMemory/DirectMemory.cpp
core/libs/tests/GuestMemory.cpp
PR 7149 core/libs/prx/libkernel/DirectMemory/DirectMemory.cpp
PR 7449 docs/dev/debt/libSceAgcDriver.md
PR 7604 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7642 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
docs/dev/debt/libSceAgcDriver.md
PR 8592 docs/dev/debt/libSceAgcDriver.md
PR 9356 docs/dev/debt/libSceAgcDriver.md
PR 9387 docs/dev/debt/libSceAgcDriver.md
PR 9508 docs/dev/debt/libSceAgcDriver.md
PR 9592 docs/dev/debt/libSceAgcDriver.md
PR 9748 docs/dev/debt/libSceAgcDriver.md
PR 9893 docs/dev/debt/libSceAgcDriver.md
PR 9915 docs/dev/debt/libSceAgcDriver.md
PR 9950 docs/dev/debt/libSceAgcDriver.md
PR 10193 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
docs/dev/debt/libSceAgcDriver.md
PR 10233 docs/dev/debt/libSceAgcDriver.md
PR 10359 docs/dev/debt/libSceAgcDriver.md
PR 11825 docs/dev/debt/libSceAgcDriver.md
PR 12904 docs/dev/debt/libSceAgcDriver.md
PR 13486 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
core/libs/prx/libc/src/GuestWriteWatch.cpp
core/libs/prx/libkernel/DirectMemory/DirectMemory.cpp
core/libs/tests/GuestMemory.cpp
docs/dev/debt/libSceAgcDriver.md
PR 13599 docs/dev/debt/libSceAgcDriver.md
PR 13707 docs/dev/debt/libSceAgcDriver.md
PR 13793 docs/dev/debt/libSceAgcDriver.md
PR 13809 docs/dev/debt/libSceAgcDriver.md
PR 13863 docs/dev/debt/libSceAgcDriver.md
PR 13920 docs/dev/debt/libSceAgcDriver.md
PR 13928 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
docs/dev/debt/libSceAgcDriver.md
PR 13929 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
docs/dev/debt/libSceAgcDriver.md
PR 14137 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
docs/dev/debt/libSceAgcDriver.md
PR 14212 docs/dev/debt/libSceAgcDriver.md
PR 14344 docs/dev/debt/libSceAgcDriver.md
PR 14944 docs/dev/debt/libSceAgcDriver.md
PR 15136 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
docs/dev/debt/libSceAgcDriver.md
PR 15169 docs/dev/debt/libSceAgcDriver.md
PR 15529 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
docs/dev/debt/libSceAgcDriver.md
PR 15548 docs/dev/debt/libSceAgcDriver.md
PR 16059 docs/dev/debt/libSceAgcDriver.md
PR 16198 core/libs/tests/GuestMemory.cpp

@Tehshortbus
Tehshortbus force-pushed the perf/watch-aliased-direct-memory branch from b6535bf to dc64a22 Compare October 28, 2026 14:31

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

Follow-up on the new head dc64a22147: the added CheckDirectMemoryWriteWatchDropsAliasOnRemap and CheckImportWindowOverAlias tests now exercise the two previously uncovered paths (cutting a link on Register and rejecting a linked page outside an import window). I confirmed those cases are present in the exact-head diff, and python3 tools/check_conventions.py --base upstream/main plus git diff --check upstream/main...HEAD pass locally. I have not run the C++ tests on this host. The remaining blocker from my earlier review is still the perf report: the attached A/B captures use the pre-rebase build 690ca44415, not this head, and GitHub still reports perf numbers missing. Please attach a same-machine/title/scene main vs current-head pair, the two summary lines, traces, and tools/trace_digest.py output; the performance claim cannot yet be checked for this commit.

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Both test gaps are covered: CheckDirectMemoryWriteWatchDropsAliasOnRemap pins that neither view reports the other's stores after a remap to other physical pages, and CheckImportWindowOverAlias pins the window collect reporting the linked page below the window. Each fails without the corresponding code (the link cut on Register, the Holds bound).

One point is left, the one @MarcZX10 still has open: the perf report. The GTA V pair and both aps5-summary.jsonl lines are from 690ca44415 on base 48919964c6; the head is now dc64a22147. The patch under test did not change in the rebase (range-diff shows =), so a pair on the current head is enough, no new analysis: rerun base/PR on the current head, update the two summary lines and the trace_digest.py output in the description, and attach the traces. Once that is in, this is ready to merge.

@Tehshortbus

Copy link
Copy Markdown
Contributor Author

@MarcZX10 @adriadam10 The GTA V A/B is now on the current head. The description has the new tables, the two aps5-summary.jsonl lines and the tools/trace_digest.py output of both.

One zip per run, in run order. The traces are recompressed with xz to fit the attachment limit; xz -d gives the .json that tools/trace_digest.py reads.

Zip Build Cutscene 1 / 2 marked (s after launch) Trace window (s after cutscene 1 starts)
gta-alias6-base-r1.zip base (97a3e149ca) 81 / 181 26–86
gta-alias6-alias-r1.zip PR (aff5afdf9d) 78 / 184 28–88
gta-alias6-alias-r2.zip PR (aff5afdf9d) 71 / 178 36–96
gta-alias6-base-r2b.zip base (97a3e149ca) 97 / 204 10–70

Each zip holds:

  • aps5-summary.jsonl: the summary lines (APS5_TRACE_SUMMARY_EVERY=10).
  • summary-stamped.txt: the same lines with the Unix time each was printed, to line them up with the cutscene marks.
  • aps5-trace-*.json.xz: the trace (APS5_TRACE_SECONDS=100:60).
  • profile-draw-lines.txt: the [guestmem], [rescache] and [draw] lines of APS5_PROFILE_DRAW=1, printed every 10 s; the comparison, revalidation and committer figures come from these.
  • README.txt: build, switches, cutscene marks and how the run ended.

The second PR run was left in gameplay after cutscene 2 and stopped by the 30-minute run limit. Its tables use only the cutscene windows.

AI-assisted: yes (Claude Code)

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

Re-checked — changes requested

The new head adds the two regression cases requested in the earlier review: remapping one alias now checks that tracking is detached correctly, and the import-window case checks that a linked store outside the window is bounded. Those close the previously identified test gaps. The remaining blocker is still the performance comparison baseline.

What I ran

  • Reviewed current head 99fdd715b0857c44abf120d4c1974c21d142f84a against current main 319621ba2e578bd053b0baba2877fe70520e0737.
  • Compared the new head with the previously reviewed dc64a2214708ca7bf3e69d0ff18aae4ebb3397a0; the new commit changes only the test file.
  • Inspected the two new alias/remap and import-window cases.
  • Ran git diff --check refs/review/base...refs/review/pr-12452.
  • Generated a merge preview against current main.
  • Checked #11580’s current state and refreshed this PR’s hosted checks.

Results

Check Result
git diff --check pass
Merge preview against current main clean; tree d46006acea9dd9f061eedae09c99d781c4309703
New remap and import-window tests present at the current head; not run locally
Hosted conventions, policy, and platform checks pass
Hosted Linux/product job skipped
Author-reported test suite and GPU validation runs useful evidence; not independently reproduced
Performance report still uses a baseline including open #11580, not current main

Findings

Blocking

The performance data remains a comparison of current PR head 99fdd715b0 against main 446bd8776c plus #11580. #11580 is still open, so that baseline is not current main 319621ba2e. The paired traces may measure the optimization accurately on top of #11580, but they do not meet the repository’s required main-versus-change comparison. Please recapture on current main or obtain maintainer agreement to an explicitly declared stacked baseline.

Non-blocking

The new tests address the two test-coverage gaps from the previous review. The remaining open limitation in the report is the baseline, not those test cases.

Sources

Not verified

I did not rerun the C++ build, CTest, Vulkan validation, GTA V captures, or trace digests. Hosted Linux/product checks were skipped.

To get this to a good state

Provide a matched same-machine/title/scene capture pair using current main and this head, with both summary lines, traces, and digest output; alternatively, document maintainer-approved use of the stacked baseline and declare the dependency.

@Tehshortbus

Copy link
Copy Markdown
Contributor Author

Correction: the cutscene 1 fps row double-counted each run's 60 s trace-window summary line. Recomputed from the 10 s lines alone, it is 12.53 / 13.51 / 13.80 / 13.22 (was 12.71 / 13.77 / 13.80 / 13.31), so the cutscene 1 gain is 2–10 %, not the 3–9 % in my comment above. Both PR runs are still above both base runs, and the description is updated; the cutscene 2 and comparison figures are unchanged.

AI-assisted: yes (Claude Code)

@Tehshortbus

Copy link
Copy Markdown
Contributor Author

@MarcZX10 Thanks. On the baseline: GTA V can't reach these cutscenes on plain main. It stops 40–50 s after launch, while the save loads, on #11425 (compute shader 0x25b36a200: reads or writes a converted float image with 16-bit data), and #11580 is the fix for that stop. So no capture on plain main reaches the scenes measured here.

This PR doesn't depend on #11580 in code: the two touch different files, and the merge preview against main is clean. #11580 is needed only to reach the scene. I can:

In the meantime, here is the same comparison on current main 319621ba2e (+ #11580), with and without this PR. It comes from two rounds I ran today for another change, on the same machine, scene and warm shader cache. Per 10 s:

main + #11580, run 1 run 2 + this PR, run 1 run 2
Cutscene 1 fps 13.67 13.71 14.43 13.65
Cutscene 2 fps 5.89 5.95 6.36 6.11
Texture comparisons (c1 / c2) 8,798 / 22,292 8,828 / 22,732 6 / 32 5 / 37
Refused collects (c1 / c2) 6,458 / 11,212 6,425 / 11,037 0 / 0 0 / 0
Revalidation ms (c1 / c2) 716 / 1,336 719 / 1,315 524 / 858 521 / 847

The comparisons and refused collects go away as in the description. Cutscene 2 gains 3–8 %; in cutscene 1 one run gains about 5 % and the other matches the base.

AI-assisted: yes (Claude Code)

@Tehshortbus
Tehshortbus force-pushed the perf/watch-aliased-direct-memory branch from 99fdd71 to 60df389 Compare October 28, 2026 23:15

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

Re-checked — changes requested

The added alias and import-window regression cases address the earlier test gaps, but the performance report still does not provide a complete, accepted comparison against the current base.

What I ran

  • Reviewed exact head 60df38935c6c26fbb05d47e38d8b9a791df05c61; the head's merge base with the fetched current main 3a2b91981651569163768854a1fcdc7193b6667b is c40a9fbd1c373134505c12ce71013d903430e128.
  • Ran git merge-tree --write-tree upstream/main HEAD; the current-main merge preview is clean (beb1054126a9341f130e7868627e1c3a177dc9c7).
  • Ran python3 tools/check_conventions.py --base upstream/main and git diff --check upstream/main...HEAD; both passed.
  • Refreshed hosted checks: Windows, Ubuntu relinker, Windows relinker, ASan, Ubuntu register-context, conventions, eligibility and labels pass. macOS relinker/register-context/write-watch jobs remain pending; Linux product tests are skipped.
  • Read the updated performance comment and the PR body. The body still documents the earlier pair based on main 446bd8776c + #11580. The comment adds a table for main 319621ba2e + #11580, but it does not include the summary lines, trace files or trace_digest.py output for that pair. I did not rerun the C++ tests or captures locally.

Results

Check Result
Current-main merge preview Clean, tree beb1054126a9341f130e7868627e1c3a177dc9c7
Conventions and diff check Pass
Hosted Windows and Ubuntu relinker checks Pass
Hosted ASan and Ubuntu register-context checks Pass
Hosted macOS relinker/register-context/write-watch checks Pending
Hosted Linux product job Skipped
Current-base performance report Incomplete; table only in comment, without the paired summaries, traces and digest

Findings

Blocking

  • The required performance comparison is not yet reviewable against the current base. The complete report in the PR body uses the earlier main 446bd8776c + #11580 baseline. The newer comment reports main 319621ba2e + #11580 results, but omits the exact aps5-summary.jsonl lines, attached traces and tools/trace_digest.py output for those runs. I also do not see maintainer agreement in the thread to use a stacked baseline; #11580 remains open.
  • The reported baseline predates a relevant current-main change. Current main includes #8930 (33acc03447034b61424cc1c36143cc40ea02bad3), which changes core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp; this PR also changes that file. The merge preview is clean, but the posted tests and captures do not verify the integrated tree or the current baseline.

Sources

Not verified

I did not independently run the C++ tests, the GPU captures, or trace digests. The posted exact summary lines and trace attachments remain the earlier pair; the current main + #11580 table is author-reported.

To get this to a good state

Rebase onto current main and rerun the focused alias/write-watch tests with #8930 present. Then provide the full same-machine/title/scene report for the current main and change (both summary lines, attached traces and digest output). If retaining main + #11580 as the baseline because plain main cannot reach the scene, record maintainer agreement to that stacked baseline and provide those same artifacts for the exact runs.

@Tehshortbus

Copy link
Copy Markdown
Contributor Author

@MarcZX10 @adriadam10 This PR is now rebased onto current main c40a9fbd1c (head 60df38935c; range-diff shows both commits =), and the GTA V A/B is redone on it. The description has the new tables, the two aps5-summary.jsonl lines and the tools/trace_digest.py output of both.

One zip per run, in run order. The traces are recompressed with xz to fit the attachment limit; xz -d gives the .json that tools/trace_digest.py reads.

Zip Build Cutscene 1 / 2 marked (s after launch) Trace window (s after cutscene 1 starts)
gta-alias9-base-r1.zip base (7409219790) 78 / 186 29–89
gta-alias9-pr-r1.zip PR (d0eed65fb4) 150 / 256 mostly before cutscene 1, not compared
gta-alias9-pr-r2.zip PR (d0eed65fb4) 83 / 188 24–84
gta-alias9-base-r2.zip base (7409219790) 70 / 175 36–96

Each zip holds the summary lines (aps5-summary.jsonl, and summary-stamped.txt with the Unix time of each line), the trace, the [guestmem], [rescache] and [draw] lines of APS5_PROFILE_DRAW=1, and a README with the build, switches, cutscene marks and exit status.

AI-assisted: yes (Claude Code)

@Tehshortbus
Tehshortbus force-pushed the perf/watch-aliased-direct-memory branch from 60df389 to d10b767 Compare October 29, 2026 06:16
…port window over an alias

CheckDirectMemoryWriteWatchDropsAliasOnRemap remaps an aliased direct
memory view with MAP_FIXED to other physical pages and checks that
neither view reports the other's stores afterwards.
CheckImportWindowOverAlias opens an import window over one of two linked
views and stores through the other, so the window collect reports a
page below the window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Tehshortbus
Tehshortbus force-pushed the perf/watch-aliased-direct-memory branch from d10b767 to a160f78 Compare October 29, 2026 10:44
@Tehshortbus

Copy link
Copy Markdown
Contributor Author

@MarcZX10 Rebased onto current main 1db077e876 (it moved past aaccd0ba39 meanwhile). The head is a160f789ec, and range-diff against the measured head d10b767163 shows both commits unchanged. #11580 stays in the baseline and in Depends on, and it still merges cleanly on top.

AI-assisted: yes (Claude Code)

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

Re-checked — changes requested

Your update resolves the prior stale-baseline request against aaccd0ba39: it rebases to 1db077e876, reports all 18 focused tests and the negative controls on the new head, and explains why the captures still cover an unchanged production path. Current main is now ba5b5330b3. Please merge that current head and rerun the 18 focused write-watch/import/alias tests and negative controls. The current-main changes in the PR's files are limited to its debt entry, so the existing performance captures can remain if the updated diff confirms the measured production path is unchanged.

@Tehshortbus

Copy link
Copy Markdown
Contributor Author

@MarcZX10 Merged main ba5b5330b3 into the branch; the head is 4621b11d00. The PR's own diff is unchanged (7 files, +321/−29), and the merge preview onto main is clean.

  • Focused tests on 4621b11d00: the 18 write-watch, import and alias tests pass with ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, with no VUID- line or missing-layer message. 991 of 992 guest_* pass; guest_freebsd_clocks fails the same way on plain main (Tests: guest_freebsd_clocks aborts where the host zone is not UTC #12736).
  • Negative controls, rerun on this head:
    • without the link cut in Register, guest_memory fails at GuestMemory.cpp:3164;
    • without the WindowCopy::Holds bound, agc_write_tracking crashes (SIGSEGV);
    • with main's GuestWriteWatch.cpp and DirectMemory.cpp, guest_memory fails at :3036.
  • Measured path: between 1db077e876 and ba5b5330b3, the only change in this PR's files is fix(agc): draw compacted restart lists and restart-free strips through the barycentric patches #12706's edit of a different debt entry (triangle strips through the barycentric tessellation stages). The write watch, direct memory and WindowCopy are unchanged, so the captures stand. The description is updated with the new head and results.

AI-assisted: yes (Claude Code)

@Tehshortbus
Tehshortbus requested a review from MarcZX10 October 29, 2026 11:44

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

Re-checked — new head, looks good

The requested current-main refresh and exact-head focused evidence are present, the measured production paths are unchanged since the capture baseline, and the required hosted checks pass.

What I ran

  • Reviewed head 4621b11d0034ac851ca5691829050dc621504c8f against current main 7aabd03d0a32bb928311ef1323b95dffb4618f7e; the merge preview is clean.
  • Compared the PR file list with changes from the reported measurement base 1db077e876 to current main. The only overlapping path is the debt document; the measured write-watch, direct-memory, and import-window implementation paths are unchanged.
  • Refreshed hosted checks for the exact head. This review ran from a Linux shell; I did not invoke a compiler or run C++ tests locally.
  • Read the author's exact-head test and negative-control report; those runs are author-reported, not independently reproduced here.
git fetch upstream main
git fetch upstream pull/12452/head:refs/remotes/review/pr-12452
git merge-tree --write-tree upstream/main refs/remotes/review/pr-12452
gh pr view 12452 -R boykopovar/AnyPS5 --json files --jq '.files[].path'
git diff --name-only 1db077e876 upstream/main
gh pr checks 12452 -R boykopovar/AnyPS5

Results

Check Result
Merge preview against current main Pass; clean tree 7e84b4ba1296e790168b317d2b7c652988478574
Relevant path comparison since measured base Only shared path is docs/dev/debt/libSceAgcDriver.md; measured production paths are unchanged
Hosted conventions, eligibility, labels, report, Windows, register-context, relinker, ASan, and macOS write-watch checks Pass
Hosted Linux product job Skipped
18 focused write-watch/import/alias tests on exact head Author reports pass with Vulkan validation; not locally reproduced
991/992 guest_* tests on exact head Author reports 991 pass; guest_freebsd_clocks has the same failure on main
Three negative controls Author reports each regression test fails when its corresponding fix is removed
Unedited command output
7e84b4ba1296e790168b317d2b7c652988478574
docs/dev/debt/libSceAgcDriver.md
conventions	pass	16s	https://github.com/boykopovar/AnyPS5/actions/runs/40867583050/job/123426148406
eligibility	pass	8s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426140489
labels	pass	7s	https://github.com/boykopovar/AnyPS5/actions/runs/40867583016/job/123426201836
register-context (macos-15-intel, Debug)	pass	1m11s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211921
register-context (macos-15-intel, Release)	pass	1m13s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211890
register-context (ubuntu-latest, Debug)	pass	35s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211919
register-context (ubuntu-latest, Release)	pass	35s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211986
relinker (macos-latest, clang++)	pass	5m25s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211893
relinker (macos-latest, clang++, x86_64)	pass	6m22s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211952
relinker (ubuntu-latest, g++)	pass	2m42s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426212008
relinker (windows-latest, g++)	pass	9m23s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426212076
relinker-asan	pass	1m49s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211857
windows	pass	10m8s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211959
linux	skipping	0	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426213868
report	pass	40s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580927/job/123426135322
write-watch (macos-15)	pass	41s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211914
write-watch (macos-15-intel)	pass	1m51s	https://github.com/boykopovar/AnyPS5/actions/runs/40867580933/job/123426211799

Negative control

Assertion Change made to code under test New test failed?
Alias stores are observed through each linked view Restored main's GuestWriteWatch.cpp and DirectMemory.cpp Yes, author-reported
Remapped aliases stop reporting stale linked stores Removed the link cut in Register Yes, author-reported
Import-window alias collection stays within the window buffer Removed the WindowCopy::Holds bound Yes, author-reported

Findings

Blocking

None found in the reviewed exact head.

Non-blocking

The hosted Linux product job is skipped, and I did not independently reproduce the author's Linux/GPU test and capture runs.

Sources

Not verified

I did not run a local C++ build, CTest, Vulkan validation, GTA V capture, trace digest, or console test. The focused Linux results and GPU captures are author-reported.

@chitters2004

Copy link
Copy Markdown
Contributor

@Tehshortbus, a quick merge-order check for MarcZX10's review of #12565. #12565 changes one word ((five to (up to 600) in the frame capture entry of docs/dev/debt/libSceAgcDriver.md, and this PR edits other words of the same line, so git reports a conflict even though the edits don't touch. The order on #12565 is #10760, then #12565, then this PR, which keeps both edits when it rebases. If that works for you, could you say so here and add #12565 to this PR's Depends on line (next to #11580)? MarcZX10 asked on #12565 for the order to be recorded in each affected PR's checklist, and #12565 already lists Depends on: #10760. If you'd rather this went first, tell me and I'll rebase #12565 onto it.

AI-assisted: yes (Claude Code)

@TechLevelZero

TechLevelZero commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head 4621b11 merged onto main 828ac0b · tested 2026-10-31 13:34 UTC · 32 min

GPU NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 2,950 passed · 6 failed (0 new, 3 also fail on main, 3 unstable on main) · 42 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 2,998 of 3,048 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (1180 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 53.2 s, ⚠️ agc_driver_bda_device 43.6 s, ⚠️ agc_driver_graphics_maps_fallback 32.1 s, ⚠️ agc_driver_graphics 30.2 s
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_submit_progress: failed in 6 of the last 10 main runs
agc_submit_progress: failed in 6 of the last 10 main runs
agc_submit_progress_no_timeline: failed in 8 of the last 10 main runs
Failing on main too (3, not counted against this PR)
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validation IDs already present on main (5 IDs in 686 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (686 tests): agc_compute_pipeline_replay, agc_driver, agc_driver_address_passes, agc_driver_address_passes_draw_transitions, agc_driver_address_passes_targets_split, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, and 678 more
VUID-vkCmdCopyImage-srcImage-01548 (12 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 4 more
VUID-vkCmdCopyImage-srcImage-01551 (12 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 4 more
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (2 tests): agc_driver_prepared_exports, agc_driver_srgb8_color_target
VUID-VkShaderModuleCreateInfo-pCode-08737 (1 test): agc_driver_image_sample_derivatives
Skipped (42)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_msaa_dcc_compared_import_2: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_msaa_dcc_compared_import_4: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_msaa_dcc_compared_import_8: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_sample_order_grid_reference: skipped, the device does not keep depth drawn at custom sample locations at those locations, even after a transition that names them: the composite of uniform renders holds the guest's depth in 0 of 3005 sloped samples, so no path can be compared with it bit for bit
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_stencil_ref_export: skipped, the device lacks VK_EXT_shader_stencil_export
agc_driver_vertex_elected_atomic_max: skipped, the device runs vertex programs in subgroups, so they keep their cross-lane reductions
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_main: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_fresh: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or plat
Reproduce
git fetch origin 4621b11d0034ac851ca5691829050dc621504c8f 828ac0b2ae74aac181ba128fb59b08a1534f2041
git checkout 828ac0b2ae74aac181ba128fb59b08a1534f2041 && git merge --no-ff 4621b11d0034ac851ca5691829050dc621504c8f
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 32 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 4 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated 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.

@Tehshortbus

Copy link
Copy Markdown
Contributor Author

@chitters2004 Thanks for checking. Since this PR was opened first, I'd keep it ahead of #12565. MarcZX10 has approved the current head 4621b11d00, and the perf pair both reviewers asked for is in the description.

The rebase is one line. I merged both heads (4621b11d00 and 4284e7715b), and the only conflict is the frame capture entry: this PR rewrites the sentence on Linux aliases, and #12565 changes (five to (up to 600 in another sentence. Keeping both gives a 973-character line, under the debt-length limit. So #12565 would record Depends on: #10760, #12452, and this PR's checklist stays as it is.

AI-assisted: yes (Claude Code)

@chitters2004

Copy link
Copy Markdown
Contributor

@Tehshortbus Fair enough, and thanks for checking the merge. I get the same single conflict between 4621b11d00 and 4284e7715b in the frame capture entry, and keeping both edits resolves it. So the order is #10760, then this PR, then #12565. I've changed #12565 to Depends on: #10760, #12452, and I'll merge main into it and take the one-line resolution once this one lands. #11447 still keeps both edits when it rebases after.

AI-assisted: yes (Claude Code)

@mrfelek

mrfelek commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Independent check in gameplay, since the description measures the opening cutscenes. GTA V EU (PPSA04263 01.010.002), Linux, RTX 3080 Ti (615.71.09), 4K. main 9f748f4d8e + #11580 against the same with this head 4621b11d00. North Yankton prologue, player standing in the bank, warm caches, A B A B, APS5_TRACE_SECONDS=300:20:

presents in 20 s frame p50
main 62 / 62 325 / 319 ms
this PR 64 / 65 311 / 309 ms
  • Texture comparisons ([guestmem] compare, APS5_PROFILE_DRAW=1 runs): about 18,000 calls (about 10 GB, 0.6 s) per 10 s on main, and 105 calls in the whole run with this PR.
  • Picture: the same in all four runs.

So the effect holds in gameplay too, on another GPU and the EU release.

AI-assisted; the runs are from my machine(s).

… capture note

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Nov 1, 2026
@Tehshortbus

Copy link
Copy Markdown
Contributor Author

@MarcZX10 @adriadam10 main had moved, and the branch conflicted with it in docs/dev/debt/libSceAgcDriver.md, so I merged main e6f57307fa into the branch. The head is now fa49b5fc86.

  • Conflict: main added the "FS table calls on macOS" entry just above the frame capture entry, and this PR rewrites the Linux-alias sentence of that entry. I kept both. The PR's code diff is byte-identical to 4621b11d00 (same git patch-id; 7 files, +321/−29 with the doc), and the merge preview onto current main e67cc81869 is clean.
  • Focused tests on fa49b5fc86: 21 write-watch, import and alias tests pass with ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, with no VUID- line or missing-layer message. All 1081 guest_* pass.
  • Negative controls, rerun on this head:
    • without the link cut in Register, guest_memory fails at GuestMemory.cpp:3348;
    • without the WindowCopy::Holds bound, agc_write_tracking crashes (SIGSEGV);
    • with main's GuestWriteWatch.cpp and DirectMemory.cpp, guest_memory fails at :3220, the first coverage check of an aliased view.
  • Measured path: in GuestWriteWatch.cpp, main changed only the macOS watch (build(agc): compile Lifecycle, GuestMemory and GuestBufferMemory on macOS #11447's read traps) and the includes; the Linux userfaultfd watch this PR changes is untouched. main also brought build(agc): compile Lifecycle, GuestMemory and GuestBufferMemory on macOS #11447's DirectMemoryAliased and an ENOMEM return for unallocated direct memory in DirectMemory.cpp, and two write-watch block stamping fixes in GuestMemory.cpp. These are outside this PR's diff and apply to both arms alike. I haven't rerun the GTA V pair on this head.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Nov 1, 2026
@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head fa49b5f merged onto main e6f5730 · tested 2026-11-01 16:11 UTC · 40 min

GPU NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 3,049 passed · 6 failed (0 new, 3 also fail on main, 3 unstable on main) · 51 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 3,106 of 3,148 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (1225 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.3 s, ⚠️ agc_driver_lookup_log_fits_build 54.8 s, ⚠️ agc_driver_bda_device 53.8 s, ⚠️ agc_driver_graphics_maps_fallback 31.0 s, ⚠️ agc_driver_graphics 30.0 s
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_pipeline_journal: failed in 1 of the last 10 main runs
agc_submit_progress: failed in 6 of the last 10 main runs
agc_submit_progress_no_timeline: failed in 8 of the last 10 main runs
Failing on main too (3, not counted against this PR)
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validation IDs already present on main (5 IDs in 711 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (711 tests): agc_compute_pipeline_replay, agc_driver, agc_driver_address_passes, agc_driver_address_passes_draw_transitions, agc_driver_address_passes_targets_split, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, and 703 more
VUID-vkCmdCopyImage-srcImage-01548 (13 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 5 more
VUID-vkCmdCopyImage-srcImage-01551 (13 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 5 more
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (2 tests): agc_driver_prepared_exports, agc_driver_srgb8_color_target
VUID-VkShaderModuleCreateInfo-pCode-08737 (1 test): agc_driver_image_sample_derivatives
Skipped (51)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_msaa_dcc_compared_import_2: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_msaa_dcc_compared_import_4: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_msaa_dcc_compared_import_8: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_sample_order_grid_reference: skipped, the device does not keep depth drawn at custom sample locations at those locations, even after a transition that names them: the composite of uniform renders holds the guest's depth in 0 of 3005 sloped samples, so no path can be compared with it bit for bit
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_stencil_ref_export: skipped, the device lacks VK_EXT_shader_stencil_export
agc_driver_vertex_elected_atomic_max: skipped, the device runs vertex programs in subgroups, so they keep their cross-lane reductions
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_dcc: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_deferred: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or pla
Reproduce
git fetch origin fa49b5fc862382a1143998c4001a2ee1576ff41c e6f57307fa7f47165d7fc1bee945abdb2f6816e7
git checkout e6f57307fa7f47165d7fc1bee945abdb2f6816e7 && git merge --no-ff fa49b5fc862382a1143998c4001a2ee1576ff41c
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 32 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 4 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated 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.

…alias capture note

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

Copy link
Copy Markdown
Contributor Author

@MarcZX10 @adriadam10 #10760 merged, and its "Capture trace output" entry conflicted with this PR's edit of the next line in docs/dev/debt/libSceAgcDriver.md. I merged main 859db5cd22 into the branch and kept both: the new entry and this PR's frame capture line, which main left unchanged. The head is now eea57da58b.

  • Diff: the PR's changed lines are identical to fa49b5fc86; only the surrounding context moved, as main also changed GuestMemory.cpp, DirectMemory.cpp and their tests. The PR is still 7 files, +321/−29, and the merge preview onto current main 3c3b3cda73 is clean.
  • Focused tests on eea57da58b: the same 21 write-watch, import and alias tests pass with ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, with no VUID- line or missing-layer message.
  • Code from main that meets this PR: main brought the scattered direct memory dma-buf import, the import unwatch hooks after every window walk, and hashing an idle unit when its range leaves the write watch. All 83 agc_* import, watch, alias, direct, dma-buf and mirror tests (including agc_driver_sparse_dma_buf_import and agc_unwatch_hook_lock_order) pass under the same layers with no VUID- line. All 1333 guest_* pass.
  • Negative controls, rerun on this head:
    • without the link cut in Register, guest_memory fails at GuestMemory.cpp:3388 (CheckDirectMemoryWriteWatchDropsAliasOnRemap);
    • without the WindowCopy::Holds bound, agc_write_tracking crashes (SIGSEGV);
    • with main's GuestWriteWatch.cpp and DirectMemory.cpp, guest_memory fails at :3260, the first coverage check of an aliased view.
  • Measured path: I haven't rerun the GTA V pair on this head.

AI-assisted: yes (Claude Code)

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head eea57da merged onto main 1d91f29 · tested 2026-11-02 19:12 UTC · 30 min

GPU NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 3,437 passed · 5 failed (0 new, 3 also fail on main, 2 unstable on main) · 52 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 3,494 of 3,544 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (1295 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.5 s, ⚠️ agc_driver_bda_device 39.1 s, ⚠️ agc_driver_graphics 33.0 s, ⚠️ agc_driver_graphics_maps_fallback 32.9 s
Unstable on main (2, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_pipeline_journal: failed in 3 of the last 10 main runs
agc_driver_submit_progress: failed in 7 of the last 10 main runs
Failing on main too (3, not counted against this PR)
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validation IDs already present on main (4 IDs in 746 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (746 tests): agc_compute_pipeline_replay, agc_driver, agc_driver_address_passes, agc_driver_address_passes_draw_transitions, agc_driver_address_passes_targets_split, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, and 738 more
VUID-vkCmdCopyImage-srcImage-01548 (13 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 5 more
VUID-vkCmdCopyImage-srcImage-01551 (13 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 5 more
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (2 tests): agc_driver_prepared_exports, agc_driver_srgb8_color_target
Skipped (52)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_msaa_dcc_compared_import_2: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_msaa_dcc_compared_import_4: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_msaa_dcc_compared_import_8: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_sample_order_grid_reference: skipped, the device does not keep depth drawn at custom sample locations at those locations, even after a transition that names them: the composite of uniform renders holds the guest's depth in 0 of 3005 sloped samples, so no path can be compared with it bit for bit
agc_driver_scattered_runs: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_stencil_ref_export: skipped, the device lacks VK_EXT_shader_stencil_export
agc_driver_vertex_elected_atomic_max: skipped, the device runs vertex programs in subgroups, so they keep their cross-lane reductions
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_dcc: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_deferred: skipped, no display or Vulkan device: DisplayWindow: Vulkan suppor
Reproduce
git fetch origin eea57da58b30772c8e0a2fe31f0fc3c75ac7814a 1d91f2966d0eef82a021628a7aa8e78e615ac807
git checkout 1d91f2966d0eef82a021628a7aa8e78e615ac807 && git merge --no-ff eea57da58b30772c8e0a2fe31f0fc3c75ac7814a
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 32 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 4 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated 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.

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ AMD GPU test: passed

PR head eea57da merged onto main a4eca2a · tested 2026-11-03 02:22 UTC · 26 min

GPU AMD Radeon RX 6300 (RADV NAVI24), driver Mesa 25.2.8-0ubuntu0.24.04.4, Vulkan 1.4.318
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-42-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 3,467 passed · 15 failed (0 new, 13 also fail on main, 2 unstable on main) · 59 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 3,541 of 3,591 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (1306 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.2 s, ⚠️ agc_driver_graphics_maps_fallback 113.9 s, ⚠️ agc_driver_graphics 105.4 s, ⚠️ public_headers 80.4 s, ⚠️ agc_driver_bda_device 56.2 s
Unstable on main (2, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_array_layer_target_cpu: failed in 1 of the last 7 main runs
agc_driver_pipeline_journal: failed in 5 of the last 7 main runs
Failing on main too (13, not counted against this PR)
agc_driver_guest_memory_lifetime_direct
agc_driver_image_table
agc_driver_job_manager_compute_capacity
agc_driver_native_depth_bda_clear
agc_driver_native_depth_buffer_clear
agc_driver_native_depth_clears
agc_driver_native_multisample_depth
agc_driver_submit_progress
agc_idle_publish_wait
agc_submit_progress
agc_submit_progress_no_timeline
guest_mmap_executable
guest_socket_options_multicast
Validation IDs already present on main (4 IDs in 750 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (750 tests): agc_compute_pipeline_replay, agc_driver, agc_driver_address_passes, agc_driver_address_passes_draw_transitions, agc_driver_address_passes_targets_split, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, and 742 more
VUID-vkCmdCopyImage-srcImage-01548 (11 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_storage_dispatch, and 3 more
VUID-vkCmdCopyImage-srcImage-01551 (11 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_storage_dispatch, and 3 more
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (2 tests): agc_driver_prepared_exports, agc_driver_srgb8_color_target
Skipped (59)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_copied_writer_label_order: skipped, the device reports a minStorageBufferOffsetAlignment of 4, so the dispatch binds its record at +0x1004 in place and nothing is written back; the test needs an alignment above 4
agc_driver_copied_writer_label_order_drain: skipped, the device reports a minStorageBufferOffsetAlignment of 4, so the dispatch binds its record at +0x1004 in place and nothing is written back; the test needs an alignment above 4
agc_driver_float16_unused_nan_payloads: skipped, the device has no native f16 conversions with RTE rounding and kept f16 denormals
agc_driver_image_table_vouched_lookups: skipped, the device reports 4 of 4 host-imported pages written after a GPU read, so a watched imported table cannot be vouched for
agc_driver_linear_target_direct_write_completion: skipped, the device does not keep host imports write-watched, so no completion stamp over the target is tracked
agc_driver_ngg_vertex_wave_reduction: skipped, s3 describes a 32-lane wave only on 32-lane subgroups, and the device has 64 lanes
agc_driver_scattered_runs: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_unit_shadow: skipped, the device does not import watched host memory for unit shadows
agc_driver_unit_shadow_budget: skipped, the device does not import watched host memory for unit shadows
agc_driver_vertex_elected_atomic_max: skipped, the device runs vertex programs in subgroups, so they keep their cross-lane reductions
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_shadowed_key_stores: skipped, the device imports no watched host memory under a unit shadow
agc_small_tiled_shadow_label: skipped, host imports are unavailable: the test block is not imported and watched
agc_storage_clear_hand_over: skipped, the device imports no watched host memory for the clear-key hand-over
agc_unit_shadow: skipped, the device does not import watched host memory for unit shadows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWi
Reproduce
git fetch origin eea57da58b30772c8e0a2fe31f0fc3c75ac7814a a4eca2a056bf3bbbec98ab42e9d28163e4ea9cb8
git checkout a4eca2a056bf3bbbec98ab42e9d28163e4ea9cb8 && git merge --no-ff eea57da58b30772c8e0a2fe31f0fc3c75ac7814a
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 12 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 16 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Hi adriadam10,

Your change request from 10-28 (at dc64a22147) left one point open: the base/PR pair on the current head. As far as we can tell it is now done at the live head eea57da58b. Could you take another look?

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

Copy link
Copy Markdown
Contributor Author

@MarcZX10 @adriadam10 Build / windows on eea57da58b was cancelled at its 45-minute job timeout while still linking (target 861 of 1167), before any test ran. I can't re-run a job on this repository, so I merged current main 4f41f4c375 (no conflicts) to start a fresh run. The head is now b9a20d690a.

  • Diff: the PR's changed lines are identical to eea57da58b (and so to the measured d10b767163 patch). Only the surrounding context moved. Still 7 files, +321/−29.
  • Tests on b9a20d690a: the same 21 focused write-watch, import and alias tests and 85 agc_* import, watch, alias, direct, dma-buf and mirror tests pass with ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, with no VUID- line or missing-layer message. These cover what main brought into these files: 64-bit write-tracker generations, the copied write-back fixes, and the direct memory changes. All 1499 guest_* pass.
  • Negative controls, rerun on this head:
    • without the link cut in Register, guest_memory fails at GuestMemory.cpp:3453 (CheckDirectMemoryWriteWatchDropsAliasOnRemap);
    • without the WindowCopy::Holds bound, agc_write_tracking crashes (SIGSEGV);
    • with main's GuestWriteWatch.cpp and DirectMemory.cpp, guest_memory fails at :3325, the first coverage check of an aliased view.

AI-assisted: yes (Claude Code)

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ AMD GPU test: passed

PR head b9a20d6 merged onto main 4f41f4c · tested 2026-11-03 14:24 UTC · 40 min

GPU AMD Radeon RX 6300 (RADV NAVI24), driver Mesa 25.2.8-0ubuntu0.24.04.4, Vulkan 1.4.318
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-42-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 3,684 passed · 17 failed (0 new, 13 also fail on main, 4 unstable on main) · 60 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 3,761 of 3,811 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (1329 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 122.0 s, ⚠️ agc_driver_graphics 119.8 s, ⚠️ agc_driver_graphics_maps_fallback 113.8 s, ⚠️ agc_driver_image_sample_unnormalized 62.8 s, ⚠️ agc_driver_bda_device 52.6 s
Unstable on main (4, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_array_layer_target_cpu: failed in 1 of the last 9 main runs
agc_driver_pipeline_journal: failed in 7 of the last 9 main runs
agc_driver_store_over_untracked: failed in 1 of the last 9 main runs
agc_driver_two_sample_alpha_to_coverage_sample_mask_export: failed in 1 of the last 9 main runs
Failing on main too (13, not counted against this PR)
agc_driver_alpha_to_coverage_sample_mask_export
agc_driver_guest_memory_lifetime_direct
agc_driver_image_table
agc_driver_job_manager_compute_capacity
agc_driver_native_depth_bda_clear
agc_driver_native_depth_buffer_clear
agc_driver_native_depth_clears
agc_driver_native_multisample_depth
agc_driver_submit_progress
agc_submit_progress
agc_submit_progress_no_timeline
guest_mmap_executable
guest_socket_options_multicast
Validation IDs already present on main (4 IDs in 764 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (764 tests): agc_compute_pipeline_replay, agc_driver, agc_driver_address_passes, agc_driver_address_passes_draw_transitions, agc_driver_address_passes_targets_split, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_alpha_to_coverage_sample_mask_export, and 756 more
VUID-vkCmdCopyImage-srcImage-01548 (12 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_storage_dispatch, and 4 more
VUID-vkCmdCopyImage-srcImage-01551 (12 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_storage_dispatch, and 4 more
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_srgb8_color_target
Skipped (60)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_copied_writer_label_order: skipped, the device reports a minStorageBufferOffsetAlignment of 4, so the dispatch binds its record at +0x1004 in place and nothing is written back; the test needs an alignment above 4
agc_driver_copied_writer_label_order_drain: skipped, the device reports a minStorageBufferOffsetAlignment of 4, so the dispatch binds its record at +0x1004 in place and nothing is written back; the test needs an alignment above 4
agc_driver_float16_unused_nan_payloads: skipped, the device has no native f16 conversions with RTE rounding and kept f16 denormals
agc_driver_image_table_vouched_lookups: skipped, the device reports 4 of 4 host-imported pages written after a GPU read, so a watched imported table cannot be vouched for
agc_driver_linear_target_direct_write_completion: skipped, the device does not keep host imports write-watched, so no completion stamp over the target is tracked
agc_driver_ngg_vertex_wave_reduction: skipped, s3 describes a 32-lane wave only on 32-lane subgroups, and the device has 64 lanes
agc_driver_scattered_runs: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_unit_shadow: skipped, the device does not import watched host memory for unit shadows
agc_driver_unit_shadow_budget: skipped, the device does not import watched host memory for unit shadows
agc_driver_vertex_elected_atomic_max: skipped, the device runs vertex programs in subgroups, so they keep their cross-lane reductions
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_idle_publish_wait: skipped, the device reports 4 of 4 host-imported pages written after a GPU read, so a forced watch of the import reads its submissions as CPU stores
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_shadowed_key_stores: skipped, the device imports no watched host memory under a unit shadow
agc_small_tiled_shadow_label: skipped, host imports are unavailable: the test block is not imported and watched
agc_storage_clear_hand_over: skipped, the device imports no watched host memory for the clear-key hand-over
agc_unit_shadow: skipped, the device does not import watched host memory for unit shadows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support i
Reproduce
git fetch origin b9a20d690afa247c4cce4ee6820fec4c19a1d1cf 4f41f4c375f5abb487dbd184fbc150f31994d762
git checkout 4f41f4c375f5abb487dbd184fbc150f31994d762 && git merge --no-ff b9a20d690afa247c4cce4ee6820fec4c19a1d1cf
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 12 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 16 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs.

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head b9a20d6 merged onto main 4f41f4c · tested 2026-11-03 16:12 UTC · 25 min

GPU NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 3,703 passed · 6 failed (0 new, 3 also fail on main, 3 unstable on main) · 52 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 3,761 of 3,811 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (1329 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.2 s, ⚠️ agc_driver_bda_device 75.0 s, ⚠️ agc_driver_graphics_maps_fallback 31.3 s, ⚠️ agc_driver_graphics 30.3 s
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_pipeline_journal: failed in 4 of the last 10 main runs
agc_submit_progress: failed in 6 of the last 10 main runs
agc_submit_progress_no_timeline: failed in 5 of the last 10 main runs
Failing on main too (3, not counted against this PR)
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validation IDs already present on main (4 IDs in 764 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (764 tests): agc_compute_pipeline_replay, agc_driver, agc_driver_address_passes, agc_driver_address_passes_draw_transitions, agc_driver_address_passes_targets_split, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_alpha_to_coverage_sample_mask_export, and 756 more
VUID-vkCmdCopyImage-srcImage-01548 (14 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 6 more
VUID-vkCmdCopyImage-srcImage-01551 (14 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 6 more
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_srgb8_color_target
Skipped (52)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_msaa_dcc_compared_import_2: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_msaa_dcc_compared_import_4: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_msaa_dcc_compared_import_8: skipped, the device reports host imports that keep write protection, so the write-watch probe compares none of them
agc_driver_sample_order_grid_reference: skipped, the device does not keep depth drawn at custom sample locations at those locations, even after a transition that names them: the composite of uniform renders holds the guest's depth in 0 of 3005 sloped samples, so no path can be compared with it bit for bit
agc_driver_scattered_runs: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_stencil_ref_export: skipped, the device lacks VK_EXT_shader_stencil_export
agc_driver_vertex_elected_atomic_max: skipped, the device runs vertex programs in subgroups, so they keep their cross-lane reductions
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_dcc: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_deferred: skipped, no display or Vulkan device: DisplayWindow: Vulkan suppor
Reproduce
git fetch origin b9a20d690afa247c4cce4ee6820fec4c19a1d1cf 4f41f4c375f5abb487dbd184fbc150f31994d762
git checkout 4f41f4c375f5abb487dbd184fbc150f31994d762 && git merge --no-ff b9a20d690afa247c4cce4ee6820fec4c19a1d1cf
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 32 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 4 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated 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.

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* docs libc libkernel perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants