Skip to content

perf(agc): check a mid-decode vertex table store against the queued write set and the retired items' writes - #10677

Open
WallisSkill wants to merge 1 commit into
boykopovar:mainfrom
WallisSkill:perf/agc-vertex-table-watch
Open

WallisSkill wants to merge 1 commit into
boykopovar:mainfrom
WallisSkill:perf/agc-vertex-table-watch

Conversation

@WallisSkill

@WallisSkill WallisSkill commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

What

DecodeOrderedVertexStageInfo (from #7691) watched queue 0 for a store that lands during a vertex stage decode by copying the write ranges of every queued item under the pipeline mutex before each decode, and by scanning every queued item again afterwards. With a deep pipeline that is work per queued item on every draw, on the queue worker, under the mutex the committer takes for every item it retires. In Graveyard Keeper 2 with APS5_PIPELINED_DRAWS=256 (sampled on main with #9508 applied) the queue worker spent about 14% in DecodeOrderedVertexStageInfo, 8% in DrawPipeline::WrittenSince and 3% in DrawPipeline::WatchWrites.

Now WatchWrites only notes the retired-item count. WrittenSince checks the reads against the deduplicated queuedWrites set (the ranges of the items still queued, kept by countWrites) and against the writes of the items that retired since the watch, which the committer keeps in a 512-entry ring indexed by the retired count. More than 512 retirements during one decode count as written, so the decode drains and runs again as before. Writes still held by the draw finisher count as queued, as before.

agc_driver_vertex_table_read_order covers both cases; a mutant that skips the retired-writes check fails it ("the decode kept the vertex buffer of an attribute word that a queued store replaced during the decode").

Tested

Windows 11 Pro 10.0.26200, AMD Ryzen 7 9800X3D, NVIDIA GeForce RTX 5070 (driver 616.92), MinGW Release build.

Performance: Graveyard Keeper 2 (PPSA35943), the first dungeon room after New game, 1920x1080 window, captured with APS5_TRACE_SECONDS=120:10 and APS5_DRAW_PIPELINE=1 APS5_PIPELINED_DRAWS=256 APS5_PIPELINE_DISPATCH=1 APS5_MIMALLOC=1, no other APS5_TRACE_* or APS5_PROFILE_* switch and no log redirection. Base is main 3fcb5e4; the change was built at 0c11c4bf8, which differs from this branch's head only in the commit message. Each build ran the scene once to warm the caches, then the captures below ran back to back on the same machine; the input came from APS5_PAD_INPUT_FILE (the libScePad command file), so the window was not focused. The trace buffer dropped events at its default size in every capture (dropped: yes); the frame times come from the presents.

  • base-1: seconds 120:10 from present 2344: 148 presents, frame p50 67.3 / p90 72.2 / p99 77.4 / max 78.1 ms, GPU busy 8.9 ms per present
  • base-2: seconds 120:10 from present 2352: 145 presents, frame p50 68.8 / p90 73.7 / p99 77.9 / max 78.2 ms, GPU busy 8.8 ms per present
  • base-3: seconds 120:10 from present 2358: 146 presents, frame p50 68.1 / p90 75.0 / p99 83.9 / max 86.4 ms, GPU busy 8.8 ms per present
  • pr2-1: seconds 120:10 from present 2450: 156 presents, frame p50 63.8 / p90 69.2 / p99 74.0 / max 77.1 ms, GPU busy 9.0 ms per present
  • pr2-2: seconds 120:10 from present 2458: 157 presents, frame p50 63.3 / p90 68.7 / p99 72.0 / max 72.3 ms, GPU busy 8.9 ms per present

Summary lines (main, then this change):

{"commit":"3fcb5e4d7649","dirty":null,"env":{"APS5_DRAW_PIPELINE":"1","APS5_MIMALLOC":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_PIPELINED_DRAWS":"256","APS5_PIPELINE_DISPATCH":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"120:10"},"gpu":"NVIDIA GeForce RTX 5070","driver":"NVIDIA 616.92","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9800X3D 8-Core Processor","cpu_threads":16,"memory_mib":31908,"title_id":"PPSA35943","title":"Graveyard Keeper 2","content_version":"01.001.000","resolution":"1920x1080","window":{"spec":"seconds 120:10","first_present":2344,"ms":10047.517},"presents":148,"frame_ms":{"p50":67.270,"p90":72.242,"p99":77.354,"max":78.058},"gpu_busy_ms_per_present":8.861,"worker_busy_pct":{"queue worker 0x0":96.438},"top_phases_ms_per_frame":{"Driver.Packet":65.406,"Graphics.Draw":57.908,"Graphics.Draw.draw_and_resource_release":49.344,"Driver.Packet.draw":42.270,"Driver.Draw":41.904,"Driver.DrawFinish":35.172,"Driver.Draw.prepare":32.781,"Driver.DrawFinish.shader_compile_and_link":31.427},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":6.419,"events_lost":154720,"totals_full":false}},"trace":"aps5-trace-3fcb5e4d7649-48276.json.gz"}
{"commit":"0c11c4bf8236","dirty":null,"env":{"APS5_DRAW_PIPELINE":"1","APS5_MIMALLOC":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_PIPELINED_DRAWS":"256","APS5_PIPELINE_DISPATCH":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"120:10"},"gpu":"NVIDIA GeForce RTX 5070","driver":"NVIDIA 616.92","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9800X3D 8-Core Processor","cpu_threads":16,"memory_mib":31908,"title_id":"PPSA35943","title":"Graveyard Keeper 2","content_version":"01.001.000","resolution":"1920x1080","window":{"spec":"seconds 120:10","first_present":2450,"ms":10025.271},"presents":156,"frame_ms":{"p50":63.792,"p90":69.182,"p99":74.001,"max":77.066},"gpu_busy_ms_per_present":8.979,"worker_busy_pct":{"queue worker 0x0":96.197},"top_phases_ms_per_frame":{"Driver.Packet":61.761,"Graphics.Draw":54.890,"Graphics.Draw.draw_and_resource_release":46.766,"Driver.Packet.draw":38.936,"Driver.Draw":38.569,"Driver.DrawFinish":34.866,"Driver.Draw.prepare":32.605,"Driver.DrawFinish.shader_compile_and_link":31.115},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":8.730,"events_lost":40701,"totals_full":false}},"trace":"aps5-trace-0c11c4bf8236-23400.json.gz"}

Traces and the other summary lines: https://github.com/WallisSkill/AnyPS5/releases/tag/gk2-perf-traces-2026-10-24 (files gk2-base-* and gk2-pr2-*).

Tests: 38 AGC driver tests (draw pipeline, finisher, label order, vertex fetch, vertex table read order, draw cache, depth and DCC cases) in plain and APS5_DRAW_PIPELINE=1 APS5_PIPELINED_DRAWS=32 APS5_PIPELINE_DISPATCH=1 modes with ANYPS5_NO_SHADER_CACHE=1: 76 of 76 pass. The branch is rebased onto main 137a8fa without conflicts; the captures above are from its first head 0c11c4bf8.

Validation: the same 38 AGC driver tests ran on main 137a8fa and on this head (rebased onto it) with VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, ANYPS5_NO_SHADER_CACHE=1, ANYPS5_REQUIRE_VULKAN=1, APS5_DRAW_PIPELINE=1 APS5_PIPELINED_DRAWS=32 APS5_PIPELINE_DISPATCH=1 and VK_LOADER_DEBUG=layer. The layer is the VkLayer_khronos_validation.dll that Steam ships in bin/cef/cef.win64, registered through VK_ADD_LAYER_PATH with its own manifest; every test that creates a device logs Inserted device layer "VK_LAYER_KHRONOS_validation" (31 of 38; the other 7 make no Vulkan device), and no log contains was not found but was requested by env var VK_INSTANCE_LAYERS. All 38 pass on both. The only validation message on either side is VUID-VkDeviceCreateInfo-pNext-pNext, 126 times on main and 126 times on this head, the same count in each test (this layer build predates some device-creation structures the driver chains); no VUID is new.

Digests of a paired capture (the release holds every trace and summary line):

trace_digest.py of base-1
python3 tools/trace_digest.py gk2-base-1-aps5-trace-3fcb5e4d7649-48276.json.gz --summary gk2-base-1-summary.json

seconds 120:10 from present 2344: 148 presents, frame p50 67.3 / p90 72.2 / p99 77.4 / max 78.1 ms, GPU busy 8.9 ms per present
NVIDIA GeForce RTX 5070, NVIDIA 616.92, Windows 10.0.26200, 1920x1080, commit 3fcb5e4, dropped: yes

{"commit":"3fcb5e4d7649","dirty":null,"env":{"APS5_DRAW_PIPELINE":"1","APS5_MIMALLOC":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_PIPELINED_DRAWS":"256","APS5_PIPELINE_DISPATCH":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"120:10"},"gpu":"NVIDIA GeForce RTX 5070","driver":"NVIDIA 616.92","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9800X3D 8-Core Processor","cpu_threads":16,"memory_mib":31908,"title_id":"PPSA35943","title":"Graveyard Keeper 2","content_version":"01.001.000","resolution":"1920x1080","window":{"spec":"seconds 120:10","first_present":2344,"ms":10047.517},"presents":148,"frame_ms":{"p50":67.27,"p90":72.242,"p99":77.354,"max":78.058},"gpu_busy_ms_per_present":8.861,"worker_busy_pct":{"queue worker 0x0":96.438},"top_phases_ms_per_frame":{"Driver.Packet":65.406,"Graphics.Draw":57.908,"Graphics.Draw.draw_and_resource_release":49.344,"Driver.Packet.draw":42.27,"Driver.Draw":41.904,"Driver.DrawFinish":35.172,"Driver.Draw.prepare":32.781,"Driver.DrawFinish.shader_compile_and_link":31.427},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":6.419,"events_lost":154720,"totals_full":false}},"trace":"aps5-trace-3fcb5e4d7649-48276.json.gz"}

Slowest frames (largest slices inside each, inclusive)

  • present 2391: 78.1 ms at 3171 ms: Driver.Packet (queue worker 0x0) 55.9, Graphics.Draw (draw committer) 50.4, Graphics.Draw.draw_and_resource_release (draw committer) 38.9, Driver.Packet.draw (queue worker 0x0) 33.9
  • present 2474: 77.4 ms at 8842 ms: Graphics.Draw (draw committer) 50.2, Graphics.Draw.draw_and_resource_release (draw committer) 38.9, Driver.DrawFinish (draw finisher) 15.3, Driver.DrawFinish.shader_compile_and_link (draw finisher) 9.9
  • present 2375: 77.3 ms at 2068 ms: Driver.Packet (queue worker 0x0) 55.5, Graphics.Draw (draw committer) 49.9, Graphics.Draw.draw_and_resource_release (draw committer) 38.2, Driver.Packet.draw (queue worker 0x0) 33.9
  • present 2415: 75.7 ms at 4810 ms: Driver.Packet (queue worker 0x0) 53.5, Graphics.Draw (draw committer) 47.6, Graphics.Draw.draw_and_resource_release (draw committer) 36.8, Driver.Packet.draw (queue worker 0x0) 32.8
  • present 2444: 75.0 ms at 6808 ms: Graphics.Draw (draw committer) 48.7, Graphics.Draw.draw_and_resource_release (draw committer) 39.0, Driver.DrawFinish (draw finisher) 12.3, batch (gpu) 9.5

Threads (ms per frame)

thread busy wait untraced in slices < 20 us largest
queue worker 0x0 27.3 (40 %) 0.0 (0 %) 40.6 62.0 Driver.Packet 27.3, Driver.EndSubmission 0.0
draw committer 40.7 (60 %) 0.3 (1 %) 26.9 47.7 Graphics.Draw 39.5, Recorder.Submit 1.2
presenter 0.5 (1 %) 0.0 (0 %) 67.4 0.1 VideoOut.Flip 0.5, Driver.Present 0.0
title 0.3 (0 %) 0.0 (0 %) 67.5 0.2 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.7 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.0 (0 %) 0.0 (0 %) 67.8 0.0 Shader.ResolveGraphicsAbi 0.0, Shader.ResolveGraphicsStagesAbi 0.0
draw finisher 10.8 (16 %) 0.0 (0 %) 57.1 104.4 Driver.DrawFinish 10.8
title 0.2 (0 %) 0.0 (0 %) 67.7 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.6 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.7 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.7 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.7 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.7 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveAbi 0.1
title 0.3 (0 %) 0.0 (0 %) 67.6 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.6 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.6 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.7 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.6 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 67.6 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
gpu 8.9 (13 %) 0.0 (0 %) 59.0 0.0 batch 8.9

Largest slices (ms per frame, inclusive, all threads): Graphics.Draw 39.5, Graphics.Draw.draw_and_resource_release 31.0, Driver.Packet 27.3, Driver.Packet.draw 14.8, Driver.Draw 14.4, Driver.DrawFinish 10.8, Driver.Packet.dispatch 10.1, Driver.Dispatch 10.0, batch 8.9, Driver.DrawFinish.shader_compile_and_link 7.7

Longest waits

  • Driver.Present.render_fence_wait (presenter) 1.6 ms at 7692 ms, present 2457
  • GpuMutex.wait.end (draw committer) 0.8 ms at 8709 ms, present 2472
  • GpuMutex.wait.end (draw committer) 0.7 ms at 6666 ms, present 2442
  • GpuMutex.wait.end (draw committer) 0.6 ms at 7956 ms, present 2461
  • GpuMutex.wait.end (draw committer) 0.5 ms at 6037 ms, present 2433
  • GpuMutex.wait.end (draw committer) 0.5 ms at 5086 ms, present 2419
  • GpuMutex.wait.end (draw committer) 0.5 ms at 7623 ms, present 2456
  • GpuMutex.wait.end (draw committer) 0.5 ms at 6524 ms, present 2440
  • GpuMutex.wait.end (draw committer) 0.5 ms at 2760 ms, present 2385
  • GpuMutex.wait.end (draw committer) 0.5 ms at 6312 ms, present 2437

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

  • batch 2479: 1.1 ms at 2825 ms, present 2385: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.3, Graphics.Draw (draw committer) 0.5, Graphics.Draw.draw_and_resource_release (draw committer) 0.4, Recorder.Submit (draw committer) 0.1
  • batch 2302: 1.1 ms at 2621 ms, present 2382: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.3, Graphics.Draw (draw committer) 0.7, Graphics.Draw.draw_and_resource_release (draw committer) 0.5, Graphics.Draw.validate (draw committer) 0.0
  • batch 6150: 1.1 ms at 7088 ms, present 2447: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.3, Graphics.Draw (draw committer) 0.7, Graphics.Draw.draw_and_resource_release (draw committer) 0.4, Recorder.Submit (draw committer) 0.0
  • batch 5142: 1.1 ms at 5891 ms, present 2430: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.3, Graphics.Draw (draw committer) 0.8, Graphics.Draw.draw_and_resource_release (draw committer) 0.5, Recorder.Submit (draw committer) 0.0
  • batch 2951: 1.1 ms at 3385 ms, present 2393: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.2, Graphics.Draw (draw committer) 0.6, Graphics.Draw.draw_and_resource_release (draw committer) 0.4, Recorder.Submit (draw committer) 0.0
trace_digest.py of pr2-1
python3 tools/trace_digest.py gk2-pr2-1-aps5-trace-0c11c4bf8236-23400.json.gz --summary gk2-pr2-1-summary.json

seconds 120:10 from present 2450: 156 presents, frame p50 63.8 / p90 69.2 / p99 74.0 / max 77.1 ms, GPU busy 9.0 ms per present
NVIDIA GeForce RTX 5070, NVIDIA 616.92, Windows 10.0.26200, 1920x1080, commit 0c11c4bf8236, dropped: yes

{"commit":"0c11c4bf8236","dirty":null,"env":{"APS5_DRAW_PIPELINE":"1","APS5_MIMALLOC":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_PIPELINED_DRAWS":"256","APS5_PIPELINE_DISPATCH":"1","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"120:10"},"gpu":"NVIDIA GeForce RTX 5070","driver":"NVIDIA 616.92","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9800X3D 8-Core Processor","cpu_threads":16,"memory_mib":31908,"title_id":"PPSA35943","title":"Graveyard Keeper 2","content_version":"01.001.000","resolution":"1920x1080","window":{"spec":"seconds 120:10","first_present":2450,"ms":10025.271},"presents":156,"frame_ms":{"p50":63.792,"p90":69.182,"p99":74.001,"max":77.066},"gpu_busy_ms_per_present":8.979,"worker_busy_pct":{"queue worker 0x0":96.197},"top_phases_ms_per_frame":{"Driver.Packet":61.761,"Graphics.Draw":54.89,"Graphics.Draw.draw_and_resource_release":46.766,"Driver.Packet.draw":38.936,"Driver.Draw":38.569,"Driver.DrawFinish":34.866,"Driver.Draw.prepare":32.605,"Driver.DrawFinish.shader_compile_and_link":31.115},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":8.73,"events_lost":40701,"totals_full":false}},"trace":"aps5-trace-0c11c4bf8236-23400.json.gz"}

Slowest frames (largest slices inside each, inclusive)

  • present 2479: 77.1 ms at 1864 ms: Driver.Packet (queue worker 0x0) 52.5, Graphics.Draw (draw committer) 48.9, Graphics.Draw.draw_and_resource_release (draw committer) 37.0, Driver.Packet.draw (queue worker 0x0) 31.2
  • present 2575: 74.0 ms at 7993 ms: Driver.Packet (queue worker 0x0) 47.8, Graphics.Draw (draw committer) 45.0, Graphics.Draw.draw_and_resource_release (draw committer) 36.9, Driver.Packet.draw (queue worker 0x0) 22.4
  • present 2481: 72.7 ms at 2008 ms: Driver.Packet (queue worker 0x0) 46.0, Graphics.Draw (draw committer) 42.1, Graphics.Draw.draw_and_resource_release (draw committer) 31.7, Driver.Packet.draw (queue worker 0x0) 26.0
  • present 2599: 72.1 ms at 9572 ms: Graphics.Draw (draw committer) 44.3, Graphics.Draw.draw_and_resource_release (draw committer) 33.4, Driver.DrawFinish (draw finisher) 14.2, Driver.DrawFinish.shader_compile_and_link (draw finisher) 10.4
  • present 2528: 72.1 ms at 4997 ms: Driver.Packet (queue worker 0x0) 44.9, Graphics.Draw (draw committer) 43.3, Graphics.Draw.draw_and_resource_release (draw committer) 33.6, Driver.Packet.dispatch (queue worker 0x0) 21.4

Threads (ms per frame)

thread busy wait untraced in slices < 20 us largest
queue worker 0x0 30.2 (47 %) 0.0 (0 %) 34.1 92.9 Driver.Packet 30.1, Driver.EndSubmission 0.1
draw committer 37.0 (58 %) 0.3 (1 %) 26.9 48.9 Graphics.Draw 35.8, Recorder.Submit 1.1
presenter 0.5 (1 %) 0.0 (0 %) 63.8 0.1 VideoOut.Flip 0.5, Driver.Present 0.0
title 0.3 (0 %) 0.0 (0 %) 63.9 0.2 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
draw finisher 10.9 (17 %) 0.0 (0 %) 53.4 103.5 Driver.DrawFinish 10.9
title 0.0 (0 %) 0.0 (0 %) 64.2 0.0 Shader.ResolveGraphicsAbi 0.0, Shader.ResolveGraphicsStagesAbi 0.0
title 0.2 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.3 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.3 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.2 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveAbi 0.1
title 0.3 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveAbi 0.1
title 0.3 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.3 (0 %) 0.0 (0 %) 64.0 0.1 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
title 0.3 (0 %) 0.0 (0 %) 64.0 0.0 Shader.ResolveGraphicsAbi 0.1, Shader.ResolveGraphicsStagesAbi 0.1
gpu 9.0 (14 %) 0.0 (0 %) 55.3 0.0 batch 9.0

Largest slices (ms per frame, inclusive, all threads): Graphics.Draw 35.8, Driver.Packet 30.1, Graphics.Draw.draw_and_resource_release 28.4, Driver.Packet.dispatch 13.5, Driver.Dispatch 13.5, Driver.Packet.draw 13.4, Driver.Draw 13.0, Driver.DrawFinish 10.9, batch 9.0, Driver.Draw.prepare 8.5

Longest waits

  • Driver.Present.render_fence_wait (presenter) 1.4 ms at 4040 ms, present 2513
  • GpuMutex.wait.end (draw committer) 0.9 ms at 1732 ms, present 2477
  • GpuMutex.wait.end (draw committer) 0.6 ms at 9644 ms, present 2600
  • GpuMutex.wait.end (draw committer) 0.6 ms at 3041 ms, present 2497
  • GpuMutex.wait.end (draw committer) 0.6 ms at 9899 ms, present 2604
  • GpuMutex.wait.end (draw committer) 0.6 ms at 2080 ms, present 2482
  • GpuMutex.wait.end (draw committer) 0.5 ms at 6990 ms, present 2559
  • GpuMutex.wait.end (draw committer) 0.5 ms at 805 ms, present 2463
  • GpuMutex.wait.end (draw committer) 0.5 ms at 6807 ms, present 2556
  • GpuMutex.wait.end (draw committer) 0.5 ms at 8337 ms, present 2580

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

  • batch 7509: 7.5 ms at 8005 ms, present 2575: GPU no ranges; recorded by Recorder.Sync (draw committer) 7.6, Graphics.Draw (draw committer) 0.1, Graphics.Draw.draw_and_resource_release (draw committer) 0.1, Recorder.Submit (draw committer) 0.0
  • batch 5517: 1.2 ms at 5918 ms, present 2541: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.3, Graphics.Draw (draw committer) 0.7, Graphics.Draw.draw_and_resource_release (draw committer) 0.5, Recorder.Submit (draw committer) 0.0
  • batch 4738: 1.2 ms at 5067 ms, present 2528: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.4, Graphics.Draw (draw committer) 0.7, Graphics.Draw.draw_and_resource_release (draw committer) 0.5, Recorder.Submit (draw committer) 0.1
  • batch 5458: 1.1 ms at 5853 ms, present 2540: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.3, Graphics.Draw (draw committer) 0.6, Graphics.Draw.draw_and_resource_release (draw committer) 0.5, Recorder.Submit (draw committer) 0.0
  • batch 5219: 1.1 ms at 5585 ms, present 2536: GPU no ranges; recorded by Recorder.Sync (draw committer) 1.3, Graphics.Draw (draw committer) 0.6, Graphics.Draw.draw_and_resource_release (draw committer) 0.4, Recorder.Submit (draw committer) 0.0

Checklist

🤖 Generated with Claude Code

@github-actions github-actions Bot added the perf Performance change label Oct 24, 2026

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The retired-write ring and conservative overflow handling look internally consistent on the reviewed diff, and the published gk2 trace assets are present. I cannot approve this AGC change yet because the repository's AGC validation rule requires the same focused tests on main and this head with ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1, and VK_LAYER_KHRONOS_validation, then a comparison confirming no new VUIDs. The PR currently reports the layer is unavailable and only reports branch test counts. Please attach both runs from a layer-equipped machine/GPU (including confirmation the layer was actually loaded), or explain what supported validation route can satisfy the rule.

The contribution guide also requires tools/trace_digest.py output for performance claims. The release has the traces and per-capture JSON summary assets; please include the digest output for the paired captures (or the prescribed report output) so reviewers can reproduce the presented comparison. I downloaded the base-1 and pr2-1 trace assets and confirmed the digester reads them; its output reports 147 and 155 frames respectively, but no summary line was found when run against the release asset layout.

Finally, this diff conflicts with open #10678 in Draw.cpp, and both PRs currently say Depends on: none. Please coordinate the landing order with the other PR's author and record the dependency on the checklist before these overlapping changes are integrated.

@github-actions

github-actions Bot commented Oct 24, 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 10689 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawPipeline.cpp L413

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 1896 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawPipeline.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawPipeline.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawPipeline.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawPipeline.cpp
PR 6235 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 7410 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9431 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9432 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9672 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9673 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9674 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9675 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9676 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9842 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9891 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9892 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9893 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9895 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 9898 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawPipeline.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawPipeline.cpp
PR 10193 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawPipeline.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawPipeline.cpp
PR 10435 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 10581 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp

…rite set and the retired items' writes

DecodeOrderedVertexStageInfo copied the write ranges of every queued
item under the pipeline mutex before each vertex stage decode, and
scanned every queued item again afterwards, so the queue worker paid
for the pipeline depth on every draw. The watch now only notes the
retired count; the check reads the deduplicated queuedWrites set and
the writes of the items that retired during the decode, kept in a
512-entry ring by the committer. More than 512 retirements count as
written. Graveyard Keeper 2, first dungeon room, APS5_PIPELINED_DRAWS
256: frame p50 67.3-68.8 ms on main, 63.3-63.8 ms with this change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the agc libSceAgc* label Oct 24, 2026
@WallisSkill
WallisSkill force-pushed the perf/agc-vertex-table-watch branch from 864292e to 7b38e94 Compare October 24, 2026 17:44
@WallisSkill

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Addressed:

  • Validation runs. The same 38 AGC tests ran on main 137a8fa and on this head (now rebased onto it) with VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, ANYPS5_NO_SHADER_CACHE=1, ANYPS5_REQUIRE_VULKAN=1 and VK_LOADER_DEBUG=layer, so each log shows the loader inserting the layer (Inserted device layer "VK_LAYER_KHRONOS_validation" in the 31 tests that create a device) and none reports was not found but was requested. All pass on both; the only message is VUID-VkDeviceCreateInfo-pNext-pNext, 126 on each side with the same count per test, so nothing is new. Details are in the Tested section.
  • Digest. The description now holds the full trace_digest.py output of base-1 and the change's capture. With the release files the summary line is found with --summary, e.g. python3 tools/trace_digest.py gk2-base-1-aps5-trace-3fcb5e4d7649-48276.json.gz --summary gk2-base-1-summary.json (the per-capture .json files are single aps5-summary.jsonl lines).
  • perf(agc): build a pipelined draw's resource-cache key before it reaches the committer #10678. This branch does not touch Draw.cpp; git merge-tree of the two heads (both now on main 137a8fa) reports no conflict, so either can land first and Depends on stays none. The checklist line says so now.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed exact head 7b38e94968eb760135eadcd3a0daf197d6b62a5f. The retired-write ring is indexed consistently with the monotonically increasing retired count; if more than 512 items retire during a decode, WrittenSince conservatively reports a write and forces the retry. The regression test covers queued and retired writes, and its described mutant fails. The author has now documented the same 38 focused AGC tests on main and this head with the validation layer confirmed loaded; both runs passed with identical VUID counts and no new VUIDs. The paired performance report now includes trace_digest.py summaries and the trace assets. Current hosted conventions, labels, eligibility and report checks pass; product CI jobs are skipped by policy.

@oneandonlydean oneandonlydean self-assigned this Oct 25, 2026

This branch has not been deployed

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

Labels

agc libSceAgc* perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants