Skip to content

perf(agc): keep an untracked fast proof across collect epochs on Windows while its write-watch hint has not moved - #12921

Closed
EagleBearerYS wants to merge 15 commits into
boykopovar:mainfrom
EagleBearerYS:perf/agc-untracked-proof-hint-key-on-6192
Closed

EagleBearerYS wants to merge 15 commits into
boykopovar:mainfrom
EagleBearerYS:perf/agc-untracked-proof-hint-key-on-6192

Conversation

@EagleBearerYS

@EagleBearerYS EagleBearerYS commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

What

Windows only in effect. Write-watch hints exist only on Windows (GuestMemory::UntrackedHint returns 0 on other platforms), so on Linux this changes nothing: every untracked proof keeps #6192's epoch stamp.

#6192 lets a fast revalidation over untracked memory accept a surface by its stamp until the next ordering point: the stamp is {collect epoch, NewestStamp, ForgetStamp, write note}. In Resident Evil Village (PPSA01556)'s static menu, collect epochs advance about 80 times a second, so most of those proofs expire before they're reused, and the next one walks the full table again.

On Windows, an unwatched range has a write-watch hint (GuestMemory::UntrackedHint), and a store into it moves the hint at the next walk of that page's marks. The check runs that walk itself: UntrackedHint reads and resets the range's marks (walkHints) unless this thread already walked the range in the current collect epoch. This change keeps a proof across epochs while the hint hasn't moved.

  • A hinted range's stamp is {hint, NewestStamp, ForgetStamp, write note, 1}. Every field is taken just before the bytes the proof stands on are read or compared, not when the proof is captured:
    • snapshots: main's untrackedKey, carried in the lookup record (LookupRecord::untracked);
    • views and storage images: the stamp of the image's last equal compare in StorageTexture::compareUntracked, through StorageTexture::HintedComparison.
  • Why a racing store is never absorbed: a CPU store after the read leaves a write-watch mark, and the next hint walk stamps a hint newer than the recorded one. A driver store moves NewestStamp, a forget moves ForgetStamp, and a new recorded GPU write moves the note. So at the next ordering point the check walks again.
  • Unhinted ranges (Linux, shared pages, host regions) keep perf(agc): fast revalidation over untracked memory proves a surface by its stamp until the next ordering point #6192's epoch stamp. The last field keeps the two kinds apart, and both forms are refused while a forget is in progress.
  • APS5_VERIFY_UNTRACKED_PROOFS=1 still cross-checks every fast proof that used an untracked stamp, hinted or epoch, with the full walk.
  • Known cost: a new storage image has no hinted entry until its first equal compare, so its first proof across an ordering point walks once.

The branch. It holds #6192's four commits unchanged (with #6187 under them), then four of ours:

  1. A merge of main. perf(agc): fast revalidation over untracked memory proves a surface by its stamp until the next ordering point #6192 conflicts with current main in Texture.cpp (main's per-range comparedRanges memo kept, with perf(agc): an untracked comparison memo holds until memory it covers is forgotten #6187's ForgetStamp in place of ForgetSerial), ShaderResources.cpp (main's LastRecordIndices, GenerationFor and depth guard kept, with the untracked stamps added) and CMakeLists.txt (the Windows test list).
  2. The ENVIRONMENT.md row for APS5_VERIFY_UNTRACKED_PROOFS, which main's conventions check requires.
  3. agc_untracked_forget's teardown fix, offered on perf(agc): an untracked comparison memo holds until memory it covers is forgotten #6187: the test freed its detiler while a recorded dispatch still used its pipeline, which crashed lavapipe's queue thread. It's test-only.
  4. The hint key and its test.

Overlap: checked with git merge-tree against each pull request the overlap comment lists, at head fdc7004.

Resident Evil Village (PPSA01556)

Static menu, one block of four unprofiled runs, B A A B.

run fps frame p50 / p90 (s)
B 0.691 1.36 / 1.76
A 0.513 1.71 / 2.25
A 0.657 1.47 / 1.80
B 0.829 1.18 / 1.39
Summary lines at menu +10 of the first B and A runs (B 07f624d, A 103015a). Each row is one 10 s interval, so its frame times aren't the window's figures above.
{"commit":"07f624d854fb","dirty":false,"env":{"APS5_HOST_IMPORT_MIB":"6400","APS5_LAZY_SHADER_PREPARE":"1","APS5_NO_GPL":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"NVIDIA GeForce RTX 3070 Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26300","cpu":"AMD Ryzen 9 5900HS with Radeon Graphics","cpu_threads":16,"memory_mib":15776,"title_id":"PPSA01556","title":"Resident Evil Village","content_version":"01.210.000","resolution":"3840x2160","window":{"spec":"summary_every 10","first_present":1605,"ms":10237.489},"interval_start_s":836.978,"interval_end_s":847.215,"presents":6,"frame_ms":{"p50":1738.099,"p90":2336.798,"p99":2336.798,"max":2336.798},"gpu_busy_ms_per_present":243.520,"worker_busy_pct":{"queue worker 0x0":99.570,"queue worker 0x38":0.112,"queue worker 0x20":89.391,"queue worker 0x28":94.215},"top_phases_ms_per_frame":{"Driver.Packet":4828.637,"Driver.Packet.memory_wait":2822.733,"Driver.Packet.draw":1269.158,"Driver.Draw":1267.783,"Graphics.Draw":996.479,"Graphics.Draw.draw_and_resource_release":970.327,"Driver.Packet.dispatch":693.763,"Driver.Dispatch":639.245},"trace_dropped":false,"trace":""}
{"commit":"103015a9ca66","dirty":false,"env":{"APS5_HOST_IMPORT_MIB":"6400","APS5_LAZY_SHADER_PREPARE":"1","APS5_NO_GPL":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"NVIDIA GeForce RTX 3070 Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26300","cpu":"AMD Ryzen 9 5900HS with Radeon Graphics","cpu_threads":16,"memory_mib":15776,"title_id":"PPSA01556","title":"Resident Evil Village","content_version":"01.210.000","resolution":"3840x2160","window":{"spec":"summary_every 10","first_present":3369,"ms":11746.745},"interval_start_s":979.116,"interval_end_s":990.863,"presents":6,"frame_ms":{"p50":2124.387,"p90":2317.005,"p99":2317.005,"max":2317.005},"gpu_busy_ms_per_present":285.700,"worker_busy_pct":{"queue worker 0x0":99.617,"queue worker 0x38":0.114,"queue worker 0x20":90.888,"queue worker 0x28":95.018},"top_phases_ms_per_frame":{"Driver.Packet":5590.476,"Driver.Packet.memory_wait":3348.407,"Driver.Packet.draw":1541.600,"Driver.Draw":1540.185,"Graphics.Draw":1190.041,"Graphics.Draw.draw_and_resource_release":1161.247,"Driver.Packet.dispatch":661.397,"Driver.Dispatch":602.462},"trace_dropped":false,"trace":""}
  • Traces: one 30 s capture of each arm, menu +10.3-10.5 min, with APS5_TRACE_SECONDS=960:30 and no other trace or profile switch:
    • A: aps5-trace-103015a9ca66-33724.json.gz, 2,419,643 bytes, sha256 16eab88b27f0843a5aa46433a83dbb69cc1fd960ff2a521acade7d20b52fb809;
    • B: aps5-trace-07f624d854fb-36204.json.gz, 2,161,932 bytes, sha256 bb08a9ac103f778937429c3ead8343ed6b3e87b6abf7bc7ff8c471b125913f0b.
    • A single 30 s window per arm is too short to compare speed (frame p50 1.50 s for A, 1.44 s for B). The comparison is the four unprofiled runs above.
    • GPU clocks weren't held: P0 98 %, mean 1,420-1,425 MHz.
trace_digest.py of A (103015a)

seconds 960:30 from present 2901: 21 presents, frame p50 1497.6 / p90 1783.2 / p99 1903.7 / max 1903.7 ms, GPU busy 230.6 ms per present
NVIDIA GeForce RTX 3070 Laptop GPU, NVIDIA 617.42, Windows 10.0.26300, 3840x2160, commit 103015a, dropped: no

{"commit":"103015a9ca66","dirty":false,"env":{"APS5_HOST_IMPORT_MIB":"6400","APS5_LAZY_SHADER_PREPARE":"1","APS5_NO_GPL":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_SECONDS":"960:30"},"gpu":"NVIDIA GeForce RTX 3070 Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26300","cpu":"AMD Ryzen 9 5900HS with Radeon Graphics","cpu_threads":16,"memory_mib":15776,"title_id":"PPSA01556","title":"Resident Evil Village","content_version":"01.210.000","resolution":"3840x2160","window":{"spec":"seconds 960:30","first_present":2901,"ms":31778.408},"presents":21,"frame_ms":{"p50":1497.603,"p90":1783.23,"p99":1903.699,"max":1903.699},"gpu_busy_ms_per_present":230.559,"worker_busy_pct":{"queue worker 0x0":99.554,"queue worker 0x38":0.057,"queue worker 0x28":93.25,"queue worker 0x20":89.065},"top_phases_ms_per_frame":{"Driver.Packet":4261.674,"Driver.Packet.memory_wait":2505.215,"Driver.Packet.draw":1156.599,"Driver.Draw":1155.503,"Graphics.Draw":928.353,"Graphics.Draw.draw_and_resource_release":907.06,"Driver.Packet.dispatch":560.368,"Driver.Dispatch":510.148},"trace_dropped":false,"trace":"aps5-trace-103015a9ca66-33724.json.gz"}

Slowest frames (largest slices inside each, inclusive)

  • present 2907: 1903.7 ms at 9350 ms: Driver.WorkerWait (queue worker 0x38) 1903.0, Driver.WorkerWait.dequeue_order (queue worker 0x38) 1897.0, Driver.Packet (queue worker 0x0) 1885.3, Driver.Packet (queue worker 0x28) 1785.2
  • present 2908: 1831.4 ms at 11253 ms: Driver.WorkerWait (queue worker 0x38) 1828.9, Driver.WorkerWait.dequeue_order (queue worker 0x38) 1818.7, Driver.Packet (queue worker 0x0) 1812.5, Driver.Packet (queue worker 0x28) 1746.7
  • present 2921: 1783.2 ms at 29995 ms: Driver.Packet (queue worker 0x0) 1764.7, Driver.Packet (queue worker 0x28) 1682.4, Driver.Packet.memory_wait (queue worker 0x28) 1663.5, Driver.Packet (queue worker 0x20) 1600.6
  • present 2901: 1750.5 ms at 0 ms: Driver.Packet (queue worker 0x0) 1728.6, Driver.Packet (queue worker 0x20) 1566.8, Driver.Packet (queue worker 0x28) 1505.2, Driver.Packet.memory_wait (queue worker 0x28) 1486.6
  • present 2904: 1743.3 ms at 4870 ms: Driver.WorkerWait (queue worker 0x38) 1742.3, Driver.WorkerWait.dequeue_order (queue worker 0x38) 1736.4, Driver.Packet (queue worker 0x0) 1724.7, Driver.Packet (queue worker 0x28) 1658.1

Threads (ms per frame)

thread busy wait untraced in slices < 20 us largest
queue worker 0x0 1057.9 (70 %) 442.5 (29 %) 12.9 90.7 Driver.Packet 1496.1, Vulkan.Dispatch 0.0
draw committer 660.4 (44 %) 40.9 (3 %) 811.9 4.9 Graphics.Draw 675.0, Recorder.Submit 2.1
presenter 3.3 (0 %) 0.3 (0 %) 1509.7 0.1 VideoOut.Flip 3.2, Driver.Present 0.4
queue worker 0x38 0.7 (0 %) 1344.4 (89 %) 168.1 0.9 Driver.Packet 0.7, Driver.EndSubmission 0.1
queue worker 0x28 18.2 (1 %) 1483.2 (98 %) 11.9 0.2 Driver.Packet 1410.6, Driver.EndSubmission 0.5
queue worker 0x20 129.1 (9 %) 1374.5 (91 %) 9.7 4.9 Driver.Packet 1343.2, Driver.EndSubmission 4.0
gpu 242.4 (16 %) 0.0 (0 %) 1270.9 0.0 batch 242.4

Largest slices (ms per frame, inclusive, all threads): Driver.Packet 4250.6, Driver.Packet.memory_wait 2505.1, Driver.WorkerWait 1594.9, Driver.WorkerWait.dequeue_order 1338.7, Driver.Packet.draw 1155.6, Driver.Draw 1154.5, Graphics.Draw 927.6, Graphics.Draw.draw_and_resource_release 906.3, Driver.Packet.dispatch 559.1, Driver.Dispatch 508.7

Longest waits

  • Driver.WorkerWait (queue worker 0x38) 1903.8 ms at 9351 ms, present 2907
  • Driver.WorkerWait (queue worker 0x38) 1827.9 ms at 11257 ms, present 2908
  • Driver.WorkerWait (queue worker 0x38) 1742.4 ms at 4872 ms, present 2904
  • Driver.WorkerWait (queue worker 0x38) 1707.2 ms at 28288 ms, present 2920
  • Driver.WorkerWait (queue worker 0x38) 1652.5 ms at 26635 ms, present 2919
  • Driver.Packet.memory_wait (queue worker 0x28) 1639.3 ms at 9478 ms, present 2907
  • Driver.Packet.memory_wait (queue worker 0x28) 1577.3 ms at 11410 ms, present 2908
  • Driver.WorkerWait (queue worker 0x38) 1564.9 ms at 1753 ms, present 2902
  • Driver.WorkerWait (queue worker 0x38) 1552.0 ms at 3319 ms, present 2903
  • Driver.WorkerWait (queue worker 0x38) 1542.0 ms at 13086 ms, present 2909

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

  • batch 427: 41.7 ms at 11426 ms, present 2908: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 3.0, Driver.Packet.dispatch (queue worker 0x0) 2.6, Driver.Dispatch (queue worker 0x0) 2.5, Vulkan.DispatchRecipe (queue worker 0x0) 1.3
  • batch 1139: 41.4 ms at 28443 ms, present 2920: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 2.2, Driver.Packet.dispatch (queue worker 0x0) 2.0, Driver.Dispatch (queue worker 0x0) 1.9, Vulkan.DispatchRecipe (queue worker 0x0) 0.4
  • batch 897: 41.4 ms at 22580 ms, present 2916: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 1.8, Driver.Packet.dispatch (queue worker 0x0) 1.5, Driver.Dispatch (queue worker 0x0) 1.5, Vulkan.DispatchRecipe (queue worker 0x0) 0.7
  • batch 779: 41.3 ms at 19993 ms, present 2914: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 0.6, Driver.Packet.dispatch (queue worker 0x0) 0.4, Driver.Dispatch (queue worker 0x0) 0.4, Vulkan.DispatchRecipe (queue worker 0x0) 0.3
  • batch 955: 41.3 ms at 24025 ms, present 2917: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 0.2, Driver.Packet.flush_between_packets (queue worker 0x0) 0.1, Driver.Packet.dispatch (queue worker 0x0) 0.1, Recorder.Submit (queue worker 0x0) 0.1
trace_digest.py of B (07f624d)

seconds 960:30 from present 1815: 19 presents, frame p50 1438.8 / p90 2203.1 / p99 2511.8 / max 2511.8 ms, GPU busy 255.7 ms per present
NVIDIA GeForce RTX 3070 Laptop GPU, NVIDIA 617.42, Windows 10.0.26300, 3840x2160, commit 07f624d, dropped: no

{"commit":"07f624d854fb","dirty":false,"env":{"APS5_HOST_IMPORT_MIB":"6400","APS5_LAZY_SHADER_PREPARE":"1","APS5_NO_GPL":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_SECONDS":"960:30"},"gpu":"NVIDIA GeForce RTX 3070 Laptop GPU","driver":"NVIDIA 617.42","os":"Windows 10.0.26300","cpu":"AMD Ryzen 9 5900HS with Radeon Graphics","cpu_threads":16,"memory_mib":15776,"title_id":"PPSA01556","title":"Resident Evil Village","content_version":"01.210.000","resolution":"3840x2160","window":{"spec":"seconds 960:30","first_present":1815,"ms":30085.902},"presents":19,"frame_ms":{"p50":1438.787,"p90":2203.059,"p99":2511.784,"max":2511.784},"gpu_busy_ms_per_present":255.744,"worker_busy_pct":{"queue worker 0x0":94.143,"queue worker 0x38":0.263,"queue worker 0x28":87.619,"queue worker 0x20":83.028},"top_phases_ms_per_frame":{"Driver.Packet":4195.016,"Driver.Packet.memory_wait":2410.236,"Driver.Packet.draw":1091.817,"Driver.Draw":1090.727,"Graphics.Draw":809.924,"Graphics.Draw.draw_and_resource_release":788.767,"Driver.Packet.dispatch":649.726,"Driver.Dispatch":595.737},"trace_dropped":false,"trace":"aps5-trace-07f624d854fb-36204.json.gz"}

Slowest frames (largest slices inside each, inclusive)

  • present 1818: 2511.8 ms at 5778 ms: Driver.WorkerWait (queue worker 0x38) 2508.9, Driver.WorkerWait.dequeue_order (queue worker 0x38) 2501.5, Driver.Packet (queue worker 0x0) 2491.6, Driver.Packet (queue worker 0x28) 2380.0
  • present 1815: 2203.1 ms at 0 ms: Driver.Packet (queue worker 0x0) 608.2, Driver.Packet.dispatch (queue worker 0x0) 547.6, Driver.Dispatch (queue worker 0x0) 522.9, GpuMutex.wait.dispatch (queue worker 0x0) 315.3
  • present 1817: 2086.2 ms at 3691 ms: Driver.WorkerWait (queue worker 0x38) 2085.5, Driver.WorkerWait.dequeue_order (queue worker 0x38) 2080.5, Driver.Packet (queue worker 0x0) 2065.6, Driver.Packet (queue worker 0x28) 1986.3
  • present 1831: 1957.3 ms at 25030 ms: Driver.WorkerWait (queue worker 0x38) 1956.2, Driver.WorkerWait.dequeue_order (queue worker 0x38) 1950.6, Driver.Packet (queue worker 0x0) 1938.5, Driver.Packet (queue worker 0x28) 1850.0
  • present 1827: 1891.9 ms at 18993 ms: Driver.WorkerWait (queue worker 0x38) 1890.6, Driver.WorkerWait.dequeue_order (queue worker 0x38) 1884.8, Driver.Packet (queue worker 0x0) 1875.6, Driver.Packet (queue worker 0x28) 1806.1

Threads (ms per frame)

thread busy wait untraced in slices < 20 us largest
queue worker 0x0 1089.9 (69 %) 401.2 (25 %) 92.4 85.7 Driver.Packet 1480.6, Recorder.Sync 3.7
draw committer 628.2 (40 %) 45.0 (3 %) 910.2 4.5 Graphics.Draw 640.6, Recorder.Submit 3.9
presenter 25.9 (2 %) 4.6 (0 %) 1553.0 0.1 VideoOut.Flip 22.4, Driver.Present 8.0
queue worker 0x38 3.9 (0 %) 1383.6 (87 %) 195.9 0.8 Driver.Packet 3.9, Driver.EndSubmission 0.1
queue worker 0x28 26.2 (2 %) 1441.4 (91 %) 115.8 0.2 Driver.Packet 1386.8, Driver.EndSubmission 0.5
queue worker 0x20 141.6 (9 %) 1348.7 (85 %) 93.2 4.6 Driver.Packet 1312.8, Vulkan.Dispatch 7.3
gpu 233.5 (15 %) 0.0 (0 %) 1350.0 0.0 batch 233.5

Largest slices (ms per frame, inclusive, all threads): Driver.Packet 4184.1, Driver.Packet.memory_wait 2410.1, Driver.WorkerWait 1639.1, Driver.WorkerWait.dequeue_order 1381.6, Driver.Packet.draw 1090.9, Driver.Draw 1089.8, Graphics.Draw 809.3, Graphics.Draw.draw_and_resource_release 787.9, Driver.Packet.dispatch 648.6, Driver.Dispatch 594.5

Longest waits

  • Driver.WorkerWait (queue worker 0x38) 2509.4 ms at 5781 ms, present 1818
  • Driver.WorkerWait (queue worker 0x38) 2085.3 ms at 3693 ms, present 1817
  • Driver.Packet.memory_wait (queue worker 0x28) 2056.8 ms at 5941 ms, present 1818
  • Driver.WorkerWait (queue worker 0x38) 1956.1 ms at 25031 ms, present 1831
  • Driver.WorkerWait (queue worker 0x38) 1890.8 ms at 18995 ms, present 1827
  • Driver.Packet.memory_wait (queue worker 0x28) 1816.0 ms at 3845 ms, present 1817
  • Driver.Packet.memory_wait (queue worker 0x28) 1689.8 ms at 25170 ms, present 1831
  • Driver.Packet.memory_wait (queue worker 0x28) 1650.0 ms at 19134 ms, present 1827
  • Driver.Packet.memory_wait (queue worker 0x20) 1637.9 ms at 5908 ms, present 1818
  • Driver.Packet.memory_wait (queue worker 0x20) 1602.1 ms at 3808 ms, present 1817

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

  • batch 694: 41.9 ms at 19138 ms, present 1827: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 3.0, Driver.Packet.dispatch (queue worker 0x0) 2.0, Driver.Dispatch (queue worker 0x0) 1.9, Driver.Packet.flush_between_packets (queue worker 0x0) 1.0
  • batch 95: 41.8 ms at 3861 ms, present 1817: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 0.2, Driver.Packet.dispatch (queue worker 0x0) 0.1, Driver.Dispatch (queue worker 0x0) 0.1, Driver.Packet.flush_between_packets (queue worker 0x0) 0.1
  • batch 569: 41.6 ms at 16447 ms, present 1825: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 0.1, Driver.Packet.dispatch (queue worker 0x0) 0.1, Driver.Dispatch (queue worker 0x0) 0.1, Driver.Packet.flush_between_packets (queue worker 0x0) 0.1
  • batch 935: 41.6 ms at 25173 ms, present 1831: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 1.7, Driver.Packet.dispatch (queue worker 0x0) 1.5, Driver.Dispatch (queue worker 0x0) 1.4, Vulkan.DispatchRecipe (queue worker 0x0) 0.5
  • batch 159: 41.6 ms at 5964 ms, present 1818: GPU no ranges; recorded by Driver.Packet (queue worker 0x0) 474.3, Driver.Packet.draw (queue worker 0x0) 461.8, Driver.Draw (queue worker 0x0) 461.4, Driver.Draw.draw_enqueued (queue worker 0x0) 154.9
- **The self-check, in Village:** one boot to menu +15 with `APS5_VERIFY_UNTRACKED_PROOFS=1`. After every fast proof that accepted a surface over untracked memory by its stamp, hinted or epoch, the full walk ran too. - **The result:** 38,000 such proofs were checked, from boot through the menu, and **0 disagreed**. That's all 38 of its `[verify-untracked]` lines; the last reads `38000 fast proofs over untracked memory checked by the full walk, 0 disagreed`. - **How it was built:** the boot was a diagnostic build of this change that prints the count every 1,000 checks instead of every 100,000. - **Not a speed figure:** the self-check's extra walks slow the boot.

Grand Theft Auto V (PPSA04263), by @chitters2004

On Windows 11, a Ryzen 7 5800X and an RTX 3080 (driver 621.01), with the same machine, scene and save in both arms.

Grand Theft Auto V (PPSA04264), by @Nesyth

Windows 11 Pro 26300, a Radeon RX 7900 XTX (AMD Software 26.10.1), a Ryzen 7 7800X3D, 3840x2160 output. Version 01.011.001 in the Performance graphics mode, gameplay of the opening level with warm caches (comment). The arms are main 9090972 and the same commit with this PR's head 793fc7f merged, so the second carries #6192's four commits as well as this PR's. Each run is a separate boot, and FPS is the window title's counter over 57 s of scripted gameplay.

Tested

  • agc_untracked_hint_proof (new), with two sampled 64 KiB surfaces over write-watched, host-imported, then unwatched memory:
    • Red/green: after a collect epoch with no write, the proof is fast exactly when the block has a hint.
    • Controls: a CPU store after a bump; a MarkWritten driver store; a recorded GPU write note, before and after the write is reaped; and a CPU store made after the hint is sampled but before the stamp is recorded, through a flush hook.
    • Each control must walk and take the new content, and settle re-proves the stamps after each one. No case asserts a throw.
  • Red/green on Windows (RTX 3070 Laptop, driver 617.42, Windows 10.0.26300):
  • Linux (lavapipe, Ubuntu 24.04, GCC 13.3, Release, CI's flags), on this head's tree:
    • agc_untracked_hint_proof, agc_untracked_revalidate and agc_untracked_forget passed 20 of 20 each. Linux has no hints, so the new test runs there under the epoch rule and checks that nothing changes.
    • ctest -R '^agc' --parallel 4: 1,119 tests: 1,046 passed, 73 skipped, 0 failed.
    • Without the teardown fix, agc_untracked_forget crashes on lavapipe 20 of 20 times.
  • Checks: check_conventions.py and check_test_registration.py pass. MinGW-w64 -fsyntax-only adds no errors or warnings to main's. Nothing under core/shader/** changes, so the shader cache key is unchanged.
  • GitHub, ×10, with the Khronos validation comparison on Linux (run). The comparison arm is perf(agc): fast revalidation over untracked memory proves a surface by its stamp until the next ordering point #6192 merged with main plus the teardown fix (e440b74), so it differs from this head only by the hint key.
    • Linux: agc_untracked_hint_proof, agc_untracked_revalidate and agc_untracked_forget passed 10 of 10 under validation.
    • Linux ^agc under validation: 1,119 run, 73 skipped, 1 failed. The failure is agc_driver_image_table, whose only validation message is VUID-VkDeviceCreateInfo-pNext-pNext from vkCreateDevice ("unknown VkStructureType (1000574000) ... version 275 of the Vulkan header"). That's the runner's validation layer being older than the headers. The comparison arm fails that test the same way, and the change adds no VUID.
    • Windows runner: 1,144 run, 812 skipped, 0 failed. The three tests skip there, because the runner has no Vulkan device, so on Windows this is a build and no-crash check. The device evidence for Windows is the RTX 3070 red/green above. It ran on the same library lines as this head; only the test-only teardown fix is newer.
    • Suites: the libc and libkernel suites, run with APS5_SKIP_TIMING_TESTS=1, pass: 191 and 291 on Linux, 220 and 314 on Windows.
    • agc_driver_image_table without the validation layer (run 40890382693) passes on both sides. On Linux, it ran with the branch's 78 tests: 71 passed, 7 skipped, 0 failed. On Windows, 94 ran, 4 passed and 90 skipped, since the runner has no device. The suites match the run above.
  • 31dff93, a merge of main 673fa86, which brings johandavidcm's feat(agc): count why a template's collect was refused #11550 (run).
  • 2b74a6c, cross-thread cases (test-only).
    • agc_untracked_hint_proof gains three cases:
      • another thread stores right after the first surface's compare, from inside the flush hook;
      • another thread stores after a fast proof;
      • the check itself runs on another thread.
    • agc_write_tracking gains a device-free case on Windows:
      • a store from one thread is seen by another thread's walk;
      • the stamps are shared, so a thread still in its old epoch reads the newer hint, and so does the next epoch;
      • a writer races across 50 epochs.
    • Green on Windows (RTX 3070 Laptop, driver 617.42):
      • agc_untracked_hint_proof, agc_untracked_revalidate, agc_untracked_forget and agc_write_tracking pass 10 of 10 each.
      • The hint proof printed "the block has a write-watch hint" in all 10 runs, so the hinted path ran.
      • agc_write_tracking alone passes 20 of 20.
    • GitHub, ×10 (run):
      • Linux: 79 run, 71 pass, 8 skip, 0 fail.
      • Windows: 102 run, 12 pass, 90 skip (no Vulkan device), 0 fail. agc_write_tracking's device-free cases run there.
      • The libc and libkernel suites run 194 and 294 tests on Linux and 224 and 317 on Windows, with 0 failed. The suites ran with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.
    • Red, with the UntrackedHint memo made to ignore the collect epoch (a measurement branch, not part of this PR):
      • On the RTX 3070, agc_write_tracking fails with "the last store of a racing thread did not move the hint past every value read before it", and agc_untracked_hint_proof fails at its existing step, "a CPU store after a collect epoch kept the fast proof".
      • On GitHub (run), Windows fails agc_write_tracking with the same message, and agc_untracked_hint_proof skips there. Linux passes: it has no write-watch hints, so its ranges keep the epoch stamp.
    • Taking the hint after the compare has no deterministic red. The only hook in that path runs before both reads.
  • 23ef222, a merge of main 8304cca (run).
    • The conflict: one line in CMakeLists.txt, the Windows ENVIRONMENT_MODIFICATION test list, where fix(agc): free a completed batch's command buffer instead of keeping it #9565 adds agc_recorder_command_buffer_release. The resolution is the union of both sides' names, each once.
    • This PR's own lines are unchanged. The only difference in its diff is that list line, which now carries main's new name.
    • ×10: the ^agc_untracked_ tests, agc_write_tracking, agc_driver_recorder and main's agc_recorder_command_buffer_release.
      • Linux: 81 run, 73 pass, 8 skip, 0 fail.
      • Windows: 104 run, 12 pass, 92 skip (no Vulkan device), 0 fail.
      • The libc and libkernel suites run 198 and 307 tests on Linux and 225 and 327 on Windows, with 0 failed. The suites ran with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.
  • 8bee4ca, a merge of main 0836dfd (run). build(agc): register each AGC test executable in its own CMake fragment #12862 moved libSceAgcDriver's test registrations into tests/cmake/; the conflict in CMakeLists.txt is resolved with tools/agc_test_split.py resolve, which moves this PR's registrations into tests/cmake/agc_driver_recorder_tests.cmake (+7 −1). Nothing else conflicted. Apart from the move, this PR's diff is unchanged. With -DBUILD_TESTING=ON, ctest -N gives 3078 tests: main's 3075 plus its 3 tests, each listed once. agc_driver_recorder, agc_recorder_command_buffer_release, agc_untracked_forget, agc_untracked_hint_proof, agc_untracked_revalidate, agc_write_tracking pass 10 runs in a row. Linux: 6 run, 6 pass, 0 skip, 0 fail. Windows: 6 run, 1 pass, 5 skip (no Vulkan device), 0 fail. Suites: libc and libkernel pass on Linux (199 and 308) and on Windows (226 and 330). The suites ran with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.
  • 793fc7f, the untracked proof tests report a skip when they can't run, for oneandonlydean's review (test-only, tests/Recorder.cpp). untrackedForgetTests, untrackedRevalidateTests and untrackedHintProofTests return false at each of their 10 early outs and true at the end, and their --untracked-*-only branches return ? 0 : 77, as SKIP_RETURN_CODE 77 expects.
    • ×10 (run): Linux: 3 run, 3 pass, 0 skip, 0 fail. Windows: 3 run, 0 pass, 3 skip (no Vulkan device), 0 fail. The libc and libkernel suites run 199 and 308 tests on Linux and 226 and 330 on Windows, with 0 failed. The suites ran with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.
    • The new skips aren't reached on GitHub's runners: Linux runs all three in full at both heads (before), and Windows skips the binary before them at both heads.
  • AMD Radeon RX 6300 (RADV NAVI24, Mesa 25.2.8) at 793fc7f, from TechLevelZero's AMD bot (report): this head merged onto main 291e02d, Ubuntu 26.04.1, 2,540 of 3,155 tests selected.
    • 2,477 passed, 9 failed and 54 skipped. None of the failures is new: all 9 also fail on main.
    • With VK_LAYER_KHRONOS_validation, no new validation IDs over 934 GPU tests. agc_untracked_forget, agc_untracked_revalidate and agc_untracked_hint_proof passed on the GPU, so they ran in full there, since this head reports 77 when they can't. They aren't in main's baseline, so their validation wasn't compared.
  • NVIDIA RTX 2000 Ada Generation at 793fc7f, from TechLevelZero's NVIDIA bot (report): this head merged onto main e6f5730, driver 595.99.02, Ubuntu 26.04.1, 2,535 of 3,148 tests selected.
    • 2,484 passed, 6 failed and 45 skipped. None of the failures is new: 3 also fail on main, and 3 are unstable on main.
    • With VK_LAYER_KHRONOS_validation, no new validation IDs over 934 GPU tests. The three agc_untracked_* tests passed on the GPU, so they ran in full there too. They aren't in main's baseline, so their validation wasn't compared.
  • 38dc520, oneandonlydean's merge of main f6232fc. It resolves the conflicts in ShaderResources.hpp and tests/cmake/agc_driver_recorder_tests.cmake. This PR's own lines are unchanged. The only difference in its diff is the Windows ENVIRONMENT_MODIFICATION list line, which now carries main's agc_window_import_unmap.
    • NVIDIA RTX 2000 Ada Generation at 38dc520, from TechLevelZero's NVIDIA bot (report): this head merged onto main f6232fc, driver 595.99.02, Ubuntu 26.04.1, 2,795 of 3,743 tests selected. 2,740 passed, 6 failed and 49 skipped. None of the failures is new: 3 also fail on main, and 3 are unstable on main. With VK_LAYER_KHRONOS_validation, no new validation IDs over 937 GPU tests.
  • 8468301, a merge of main 4f41f4c (run).
    • The conflicts: two, each resolved by keeping both sides. In Texture.hpp, main's new OccasionalLabelStores declaration and this PR's HintedComparison declaration are adjacent, and both stay. In tests/cmake/agc_driver_recorder_tests.cmake, the Windows ENVIRONMENT_MODIFICATION list, where main adds agc_changed_copy, the resolution is the union of both sides' names, each once. This PR's own lines are unchanged, and that list line is the only difference in its diff.
    • ×10: agc_changed_copy, agc_recorder_read_list and every test matching ^agc_untracked or ^guest_memory. Linux: 9 run, 9 pass, 0 skip, 0 fail. Windows: 8 run, 3 pass, 5 skip (no Vulkan device), 0 fail. The libc and libkernel suites run 300 and 322 tests on Linux and 327 and 342 on Windows, with 0 failed. The suites ran with APS5_SKIP_TIMING_TESTS=1, which relaxes precise_wait's median bounds on GitHub's hosted runners.

Checklist

TheAggie and others added 8 commits October 15, 2026 10:07
…is forgotten

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y its stamp until the next ordering point

APS5_VERIFY_UNTRACKED_PROOFS=1 runs the full walk beside every such proof and counts disagreements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n a collect epoch

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

The test's last refresh records a detile dispatch that is still pending
when the function returns. The detiler, declared after the Unregister
guard, was destroyed first, freeing the pipeline and descriptor pools
that dispatch uses; Unregister then removed the allocations, which syncs
the recorder, and lavapipe executed the dispatch with the freed pipeline
and crashed on its queue thread.

Sync the recorder before the detiler goes away, as the neighbouring
untracked tests already do.
@github-actions github-actions Bot added the perf Performance change label Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 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 6108 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L2647
PR 9875 core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake L418
PR 12575 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp L1033-1072, L1135-1136

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 1368 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 1395 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 1896 docs/dev/ENVIRONMENT.md
PR 4472 docs/dev/ENVIRONMENT.md
PR 5021 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 5609 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5925 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6186 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 6187 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6192 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6194 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6197 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6209 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6223 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6280 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6340 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6412 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6481 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6804 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6924 docs/dev/ENVIRONMENT.md
PR 7002 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7085 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
PR 7256 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7449 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
docs/dev/ENVIRONMENT.md
PR 7457 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
docs/dev/ENVIRONMENT.md
PR 7514 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/ENVIRONMENT.md
PR 7604 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
docs/dev/ENVIRONMENT.md
PR 7689 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8004 docs/dev/ENVIRONMENT.md
PR 8246 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/ENVIRONMENT.md
PR 8484 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
docs/dev/ENVIRONMENT.md
PR 8707 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 9012 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 9289 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 9318 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9345 docs/dev/ENVIRONMENT.md
PR 9356 docs/dev/ENVIRONMENT.md
PR 9387 docs/dev/ENVIRONMENT.md
PR 9592 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9712 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
docs/dev/ENVIRONMENT.md
PR 9852 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 9897 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9898 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 10049 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 10193 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 10249 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 10256 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 10442 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
docs/dev/ENVIRONMENT.md
PR 10757 docs/dev/ENVIRONMENT.md
PR 10894 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 10920 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 11351 docs/dev/ENVIRONMENT.md
PR 11435 docs/dev/ENVIRONMENT.md
PR 11436 docs/dev/ENVIRONMENT.md
PR 11485 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 11551 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 12070 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 12323 docs/dev/ENVIRONMENT.md
PR 12324 docs/dev/ENVIRONMENT.md
PR 12746 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/ENVIRONMENT.md
PR 12848 docs/dev/ENVIRONMENT.md
PR 12863 docs/dev/ENVIRONMENT.md
PR 12895 docs/dev/ENVIRONMENT.md
PR 12930 docs/dev/ENVIRONMENT.md
PR 12970 docs/dev/ENVIRONMENT.md
PR 13486 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/WriteTracking.cpp
docs/dev/ENVIRONMENT.md
PR 13707 docs/dev/ENVIRONMENT.md
PR 13793 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 13796 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 13809 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 13863 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 13920 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 13928 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 13929 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 14032 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 14235 docs/dev/ENVIRONMENT.md
PR 14264 docs/dev/ENVIRONMENT.md
PR 14299 docs/dev/ENVIRONMENT.md
PR 14344 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
docs/dev/ENVIRONMENT.md
PR 14943 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/ENVIRONMENT.md
PR 14944 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 15059 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 15136 core/libs/prx/libSceAgcDriver/Execution/include/GuestMemory.hpp
core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md
PR 15169 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
docs/dev/ENVIRONMENT.md

@EagleBearerYS
EagleBearerYS marked this pull request as ready for review October 29, 2026 15:11
@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head fdc7004 merged onto main ba5b533 · tested 2026-10-29 15:42 UTC · 23 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,289 passed · 6 failed (0 new, 5 also fail on main, 1 unstable on main) · 39 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,334 of 2,891 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 (897 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_bda_device 61.6 s, ⚠️ agc_driver_pipeline_journal 54.0 s
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_submit_progress: failed in 3 of the last 5 main runs
Failing on main too (5, not counted against this PR)
agc_compute_pipeline_inspection
agc_submit_progress
agc_submit_progress_no_timeline
guest_mmap_executable
guest_socket_options_multicast
Validated but not compared (3, not in the main baseline's validation pass)
agc_untracked_forget
agc_untracked_hint_proof
agc_untracked_revalidate
Validation IDs already present on main (4 IDs in 436 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (436 tests): agc_compute_pipeline_replay, agc_driver, agc_driver_address_passes_draw_transitions, agc_driver_address_passes_targets_split, agc_driver_alias_copy_label, agc_driver_array_layer_target, agc_driver_array_layer_target_cpu, agc_driver_bda_anchor_reads, and 428 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 (39)
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_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_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 platform
video_out_flip_labels: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SD
Reproduce
git fetch origin fdc70046f8fca66d37bcb9ce0410db88f283b816 ba5b5330b37724bca4b99f30faab504653635a04
git checkout ba5b5330b37724bca4b99f30faab504653635a04 && git merge --no-ff fdc70046f8fca66d37bcb9ce0410db88f283b816
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.

@chitters2004

Copy link
Copy Markdown
Contributor

GTA V (PPSA04263, 01.011.001) on Windows: no FPS change at story start, and 0 disagreements in the proof self-check. GTA's collect fast-fails are almost all on ranges with no write-watch hint, so the hint key doesn't apply to them.

Setup

Results (FPS)

Arm Run 1 Run 2 Run 3 Mean
#6192 12.33 12.65 12.82 12.60
#6192 + this PR 12.27 12.52 12.15 12.31

The difference is inside the run-to-run spread.

Why (local counters, not part of either PR)

  • With this PR, [rescache] revalidate still shows about 21.7k collect fast-fails per 10 s, against about 135k fast proofs.
  • I split those failures by the recorded stamp's kind and its first differing field.
    • All of them are sampled-texture surfaces whose stamp is the epoch kind, meaning UntrackedHint returned 0 at capture, and they fail because the epoch moved.
    • There were no hinted-stamp failures, no storage-image failures and no missing stamps.
    • GTA advances about 35 collect epochs a second here.
  • So in GTA the untracked surfaces are in memory where tracker.hinted() is false.
  • Adding perf(agc): exclude only an import's own pages from the write watch and settle partial-block imports in the background #12378 on top reduces those failures to about 16.4k per 10 s. The FPS change stays inside the noise: 12.52 vs 12.40 over three runs each.

Correctness

AI-assisted (Claude Code). All numbers come from runs on the machine above.

@CnRJay CnRJay 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 measurement does not isolate this change, and the fast path it extends gets more expensive per proof. Neither point is addressed in the description.

1. The +29.9 % is #6192 plus this PR. The description says so: "#6192 alone wasn't run". The branch carries #6192's four commits, #6187 under them, and a merge of main, so an unrelated diff of about 450 lines is reviewed as one PR. The arms are 4 runs of 0.51–0.83 fps with a 19–25 % spread inside each arm. B ahead of A by 30 % on two runs per arm is not distinguishable from the spread. The only independent run so far is chitters2004's GTA V one above (12.60 vs 12.31 fps, inside the noise), and it says the fast-fails there are on ranges with no hint, where this change does not apply. Please run main + #6192 against main + #6192 + this PR on the Village menu, same machine and scene, with tools/trace_digest.py summaries of both. That is the only comparison that measures this PR.

2. The proof now does more work per surface. For an untracked surface, currentUntrackedStamp calls hintedProof: UntrackedHint, NewestStamp, ForgetStamp and NewestWriteNote. ForgetStamp, which this branch carries from #6192, loops over every 64 KiB block of the range with an acquire load per block. A 3840x2160 RGBA16F target is about 66 MB, which is about 1,000 loads per call, per surface, per proof. GTA shows about 135k fast proofs per 10 s, and each proof can hold several untracked surfaces. The fast path exists because it is cheaper than the full walk; with #6192's loop it costs O(range size) per surface instead of O(1). Keep a single global counter that the forget path bumps, and use the per-block slots only when that counter has moved. Or show the proof cost in the trace.

3. Correctness depends on the hint being up to date. The description says "a store into it moves the hint at the next walk of that page's marks". Between two ordering points no walk happens, so a CPU store after the compare is only visible if something walks those marks before the next check. Please say what guarantees a walk between the compare and the next check on a surface nobody reads through CollectWrites. APS5_VERIFY_UNTRACKED_PROOFS covers the runs listed, but a title that rewrites an untracked surface once per frame from the CPU would show a stale texture instead of a slow frame. The new test would need a case that stores into the range from another thread right after the compare.

4. Smaller points.

  • The "where it comes from" numbers use APS5_PROFILE_DRAW=1. The Performance report form does not accept those for a speed claim. They are fine as explanation, but the claim needs the aps5-summary.jsonl figures from item 1.
  • On Linux and for unhinted ranges nothing changes, so the PR is Windows-only in effect. Say that in the title or in What.
  • "A new storage image has no hinted entry until its first equal compare" means a freshly created image pays the full walk once per recreation. If the title recreates targets per scene change, that cost should be in the numbers too.

@chitters2004

Copy link
Copy Markdown
Contributor

@CnRJay, on point 2, with the proof cost measured on GTA V instead of estimated.

Where the loop comes from. ForgetStamp and its per-block loop come from #6192 (015bd22678), not from this PR. On #6192 every fast check of an untracked surface already calls it through untrackedRangeStamp. What this PR adds per proof is hintedProof, and currentUntrackedStamp calls it only when the recorded stamp is the hinted kind (recorded[4] != 0). An unhinted surface pays nothing new; a hinted one pays UntrackedHint (the tracker lock) and then the stamp reads the epoch stamp would have done.

Measured. I timed each currentUntrackedStamp call and split the checks by stamp kind (local counters, not part of either PR). Setup as in my run above: main 52c09d5 + #11580 + #6192's commits + this PR's fdc70046f8, Windows, RTX 3080, Ryzen 7 5800X. Nine consecutive 10 s intervals at story start in the North Yankton prologue. The times include the clock reads around each call, a few tens of ns.

Per 10 s Epoch stamp (#6192) Hinted stamp (this PR)
Checks 32,211–38,851 8,729–10,515
Passed 52.6–53.3 % 100 % (0 failures in these intervals)
64 KiB blocks per check, mean 8.4 1.17
Time per check, mean 210–230 ns 1,040–1,143 ns
Total per 10 s 7.2–8.5 ms 10.0–11.2 ms
  • My earlier note was about the failing proofs, which are all epoch-kind. The passing ones include about 10k hinted proofs every 10 s, so this change does apply in GTA, and every one of them passed.
  • They cost about 5× an epoch check while touching a seventh of the blocks. The per-block loop isn't the hinted path's cost here; the lookup and lock in UntrackedHint are. On the title menus before Story, hinted checks over 7–10 blocks averaged 10–14 µs, which also points at the lookup rather than the loop.
  • Both kinds together cost about 17–20 ms per 10 s of CPU, about 0.15 ms per frame at this scene's 12.5 fps, which fits the FPS difference staying inside the noise. One run, one scene; it says nothing about a title with many more hinted surfaces.

On point 1, the GTA run above is that isolated comparison: #6192 against #6192 + this PR, same machine, scene and save, arms interleaved. tools/trace_digest.py over each run's aps5-summary.jsonl, the same 15 steady 10 s intervals in each:

Run FPS p50 ms p99 ms GPU busy ms
#6192 r1 / r2 / r3 12.30 / 12.61 / 12.78 80.5 / 78.4 / 77.4 89.3 / 89.1 / 86.3 36.3 / 36.2 / 36.2
+ this PR r1 / r2 / r3 12.24 / 12.48 / 12.12 80.7 / 79.3 / 81.7 91.8 / 88.3 / 92.6 36.0 / 36.2 / 36.1

The PR arm averages 2.2 % lower, and the ranges overlap. The measured proof cost above is about 0.2 % of an 80 ms frame, so it doesn't explain a 2 % gap if there is one. Three runs per arm can't separate that from noise. This is GTA, not the Village menu, so it doesn't replace the run you asked EagleBearerYS for.

Your global-counter idea would cut the epoch path's loop. For the hinted path, the cost to look at is UntrackedHint's lock. @EagleBearerYS, your call whether that belongs in this PR.

AI-assisted: yes (Claude Code)

@EagleBearerYS

Copy link
Copy Markdown
Contributor Author

@CnRJay, thanks for the close read. The answers are below, in the order 3, 2, 4, 1, with links at this head (fdc7004). @chitters2004, thank you for the Grand Theft Auto V runs and the timing by stamp kind.

3. What makes a store after the compare visible. The check walks the write-watch marks itself, so it doesn't depend on anyone else calling CollectWrites.

  • The call chain: a fast check of a hinted surface goes currentUntrackedStamp (ShaderResources.cpp L3069) → hintedProof (L3054) → GuestMemory::UntrackedHint (GuestMemory.cpp L2195).

  • The walk: UntrackedHint runs walkHints (L2215).

    • It reads the range's write-watch marks with reset, through GuestArenaCollectWrites_nid_postfix(..., true) (L2181).
    • It stamps each marked block's hint under the tracker mutex (L2184).
    • Then it returns the newest hint over the range.
  • So a CPU store after the compare is caught. It leaves a mark, and the next check's own walk turns that mark into a newer hint. The stamp no longer matches, and the proof falls back to the full walk.

  • The one case that skips the walk is the per-thread memo (L2208). A thread that has already walked the range in its current collect epoch reuses that walk.

  • Nothing else clears those marks.

    • collectWrites returns 0 for a range the tracker doesn't cover, before it walks anything (L1629).
    • hinted() requires every block of the range to be outside the covered set (L1071).
    • So walkHints is the only thing that resets a hinted page's marks, and it stamps them as it does.
  • At capture, StorageTexture::compareUntracked takes the hint, walk included (Texture.cpp L2615), before EqualsCommittedUnsynced (L2625). A store that races the compare leaves a mark for the next walk. At worst it costs one more full walk.

  • The test already covers a store between the compare and the stamp being recorded, on one thread.

    • storeDuringWalk (Recorder.cpp L5754) stores into the first surface from the flush hook while the second surface is compared.
    • The next epoch's proof must not be fast (L5895).
  • Three cross-thread cases are coming as a test(agc) commit on this PR, with red/green:

    • the same store, made on another thread inside the hook;
    • another thread storing after a fast proof;
    • the check itself running on another thread.

    A device-free version goes into agc_write_tracking, so that GitHub's Windows runner can run it too.

2. Cost per proof. chitters2004's measurement stands, and so does their point about where the loop comes from.

4. The smaller points.

1. The isolation pair is queued, on the same machine and scene as before.

@EagleBearerYS EagleBearerYS changed the title perf(agc): keep an untracked fast proof across collect epochs while its write-watch hint has not moved perf(agc): keep an untracked fast proof across collect epochs on Windows while its write-watch hint has not moved Oct 29, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 30, 2026
# Conflicts:
#	core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
@github-actions github-actions Bot added build docs agc libSceAgc* and removed needs rebase Conflicts with main, rebase needed labels Oct 30, 2026
The conflict in core/libs/prx/libSceAgcDriver/CMakeLists.txt from boykopovar#12862's split is resolved with tools/agc_test_split.py resolve, which moves this PR's test registrations into tests/cmake/.
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 31, 2026
@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head 8bee4ca merged onto main 0836dfd · tested 2026-10-31 23:51 UTC · 36 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,445 passed · 7 failed (0 new, 4 also fail on main, 3 unstable on main) · 44 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,496 of 3,087 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 (927 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_lookup_log_fits_build 66.6 s, ⚠️ agc_driver_pipeline_journal 59.6 s, ⚠️ agc_driver_graphics_maps_fallback 32.3 s, ⚠️ agc_driver_graphics 31.0 s
Intermittent validation messages (1, seen once in the parallel run, not reproduced when the test was re-run alone 2 times; not counted against this PR)
agc_driver_depth_clear_hle: VUID-vkCmdCopyBuffer-commonparent (6x)
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_depth_clear_hle: failed in 2 of the last 10 main runs
agc_submit_progress: failed in 7 of the last 10 main runs
agc_submit_progress_no_timeline: failed in 9 of the last 10 main runs
Failing on main too (4, not counted against this PR)
agc_driver_idle_store_yields
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validated but not compared (3, not in the main baseline's validation pass)
agc_untracked_forget
agc_untracked_hint_proof
agc_untracked_revalidate
Validation IDs already present on main (5 IDs in 476 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (476 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 468 more
VUID-vkCmdCopyImage-srcImage-01548 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_prepared_exports
VUID-VkShaderModuleCreateInfo-pCode-08737 (1 test): agc_driver_image_sample_derivatives
Skipped (44)
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_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_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 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 platform
video_out_f
Reproduce
git fetch origin 8bee4cadbf85a7be7fbe3f3d36e24f4ce84a3cb6 0836dfdf4fecb1e0326100c490476e15d3a74da5
git checkout 0836dfdf4fecb1e0326100c490476e15d3a74da5 && git merge --no-ff 8bee4cadbf85a7be7fbe3f3d36e24f4ce84a3cb6
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.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

@EagleBearerYS the change itself looks right to us: the per-block forget stamps only err on the side of comparing again, and the cross-thread hint test covers the race. One fix in the tests: agc_untracked_forget, agc_untracked_revalidate and agc_untracked_hint_proof are registered with SKIP_RETURN_CODE 77, but their --untracked-*-only branches in Recorder.cpp always return 0, and the subtests just print "... not tested" and return when host imports are unavailable, the import is refused or the memory stays write-watched. On such a machine ctest reports them as passed rather than skipped. Could you have the three functions return whether they ran and map that to 0 : 77, as vertexTargetRangeTests already does?

Also, this PR and #12745 both change Graphics/src/ShaderResources.cpp and conflict there; could you note on both which one lands first?

@EagleBearerYS

Copy link
Copy Markdown
Contributor Author

@oneandonlydean thanks. Done in 793fc7f:

  • The three tests: untrackedForgetTests, untrackedRevalidateTests and untrackedHintProofTests now return whether they ran: false at each of their 10 early outs, where they print "... not tested", and true at the end. The --untracked-*-only branches return X(device, recorder) ? 0 : 77, so a machine where they can't run shows them as skipped.
  • ×10 at 793fc7f (run):
    • Linux: 3 run, 3 pass, 0 skip, 0 fail.
    • Windows: 3 run, 0 pass, 3 skip (no Vulkan device), 0 fail.
  • Neither of GitHub's runners reaches the new skips. lavapipe on Linux has host imports, null descriptors and a write watch, so all three tests run in full at both heads (before). Windows has no Vulkan device, so the binary skips before it reaches them, at both heads too.
  • Merge order: perf(agc): prove cached image tables from a write index behind APS5_TABLE_INDEX #12745 first, then this PR, noted on both. This PR takes the second merge in ShaderResources.cpp, with the test-only update already on test/untracked-proof-index-on-12921.

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ AMD GPU test: passed

PR head 793fc7f merged onto main 291e02d · tested 2026-11-01 17:23 UTC · 14 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 ✅ 2,477 passed · 9 failed (0 new, 9 also fail on main) · 54 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,540 of 3,155 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 (934 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 88.2 s, ⚠️ agc_driver_graphics_maps_fallback 37.0 s, ⚠️ agc_driver_graphics 35.9 s, ⚠️ public_headers 30.2 s
Failing on main too (9, not counted against this PR)
agc_driver_guest_memory_lifetime_direct
agc_driver_image_table
agc_driver_native_depth_bda_clear
agc_driver_native_depth_buffer_clear
agc_driver_native_depth_clears
agc_driver_native_multisample_depth
agc_idle_publish_wait
guest_mmap_executable
guest_socket_options_multicast
Validated but not compared (3, not in the main baseline's validation pass)
agc_untracked_forget
agc_untracked_hint_proof
agc_untracked_revalidate
Validation IDs already present on main (5 IDs in 481 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (481 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 473 more
VUID-vkCmdCopyImage-srcImage-01548 (6 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (6 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_prepared_exports
VUID-VkShaderModuleCreateInfo-pCode-08737 (1 test): agc_driver_image_sample_derivatives
Skipped (54)
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_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_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_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: 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
Reproduce
git fetch origin 793fc7f8ea83a023d6944a5122e3964d61bce6a2 291e02d4877784d03d346962af51713b9df63b91
git checkout 291e02d4877784d03d346962af51713b9df63b91 && git merge --no-ff 793fc7f8ea83a023d6944a5122e3964d61bce6a2
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 793fc7f merged onto main e6f5730 · tested 2026-11-01 17:31 UTC · 18 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,484 passed · 6 failed (0 new, 3 also fail on main, 3 unstable on main) · 45 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,535 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 (934 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.1 s, ⚠️ agc_driver_graphics_maps_fallback 33.2 s, ⚠️ agc_driver_graphics 32.7 s, ⚠️ agc_driver_indirect_thread_dimensions 30.7 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
Validated but not compared (3, not in the main baseline's validation pass)
agc_untracked_forget
agc_untracked_hint_proof
agc_untracked_revalidate
Validation IDs already present on main (5 IDs in 484 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (484 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 476 more
VUID-vkCmdCopyImage-srcImage-01548 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_prepared_exports
VUID-VkShaderModuleCreateInfo-pCode-08737 (1 test): agc_driver_image_sample_derivatives
Skipped (45)
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_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_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 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_fps_limit: 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_o
Reproduce
git fetch origin 793fc7f8ea83a023d6944a5122e3964d61bce6a2 e6f57307fa7f47165d7fc1bee945abdb2f6816e7
git checkout e6f57307fa7f47165d7fc1bee945abdb2f6816e7 && git merge --no-ff 793fc7f8ea83a023d6944a5122e3964d61bce6a2
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.

chitters2004 pushed a commit to chitters2004/AnyPS5 that referenced this pull request Nov 2, 2026
The counter commit below reads APS5_COUNT_WALKS without a row in
docs/dev/ENVIRONMENT.md, which the conventions check refuses. This adds
the row. It goes with the counter and is not for a pull request either.
The report of this branch follows, as in the counter commit fb0be86.

Report (v2)

Branch draft/revalidate-walks-v2, based on upstream main 4ac683f.
Commits:
- 3e89f8a perf(agc): look up only the changed textures when a
  template's memory moved (unchanged from v1)
- 795405a perf(agc): fail a template on a released texture without
  the full walk (unchanged from v1)
- 3ac1c0d perf(agc): find a template's changed elements in one
  tracker query
- 983e273 perf(agc): relook changed elements from lookup recipes
  captured once
- this counter
v1's report (draft/revalidate-walks, aefbec8) still holds for every
reason a walk runs and for the relook and replaced arguments.

What each addition costs, per call and per frame:
- ChangedSince, proof passes: the same single tracker lock and one range
  check per query as UnchangedSinceAll, plus a clear of a thread-local
  vector and one branch per query. Nothing measurable per Revalidate.
- ChangedSince, 'memory changed': v1 took UnchangedSinceAll's lock, then
  one more lock, covers check and range check for each of Q queries to
  name the changed ones. Now one lock and Q range checks. That is Q lock
  round trips saved per failure. Calls per frame: the [walks] relook
  counts (same + differing + fell back).
- Recipes, capture: once per template, on its first relook. One pass
  over its bindings and table elements, which is what v1's relook did on
  every call, plus about 64 bytes per element held by the template.
- Recipes, each later relook: v1 re-enumerated all bindings and table
  elements (narrowing and null-checking every sampled descriptor) to
  reach k changed elements. Now k recipe reads, a sort of k entries by
  build order, and the k lookups. Calls per frame: as above.
- Neither adds work to a proof that passes.

Why the recipes are the walk's lookups:
- The walk derives each lookup from the bindings it is passed.
  ShaderResources::ContentKey puts every non-data binding's descriptor
  words, image shapes and compare bits into the cache key, so a template
  found under that key has its build's descriptors.
- The recipe holds those raw words. Sampled elements are narrowed by
  firstLayerWords at each lookup, as the walk does. Components and
  multisample view type are derived as the walk derives them. Storage
  elements keep the build's mip, written flag and dedupe (index - 1).
- Lookups run in the walk's order: bindings stage by stage, then tables.
- A layout the walk would refuse (no program, more than 8 words per
  element, a table index out of step, counts not matching textures[] or
  storageTextures[]) marks the recipes refused. Those templates take the
  full walk.

Conservative fallbacks, unchanged and tested:
- The relook starts only when 'memory changed' is the fast proof's sole
  failure. That check runs after the pending-registry, key and metadata,
  depth and cache checks.
- The rerun repeats all of those.
- Import identity, the serial loop and staging checks of revalidateFull's
  steps 2 and 3 run after either path, as before.
- A DCC key change fails on keys, and the test shows it takes the full
  walk with no relook.

Lookup-induced eviction: a sampled cache hit never evicts. admitTexture
evicts only on inserting a new texture, and a lookup that inserts has
returned a new object, so the relook returns Differs at that element.
It fails before any rerun, and no evicted object is proved. The test
shows it: a one-byte budget, the changed texture's new copy evicts the
other bound texture, and the proof fails after one relooked lookup.

Tests: ChangedRelook, now two ctest entries.
- agc_driver_changed_relook (imported memory): the 96-texture table
  cases from v1, plus the layered, DCC and eviction cases.
- agc_driver_changed_relook_copied (APS5_NO_HOST_IMPORT=1,
  APS5_VERIFY_PROOFS=1): the same synthetic cases plus a storage image
  and its sampled view over one surface. The table set is not reusable
  without imports, so it runs only in the first entry.
- Results:
  - Storage and sampled alias, same bytes: relooked, 2 lookups, current.
    Changed bytes: relooked, not current.
  - First layer of a 2D array: same bytes relooked with 1 lookup and
    current; changed not current.
  - DCC: same bytes under uncompressed keys relooked, 1 lookup, current.
    Keys cleared to 0x00: full walk, 0 relooked, not current.
  - Eviction: relooked, 1 lookup, not current, the other bound texture
    released.
- Every outcome's current flag matched a run with APS5_NO_CHANGED_RELOOK=1
  (the full walk alone), checked by hand. The copied entry also runs the
  walk beside every relooked proof that passes, through
  APS5_VERIFY_PROOFS.

Mutations, all caught:
- Recipe without the image shape (no first-layer narrowing): "a same-byte
  store in the sampled first layer of a 2D array took the relook ... not
  current", in both modes.
- ChangedSince stopping at the first changed query: "stores over 2
  textures looked 1 textures up again" (imported); the storage alias
  case "took the full walk" (copied).
- v1's mutations still apply.

Also run on lavapipe (Mesa 25.2.8 llvmpipe, LLVM 20.1.2, Ubuntu 24.04),
ANYPS5_NO_SHADER_CACHE=1, 33 of 33 passing with 3 skipped by their own
checks: agc_driver_graphics (with maps fallback), agc_driver_recorder,
agc_copy_guest_bytes, alpha_to_coverage, array_layer_target,
cached_image_multisample_guard, changed_relook (both),
image_table_reuse, lookup_log_fits_build, multisample_fill_host_only,
native_multisample_depth, own_refresh_repack_alias,
packed_mip_tail_target, partially_resident_*, sample_multisample_target,
sampled_cache_budget_*, storage_cache_budget, storage_one_slice_alias,
list_restart, quad_list_index_overflow. check_conventions passes.

Not reached:
- Storage images and views over imported memory: lavapipe compares
  imports instead of write-watching them, so their collect refuses and
  they always take the full walk there. Open boykopovar#14262, boykopovar#6192 and boykopovar#12921
  address that reason.
- Views whose source is a storage image in an image table.
- Depth surfaces, which never produce a changed query.
- A hardware GPU, the validation layer, and the title's real cost. Run
  APS5_COUNT_WALKS=1 on GTA V for calls per frame.

Overlaps as in v1: boykopovar#10894, boykopovar#9012, boykopovar#11444, boykopovar#14262, boykopovar#12575. No speed claims.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011mLh2cdhBwJrK5hBZGnNyy

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011mLh2cdhBwJrK5hBZGnNyy
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Nov 2, 2026
# Conflicts:
#	core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
#	core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_recorder_tests.cmake
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Nov 3, 2026
@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head 38dc520 merged onto main f6232fc · tested 2026-11-03 06:33 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 ✅ 2,740 passed · 6 failed (0 new, 3 also fail on main, 3 unstable on main) · 49 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,795 of 3,743 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 (937 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.2 s, ⚠️ agc_driver_lookup_log_fits_build 32.6 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
Validated but not compared (3, not in the main baseline's validation pass)
agc_untracked_forget
agc_untracked_hint_proof
agc_untracked_revalidate
Validation IDs already present on main (4 IDs in 525 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (525 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 517 more
VUID-vkCmdCopyImage-srcImage-01548 (8 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth, agc_driver_stencil_null_feedback
VUID-vkCmdCopyImage-srcImage-01551 (8 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth, agc_driver_stencil_null_feedback
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_srgb8_color_target
Skipped (49)
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_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 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
Reproduce
git fetch origin 38dc520c3f8c7170b7370b9e71cfb54748391afd f6232fcfda70644495273f6b8dd88cf0603463d6
git checkout f6232fcfda70644495273f6b8dd88cf0603463d6 && git merge --no-ff 38dc520c3f8c7170b7370b9e71cfb54748391afd
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.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Nov 3, 2026
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Nov 3, 2026
@Nesyth

Nesyth commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

@EagleBearerYS, a Windows/AMD data point for this PR: GTA V (PPSA04264, 01.011.001) in the Performance graphics mode, gameplay of the opening level, warm caches.

build FPS without profiling FPS with APS5_PROFILE_DRAW=1 draw commit collect full walks per 10 s collect refusals per 10 s
main 9090972b7e 14.46 12.78, 13.56 39.9, 37.6 us 3.83, 3.58 s 50,181 over 163 surfaces; 41,172 over 125
main + this PR 17.32, 18.70 15.60, 16.36 31.3, 30.3 us 2.42, 2.22 s 30,269 over 120 surfaces; 30,118 over 119
  • +20 to +29% FPS without profiling (+21% with it). In this mode the draw committer bounds the frame (about 88% busy on main). Its full walks over sampled surfaces outside the write watch fall by about 40%.
  • What is left is outside the watch. Every remaining refusal is counted as unwatched (none uncommitted, none other), over about 120 surfaces and 22 MiB.
  • No new warnings. Both builds print the same 8 storage image ... keeping the CPU's blocks lines per run, with no BDA or device faults.
Details
  • Machine: Radeon RX 7900 XTX (AMD Software 26.10.1, 32.0.32015.7029), Ryzen 7 7800X3D, Windows 11 Pro 26300, 3840x2160 output.
  • Builds: Release, MinGW-w64 GCC 15.2. main 9090972b7e, and the same commit with this PR's head 793fc7f8ea merged locally. This PR's own commits are the same at 8468301cdd, which merges a newer main.
  • FPS comes from the window title's counter over 57 s of scripted gameplay, each run a separate boot. The counters come from the [draw] pipelined, [rescache] revalidate and [present] lines of APS5_PROFILE_DRAW=1 in the profiled runs.
  • In the Fidelity mode the same scene runs at about 4.5 FPS on main, bound by queue 0's compute dispatches more than by the committer. This PR gave about +14% there in an earlier session on an older main.

@XairRrR XairRrR left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed — comments

On Linux/lavapipe the merge is clean, it builds, the checks pass, and the three new agc_untracked_* tests pass here and fail on main's production code. Two limits: the PR's own hinted stamp only runs on Windows, so this machine can't exercise it, and the APS5_VERIFY_UNTRACKED_PROOFS self-check cannot detect a stale view or storage image.

What I ran

Head 8468301cddcc8d5ba3992077b94084c449293b1f, main 4f41f4c375f5abb487dbd184fbc150f31994d762, merged tree 5ae2065315ccc0445f9f5092dfbd6ec1d619d5ce. Debian 13 VM (Xeon Gold 6136), GCC 14.2.0, Release, lavapipe (Mesa 26.1.6, LLVM 19).

git diff --check 4f41f4c375f5abb487dbd184fbc150f31994d762...8468301cddcc8d5ba3992077b94084c449293b1f
python3 tools/check_conventions.py --base 4f41f4c375f5abb487dbd184fbc150f31994d762
env VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ANYPS5_NO_SHADER_CACHE=1 ANYPS5_REQUIRE_VULKAN=1 ctest --test-dir build -V -R '^agc_driver_native_depth_uniform_planes$'
# negative control: the 6 production files (GuestMemory.hpp/.cpp, ShaderResources.hpp/.cpp, Texture.hpp/.cpp) restored from main
ninja -C build agc_driver_recorder_tests agc_driver_native_multisample_depth_tests
ctest --test-dir build --output-on-failure -R '^agc_untracked_'
env VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ANYPS5_NO_SHADER_CACHE=1 ANYPS5_REQUIRE_VULKAN=1 ctest --test-dir build -V -R '^agc_driver_native_depth_uniform_planes$'
# merged files restored, rebuilt
ctest --test-dir build --output-on-failure --repeat until-fail:5 -R '^agc_untracked_|^agc_write_tracking$'
git status --porcelain   # empty

Results

Check Result
git diff --check clean
check_conventions.py all checks passed
Configure / build / libs (script) ok
Selected tests (script) 2,232 run, 2,111 passed, 114 skipped (all expected), 0 new failures, 0 timeouts; the 7 known failures also fail on main
agc_untracked_forget, agc_untracked_revalidate, agc_untracked_hint_proof, agc_write_tracking pass, 5 of 5 in a row; each takes under 0.2 s
Validation (script): new VUID in agc_driver_native_depth_uniform_planes not from this PR. The test is newer than the baseline (d1ae628bc2), so the script had no main result to compare with. With main's production files I get the same 4 × VUID-vkCmdDispatch-groupCountX-00386. The test passes in both.
Validation layer loaded 769 of 770 tests; layer_missing_in is empty
uniform_planes with main's production files
1/1 Test #1852: agc_driver_native_depth_uniform_planes ...   Passed    0.40 sec
4 × Validation Error: [ VUID-vkCmdDispatch-groupCountX-00386 ] | MessageID = 0x8e927036

Negative control

I restored only the six production files from main and rebuilt. All three new tests fail:

output
agc_untracked_revalidate: AGC graphics: a sampled template over untracked memory took the full walk in the same collect epoch
agc_untracked_hint_proof: the block has no write-watch hint: its proofs are expected to follow the collect epoch
                          AGC graphics: a sampled template over untracked memory took the full walk in the same collect epoch
0% tests passed, 3 tests failed out of 3

These failures come from #6192's in-epoch part, which this branch carries. On Linux, UntrackedHint returns 0, so agc_untracked_hint_proof takes its "no hint" branch. The hinted stamp this PR adds (untrackedRangeStamp's hinted[0] != 0 branch, HintedComparison, the hinted proofKey) never runs on this machine, and this control does not cover it. The red/green for that path is the author's RTX 3070 run on Windows. I restored the merged files afterwards; git status --porcelain is empty.

Findings

Blocking

None.

Non-blocking

  1. APS5_VERIFY_UNTRACKED_PROOFS can't detect a stale view or storage image. The check is at core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp:3880. It counts a disagreement only when fullWalk() returns false.
    • fullWalk compares only pointer identity: cachedTexture(...) != textures[textureIndex] at ShaderResources.cpp:3806 and expected != storageTextures[storageIndex] at ShaderResources.cpp:3817.
    • A storage image (and a view of one) is refreshed in place, so the lookup returns the same pointer. A missed store into a view's or storage image's untracked range is therefore never counted.
    • The full walk also refreshes the image as a side effect, so verify mode hides the stale content it is meant to catch.
    • In this PR the hinted stamp applies exactly to views and storage images (through HintedComparison). The "0 disagreed" figures (38,000 in Village, 300,000 in GTA V) are therefore evidence only for snapshots.
    • Suggested fix: record each validatedTextures[i].source and storageTextures[i] Version() before the full walk, and also count a disagreement when any of them moves.
  2. The speed claim doesn't isolate the hinted stamp. CnRJay raised this, and it is still open in the description:
    • The Village pair and Nesyth's GTA V pair measure #6192 and this PR together.
    • The only isolated runs, chitters2004's North Yankton pair and Story split, show no measurable gain from the hinted stamp.
    • The isolated Village pair the author said was queued is not in the description yet.
    • The rules are met (summary lines from two commits and traces are attached), but a run of main + #6192 against main + #6192 + this PR on the Village menu would show whether this PR's own lines pay off.
  3. Not verified here: thread safety of HintedComparison. It reads the mutable, non-atomic comparedRanges of a StorageTexture from captureValidation; compareUntracked writes that array. Please confirm that both run under the same lock (the GPU mutex) or on the same thread.

Not verified

  • The hinted path itself (Windows only). I took the hint-key behaviour, the cross-thread cases in agc_untracked_hint_proof, and CheckUntrackedHintAcrossThreads in agc_write_tracking (compiled only under _WIN32) from the author's RTX 3070 report.
  • Titles. I launched none; per the review rules, no title or game is run.
  • Other GPUs. I tested only lavapipe.

To get this to a good state

  • Make the self-check compare image versions (finding 1). Then rerun it on a title where hinted stamps are taken, so that "0 disagreed" also covers views and storage images.
  • Add the isolated #6192-vs-#6192+this-PR Village measurement, or state in the description that the gain shown is #6192's.
  • Confirm the lock under which HintedComparison reads comparedRanges.

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head 8468301 merged onto main 4f41f4c · tested 2026-11-03 12:40 UTC · 29 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,761 passed · 7 failed (0 new, 3 also fail on main, 4 unstable on main) · 48 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,816 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 (933 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.3 s
Unstable on main (4, 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_driver_submit_progress: failed in 5 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
Validated but not compared (3, not in the main baseline's validation pass)
agc_untracked_forget
agc_untracked_hint_proof
agc_untracked_revalidate
Validation IDs already present on main (4 IDs in 517 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (517 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 509 more
VUID-vkCmdCopyImage-srcImage-01548 (9 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth, agc_driver_stencil_null_feedback, and 1 more
VUID-vkCmdCopyImage-srcImage-01551 (9 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth, agc_driver_stencil_null_feedback, and 1 more
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_srgb8_color_target
Skipped (48)
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_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_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 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 co
Reproduce
git fetch origin 8468301cddcc8d5ba3992077b94084c449293b1f 4f41f4c375f5abb487dbd184fbc150f31994d762
git checkout 4f41f4c375f5abb487dbd184fbc150f31994d762 && git merge --no-ff 8468301cddcc8d5ba3992077b94084c449293b1f
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 8468301 merged onto main 4f41f4c · tested 2026-11-03 12:42 UTC · 38 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 ✅ 2,748 passed · 10 failed (0 new, 8 also fail on main, 2 unstable on main) · 58 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,816 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 (933 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.5 s, ⚠️ public_headers 46.5 s, ⚠️ agc_driver_image_sample_unnormalized 36.2 s, ⚠️ agc_driver_sample_multisample_target 30.9 s, ⚠️ agc_driver_stream_copy 30.8 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 7 of the last 9 main runs
agc_driver_store_over_untracked: failed in 1 of the last 9 main runs
Failing on main too (8, not counted against this PR)
agc_driver_image_table
agc_driver_native_depth_bda_clear
agc_driver_native_multisample_depth
agc_driver_submit_progress
agc_submit_progress
agc_submit_progress_no_timeline
guest_mmap_executable
guest_socket_options_multicast
Validated but not compared (3, not in the main baseline's validation pass)
agc_untracked_forget
agc_untracked_hint_proof
agc_untracked_revalidate
Validation IDs already present on main (4 IDs in 517 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (517 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 509 more
VUID-vkCmdCopyImage-srcImage-01548 (8 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth, agc_driver_stencil_null_feedback, agc_driver_stencil_plane_memory
VUID-vkCmdCopyImage-srcImage-01551 (8 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth, agc_driver_stencil_null_feedback, agc_driver_stencil_plane_memory
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_srgb8_color_target
Skipped (58)
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_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_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 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: DisplayW
Reproduce
git fetch origin 8468301cddcc8d5ba3992077b94084c449293b1f 4f41f4c375f5abb487dbd184fbc150f31994d762
git checkout 4f41f4c375f5abb487dbd184fbc150f31994d762 && git merge --no-ff 8468301cddcc8d5ba3992077b94084c449293b1f
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.

@EagleBearerYS

Copy link
Copy Markdown
Contributor Author

Closing this PR. Thanks to XairRrR for the reviews, to chitters2004 and Nesyth for the Grand Theft Auto V runs, and to QRMOE for agreeing an order with #12575.

The isolated runs, chitters2004's North Yankton pair and Story split, show no measurable gain from the hinted stamp on its own, and a hinted check costs about 1.1 µs. The measured gain in these runs is #6192's, which #14262 carries forward.

@QRMOE, #12575 no longer waits on this PR, so the logLookup argument doesn't need carrying.

The branch stays on the fork.

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

Labels

agc libSceAgc* build docs perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants