Skip to content

perf(agc): prune and gate the label take records - #13252

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
hugodearaujo:fix/label-takes-prune
Oct 30, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
hugodearaujo:fix/label-takes-prune

Conversation

@hugodearaujo

Copy link
Copy Markdown
Contributor

What

Follow-up to #12923, from CnRJay's cost review there. The per-queue label pass and take records #12923 added (labelPasses, labelTaken in Driver) are never erased, and noteLabelIssue takes labelStoresMutex for every store packet the label history keeps. In The Elder Scrolls V: Skyrim (PPSA03747) both maps grow for the whole session once gameplay starts, and every kept store packet takes the lock:

Time main: labelPasses / labelTaken This PR: entries (live passes, takes) / ordered records Kept store packets so far Of them taking labelStoresMutex: main / this PR
50 s 502 / 380 1 (1, 0) / 1 259,635 / 258,928 259,635 / 163
100 s 565 / 443 1 (1, 0) / 1 662,193 / 661,726 662,193 / 386
150 s 24,748 / 9,639 269 (256, 13) / 270 960,169 / 966,600 960,169 / 17,341
200 s 55,414 / 21,835 247 (234, 14) / 249 1,321,739 / 1,327,249 1,321,739 / 58,576
300 s 95,532 / 37,750 247 (233, 14) / 247 2,060,407 / 2,071,636 2,060,407 / 140,379
400 s 130,269 / 57,162 251 (237, 14) / 252 2,872,134 / 2,881,622 2,872,134 / 230,605

On main both maps grow by about 400 entries a second once gameplay starts (~140 s) and never shrink. With this change the table never held more than 416 entries and 423 records over the run, and 8 % of the kept store packets took the lock (11 % during gameplay). A first version with 1024 counters locked for 22 % (31 % during gameplay), hence 4096. The label history itself (labelStores, one 4-store array per stored dword, from #178) grows the same way, 134,520 dwords at 400 s on both builds; that's outside this change.

How

  • The passes and takes move to LabelTakes (Driver/Synchronization/LabelTakes.hpp), keyed by queue and dword as before, which also keeps each queue's passes in serial order.
  • Retire rule: storedSince already skips every store whose stamp is no newer than the waiting submission's received serial, and a take only hides stores no newer than the take. So once every submission the queue can still run entered the driver after a pass or a take, that entry can't change any result. The queue's worker retires them right before it executes a submission (retireLabelTakes(id, submission.received)): a queue's submissions run in order and their received serials grow in that order. A rewind tail gets a newer serial than the submissions of its queue still pending, so it retires up to the oldest of those (or its own serial when none is pending). Suspend boundaries have serial 0 and retire nothing.
  • Bound: after a queue's worker starts a submission, the table holds for that queue only waits that passed after that submission entered the driver, one ordered record per such pass and one entry per distinct dword among them. It doesn't depend on label addresses being reused. A queue that goes idle keeps its last entries until its next submission starts.
  • Gate: noteLabelIssue reads a count of live passes per (queue, dword) hash slot (4096 relaxed atomic counters, 16 KiB) without the lock and takes labelStoresMutex only when one may exist. The counters only change under the lock. A queue's passes, the stores of that queue that take them, and its retires all run on that queue's worker thread, so the read always sees the queue's own passes; another queue's pass in the same slot only costs a lock that finds nothing.
  • storedSince, noteLabelPass and which stores a take hides are unchanged.

Tested

Linux (Arch, RADV, RX 9070 XT), Release.

  • Rebased onto main 409fe64 (aee6ce2) and rerun there with the layer: the focused set passes 15 of 15 and the wider set of 113 gives the same per-test results as below, no VUID- lines.
  • New cases in agc_driver (tests/Submit.cpp): LabelTakes on its own (a take survives a retire at an older serial and another queue's retire, goes at its own serial; an older pass record doesn't retire a newer pass on the same dword; one queue's retire leaves the other queue's pass), and a driver case: two queue 0x20 submissions entered before the producer's store, the first takes and resets the label, the second must stay blocked with the take still recorded, and a third submission entered after both waits drops the take once it runs. As mutation checks on this head: retiring up to a serial far in the future fails an existing take-and-reset case (a label store its own queue had taken and reset satisfied the queue's next wait, or the wait expired), dropping the worker's retire fails the new driver case (a take was kept after a submission of the queue entered after it started), and a gate that never opens fails the same existing case as the first.
  • Focused set from fix(agc): don't release a label wait on a store its queue already took and reset #12923 plus agc_driver_same_queue_label_wait, with Khronos validation 1.4.363 (VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, ANYPS5_NO_SHADER_CACHE=1, ANYPS5_REQUIRE_VULKAN=1, layer insertion checked with VK_LOADER_DEBUG=layer): 15 of 15 on main 102c4f9 and on this branch (agc_driver_copied_writer_label_order skips on both), no VUID- lines.
  • The wider set (^agc_.*(label|wait|queue|submit|pipeline|eop|gated|idle), 113 tests), with the layer: identical per test on main 102c4f9 and this branch, no VUID- lines; agc_idle_publish_wait fails on both with the idle publish's bytes are wrong on this GPU, and agc_small_tiled_shadow_label and both agc_driver_copied_writer_label_order tests skip on both.
  • Skyrim (PPSA03747), main 102c4f9 + fix(shader): decide each resource branch condition once per plan #11506 (Skyrim needs it to reach gameplay) without and with this change, same machine. Growth above: one 420 s run each with a local size print every 10 s (not part of this PR), both builds also with fix(ngs2): buffer voice setups, waveform blocks and patches sent during processing #12995 so the NGS2 abort below can't cut the run short. Cost: tools/trace_digest.py over the same 60 s window (APS5_TRACE_SECONDS=60:60: main menu, New Game, first loading), two 200 s runs each:
Build Run Driver.Packet ms per frame queue worker 0x0 busy frame p50 / p99
main 102c4f9 + #11506 1 1.121 6.2 % 16.7 / 16.8 ms
main 102c4f9 + #11506 2 1.555 8.6 % 16.7 / 17.7 ms
+ this PR 1 1.087 6.0 % 16.7 / 16.7 ms
+ this PR 2 1.093 5.9 % 16.7 / 16.7 ms

The window is vsync-bound and the two main runs differ by more than either differs from this change, so this shows no regression, not a speedup. No run had a label wait timeout.

trace_digest.py headers

main, run 1:

seconds 60:60 from present 3315: 3329 presents, frame p50 16.7 / p90 16.7 / p99 16.8 / max 1357.5 ms, GPU busy 8.5 ms per present
AMD Radeon RX 9070 XT (RADV GFX1201), radv Mesa 26.2.6-arch1.1, Linux 7.2.11-arch1-1, 3840x2160, commit 5ade8c491953, dropped: no

{"commit":"5ade8c491953","dirty":null,"env":{"APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_SECONDS":"60:60","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.6-arch1.1","os":"Linux 7.2.11-arch1-1","cpu":"AMD Ryzen 7 9800X3D 8-Core Processor","cpu_threads":8,"memory_mib":31192,"title_id":"PPSA03747","title":"Skyrim","content_version":"01.001.010","resolution":"3840x2160","window":{"spec":"seconds 60:60","first_present":3315,"ms":60432.977},"presents":3329,"frame_ms":{"p50":16.683,"p90":16.687,"p99":16.785,"max":1357.503},"gpu_busy_ms_per_present":8.52,"worker_busy_pct":{"queue worker 0x0":6.188},"top_phases_ms_per_frame":{"VideoOut.Flip":15.743,"VideoOut.Flip.vblank_wait":14.974,"Driver.Packet":1.121,"Graphics.Draw":0.538,"Graphics.Draw.draw_and_resource_release":0.422,"Driver.Packet.draw":0.421,"Driver.Draw":0.417,"VideoOut.Flip.present":0.404},"trace_dropped":false,"trace":"aps5-trace-5ade8c491953-2119064.json.gz"}

main, run 2:

seconds 60:60 from present 3317: 3309 presents, frame p50 16.7 / p90 16.7 / p99 17.7 / max 1431.1 ms, GPU busy 8.2 ms per present
AMD Radeon RX 9070 XT (RADV GFX1201), radv Mesa 26.2.6-arch1.1, Linux 7.2.11-arch1-1, 3840x2160, commit 5ade8c491953, dropped: no

{"commit":"5ade8c491953","dirty":null,"env":{"APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_SECONDS":"60:60","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.6-arch1.1","os":"Linux 7.2.11-arch1-1","cpu":"AMD Ryzen 7 9800X3D 8-Core Processor","cpu_threads":8,"memory_mib":31192,"title_id":"PPSA03747","title":"Skyrim","content_version":"01.001.010","resolution":"3840x2160","window":{"spec":"seconds 60:60","first_present":3317,"ms":60014.239},"presents":3309,"frame_ms":{"p50":16.683,"p90":16.688,"p99":17.663,"max":1431.087},"gpu_busy_ms_per_present":8.215,"worker_busy_pct":{"queue worker 0x0":8.594},"top_phases_ms_per_frame":{"VideoOut.Flip":15.271,"VideoOut.Flip.vblank_wait":14.495,"Driver.Packet":1.555,"Graphics.Draw":0.602,"Driver.Packet.draw":0.554,"Driver.Draw":0.549,"Graphics.Draw.draw_and_resource_release":0.474,"VideoOut.Flip.present":0.375},"trace_dropped":false,"trace":"aps5-trace-5ade8c491953-2216330.json.gz"}

this PR, run 1:

seconds 60:60 from present 3312: 3305 presents, frame p50 16.7 / p90 16.7 / p99 16.7 / max 1466.6 ms, GPU busy 8.0 ms per present
AMD Radeon RX 9070 XT (RADV GFX1201), radv Mesa 26.2.6-arch1.1, Linux 7.2.11-arch1-1, 3840x2160, commit ccd54f4ea010, dropped: no

{"commit":"ccd54f4ea010","dirty":null,"env":{"APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_SECONDS":"60:60","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.6-arch1.1","os":"Linux 7.2.11-arch1-1","cpu":"AMD Ryzen 7 9800X3D 8-Core Processor","cpu_threads":8,"memory_mib":31192,"title_id":"PPSA03747","title":"Skyrim","content_version":"01.001.010","resolution":"3840x2160","window":{"spec":"seconds 60:60","first_present":3312,"ms":60377.42},"presents":3305,"frame_ms":{"p50":16.683,"p90":16.687,"p99":16.7,"max":1466.634},"gpu_busy_ms_per_present":8.037,"worker_busy_pct":{"queue worker 0x0":5.964},"top_phases_ms_per_frame":{"VideoOut.Flip":15.775,"VideoOut.Flip.vblank_wait":15.082,"Driver.Packet":1.087,"Graphics.Draw":0.543,"Driver.Packet.draw":0.43,"Graphics.Draw.draw_and_resource_release":0.428,"Driver.Draw":0.425,"VideoOut.Flip.present":0.349},"trace_dropped":false,"trace":"aps5-trace-ccd54f4ea010-2435599.json.gz"}

this PR, run 2:

seconds 60:60 from present 3326: 3338 presents, frame p50 16.7 / p90 16.7 / p99 16.7 / max 2382.9 ms, GPU busy 8.2 ms per present
AMD Radeon RX 9070 XT (RADV GFX1201), radv Mesa 26.2.6-arch1.1, Linux 7.2.11-arch1-1, 3840x2160, commit ccd54f4ea010, dropped: no

{"commit":"ccd54f4ea010","dirty":null,"env":{"APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_SECONDS":"60:60","APS5_TRACE_SUMMARY_EVERY":"10"},"gpu":"AMD Radeon RX 9070 XT (RADV GFX1201)","driver":"radv Mesa 26.2.6-arch1.1","os":"Linux 7.2.11-arch1-1","cpu":"AMD Ryzen 7 9800X3D 8-Core Processor","cpu_threads":8,"memory_mib":31192,"title_id":"PPSA03747","title":"Skyrim","content_version":"01.001.010","resolution":"3840x2160","window":{"spec":"seconds 60:60","first_present":3326,"ms":61750.513},"presents":3338,"frame_ms":{"p50":16.683,"p90":16.687,"p99":16.698,"max":2382.857},"gpu_busy_ms_per_present":8.206,"worker_busy_pct":{"queue worker 0x0":5.922},"top_phases_ms_per_frame":{"VideoOut.Flip":15.682,"VideoOut.Flip.vblank_wait":15.31,"Driver.Packet":1.093,"Graphics.Draw":0.519,"Graphics.Draw.draw_and_resource_release":0.42,"Driver.Packet.draw":0.416,"Driver.Draw":0.412,"VideoOut.Flip.present":0.26},"trace_dropped":false,"trace":"aps5-trace-ccd54f4ea010-2490675.json.gz"}

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none (follow-up to fix(agc): don't release a label wait on a store its queue already took and reset #12923, merged)
  • Fixes: none
  • Unblocks: none
  • GPUs tested: AMD Radeon RX 9070 XT (RADV GFX1201, Mesa 26.2.6), Arch Linux 7.2.11
  • AI-assisted: yes

A queue's passes on label dwords and the takes its own stores make of them move to LabelTakes. A wait only considers stores recorded after its submission entered the driver, so a pass or take at a serial no newer than that entry can no longer hide a store: each queue's passes are kept in serial order and dropped when its worker starts a submission received after them (for a rewind tail, the oldest submission of the queue still pending bounds it).

noteLabelIssue reads a per-(queue, dword) count of live passes without the lock and takes labelStoresMutex only when a pass may exist. Passes and takes of a queue, and its stores that take them, all run on that queue's worker.
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

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 5609 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6501 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6804 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 6867 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Queues/Submission.cpp
PR 7275 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 7369 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 7622 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Queues/Submission.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 7978 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Queues/QueueWorker.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Queues/Submission.cpp
core/libs/prx/libSceAgcDriver/tests/Submit.cpp
PR 9335 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 10193 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp

@maskym

maskym commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Windows + NVIDIA result for head aee6ce2fd9, merged alone into main a5939f10a8 (the PR's Tested section names no Windows run). Correctness only; I have no title trace, so nothing here speaks to the speed claim.

Host: Windows 11 26300, Intel i7-12700K, NVIDIA GeForce RTX 2070 SUPER, WinLibs GCC 15.2.0 (x86_64-ucrt-posix-seh, r6), Release, BUILD_TESTING=ON, Ninja. Build clean.

Same machine, both trees, with ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1, VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (Khronos VVL 1.4.366) and ctest --test-dir build -R '^(agc|guest_video_out|video_out)' --parallel 4 -V:

Tree Result Layer inserted was not found but was requested Distinct VUID-
main a5939f10a8 1204/1204 1050 0 VkPipelineColorBlendStateCreateInfo-pAttachments-00605 ×18 (#11990)
this PR 1204/1204 1050 0 the same, ×18

No new validation errors. agc_driver, which runs the new testLabelTakesRetire and testLabelTakeRetiredByLaterSubmission through its default path, passes in the full run and in three further runs on its own (8.1 s each). Not run on a PS5.

AI-assisted: yes (Claude Code), the runs and the numbers above are from this machine.

@hugodearaujo

Copy link
Copy Markdown
Contributor Author

@maskym thanks for the Windows/NVIDIA run with the validation layer on both trees.

@oneandonlydean oneandonlydean self-assigned this Oct 30, 2026
@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head aee6ce2 merged onto main 98ddd9c · tested 2026-10-30 11:47 UTC · 21 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,282 passed · 4 failed (0 new, 2 also fail on main, 2 unstable on main) · 40 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,326 of 2,987 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 (861 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_bda_device 62.1 s
Unstable on main (2, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_submit_progress: failed in 5 of the last 8 main runs
agc_submit_progress: failed in 5 of the last 8 main runs
Failing on main too (2, not counted against this PR)
guest_mmap_executable
guest_socket_options_multicast
Validation IDs already present on main (4 IDs in 390 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (390 tests): agc_compute_pipeline_replay, agc_driver, agc_driver_address_passes_draw_transitions, agc_driver_address_passes_targets_split, agc_driver_array_layer_target_cpu, agc_driver_bda_span_reads_draw_pipeline, agc_driver_bindless_images, agc_driver_branch_past_endpgm, and 382 more
VUID-vkCmdCopyImage-srcImage-01548 (13 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 5 more
VUID-vkCmdCopyImage-srcImage-01551 (13 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_cpu_write_after_memo, agc_driver_depth_plane_cpu_write_after_page_unwatch, agc_driver_depth_plane_cpu_write_after_partial_unwatch, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_partial_store_unimported, agc_driver_depth_plane_sampling, and 5 more
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (2 tests): agc_driver_prepared_exports, agc_driver_srgb8_color_target
Skipped (40)
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_stencil_ref_export: skipped, the device lacks VK_EXT_shader_stencil_export
agc_driver_vertex_elected_atomic_max: skipped, the device runs vertex programs in subgroups, so they keep their cross-lane reductions
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_main: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_fresh: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_labels: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is eithe
Reproduce
git fetch origin aee6ce2fd999edc0fa2d75f12ab56c6d5d142062 98ddd9c1792bbab016ceed5db267a93d1d61f00a
git checkout 98ddd9c1792bbab016ceed5db267a93d1d61f00a && git merge --no-ff aee6ce2fd999edc0fa2d75f12ab56c6d5d142062
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
oneandonlydean merged commit ed1e0ed into boykopovar:main Oct 30, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants