Repository navigation
fix(agc): relaunch the frame replay when a host region blocks a captured GPU range - #12696
Conversation
The first replay pass compiles every shader and pipeline the frames use, so its frame times mostly measure compilation. agc_frame_replay --repeat <n> replays the frames n times: before each later pass it waits for the driver to go idle, clears the captured ranges, restores the snapshot, registers the video outputs the snapshot had again and makes the EOP flip reservations that were pending at the snapshot again (a token still reserved from the previous pass is kept). Frame times come from passes 2 to n, each pass is listed under passes, and agc_driver_frame_replay also replays its capture with --repeat 3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n minutes The drain gave up after 10 s without a completion even while the driver was still compiling or preparing the work, which reported unfinished submissions on full titles and left a process that could not exit. A blocked wait on one queue does not mean the replay is stuck either: another queue can still be preparing the work that releases it. The drain now gives up only after ten minutes without a completion and reports the waits the queues are blocked on every ten seconds and when it gives up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lready applied A replay's device has no window, so it never loaded the title's Vulkan pipeline cache file and compiled every pipeline the captured frames used again, minutes for the first Demon's Souls frames. It also replayed the pipeline journal in the background during the measured frames, which the title did at boot. APS5_HEADLESS_PIPELINE_CACHE makes a device without a window load the file, and agc_frame_replay sets it unless --cold-pipelines is given. The driver exports AgcDriverWaitForPipelineJournal, and the replay calls it after the registrations and reports the wait as journal_s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g, reservation errors --cold-pipelines now clears an inherited APS5_HEADLESS_PIPELINE_CACHE on both platforms, the replay test builds its command with boykopovar#11157's quoting so the redirect and --repeat work under sh and cmd, and a reservation that fails in a repeated pass is reported and fails the replay instead of being dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…PS5_TRACE_GPU With APS5_TRACE_GPU the driver now prints the serial it gives each submission, CPU flip and suspend point when it accepts it, with the queue, size and command address, and each completion as it is marked, including queue 0 completions deferred to the draw pipeline. A replay that stops completing can then be followed from the call that made a submission to the serial that never completed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y's serials Finding why a replay of a title stops, or which shaders a frame uses, meant running the whole capture. agc_frame_replay gains three modes: - --shaders replays nothing and maps no guest memory: it reads the snapshot, applies the captured writes in call order and prints one JSON line per shader registration with its code address, size, type, code hash and how many earlier registrations had the same code; --shader-code <dir> also writes each distinct code to a file - --submits <n> lists the first n submissions and flips of the captured frames with their queue and serials, the packets of each and the fields of its waits and releases - --trace-serials prints each submission, flip and suspend point with its call ordinal and command address as it is issued, to match the serials APS5_TRACE_GPU prints agc_driver_frame_replay_shader and agc_driver_frame_replay_shader_host check that the listing reads the code the capture holds at the registration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ayload words, output errors --submits decodes the captured ranges on Linux and macOS as well, walks packets with Pm4::PacketWords and FillerPacket so type-0 payload dwords are not taken for headers, and the listing checks open, write, flush and close of its output file, naming the path and exiting nonzero on failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… check On Linux libc prints its host CPU line to stdout, so the check that a failed write left stdout empty failed even though the tool reported the failure and exited 2. Check that no success summary was printed instead, as the blocked output case does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…red GPU range On Windows the startup thread stacks can sit inside a captured GPU-visible range, which the replay must map at its captured address. Start the replay again with a fresh address-space layout, up to 8 times, before mapping any memory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
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.
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.
|
|
Overlap with #11436 in As agreed for #12567, I'd propose #12696 lands after #11436 and declares |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…/frame-replay-inspect Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…collision Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@Sam-mon7, thanks. I merged your Same focused pattern as yours, Windows 11, RTX 3080 (NVIDIA 621.01), full builds with submodules synced: AI-assisted: yes (Claude Code) |
❌ NVIDIA GPU test: failedPR head
New validation errorsThis PR changes test files, so each test below was also run on main with only the PR's test changes applied; 0 there means the PR's other changes cause the error.
agc_driver_frame_replay_concurrent: new validation messagesUnstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (2, not counted against this PR)Validated but not compared (7, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 425 tests)Skipped (42)ReproduceAutomated 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. |
Move the frame replay test registrations this branch changed into main's new tests/cmake fragments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
❌ NVIDIA GPU test: failedPR head
New validation errorsThis PR changes test files, so each test below was also run on main with only the PR's test changes applied; 0 there means the PR's other changes cause the error.
agc_driver_frame_replay: new validation messagesagc_driver_frame_replay_concurrent: new validation messagesUnstable on main (2, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (4, not counted against this PR)Validated but not compared (7, not in the main baseline's validation pass)Validation IDs already present on main (5 IDs in 476 tests)Skipped (44)ReproduceAutomated 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. |
# Conflicts: # core/libs/prx/libSceAgcDriver/tests/cmake/agc_driver_frame_replay_tests.cmake
❌ NVIDIA GPU test: failedPR head
New validation errorsThis PR changes test files, so each test below was also run on main with only the PR's test changes applied; 0 there means the PR's other changes cause the error.
agc_driver_frame_replay: new validation messagesagc_driver_frame_replay_concurrent: new validation messagesUnstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validated but not compared (5, not in the main baseline's validation pass)Validation IDs already present on main (5 IDs in 484 tests)Skipped (45)ReproduceAutomated 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. |
…unch-host-collision Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for isolating the Windows replay retry. Could you validate Two smaller notes on the description: the branch also carries |
… limit An inherited negative or malformed APS5_FRAME_REPLAY_ATTEMPT went through atoi, so the limit of eight relaunches did not hold, and a failed _putenv_s restarted the budget in the child. The count now has to be a whole number from 0 to 8, and the relaunch stops when it cannot be passed on. The new Windows test links without high-entropy addresses so its stack is an arena host region in every process, and covers the eight-relaunch limit, malformed counts and exit codes through the chain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@oneandonlydean Thanks, all done in
Exact-head results are in the description: 19 of 19 with the validation layer. Without it, 18 of 19, because AI-assisted: yes (Claude Code) |
…unch-host-collision Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
❌ NVIDIA GPU test: failedPR head
New validation errorsThis PR changes test files, so each test below was also run on main with only the PR's test changes applied; 0 there means the PR's other changes cause the error.
agc_driver_frame_replay: new validation messagesagc_driver_frame_replay_concurrent: new validation messagesIntermittent 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)Unstable on main (4, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validated but not compared (4, not in the main baseline's validation pass)Validation IDs already present on main (5 IDs in 484 tests)Skipped (45)ReproduceAutomated 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. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ AMD GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (12, not counted against this PR)Passed on retry (1, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)Validated but not compared (2, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 514 tests)Skipped (54)ReproduceAutomated 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. |
✅ NVIDIA GPU test: passedPR head
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validation IDs already present on main (4 IDs in 519 tests)Skipped (48)ReproduceAutomated 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. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ NVIDIA GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validation IDs already present on main (9 IDs in 595 tests)Skipped (54)ReproduceAutomated 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. |
✅ AMD GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (9, not counted against this PR)Validation IDs already present on main (4 IDs in 563 tests)Skipped (60)ReproduceAutomated 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. |
What
Review only
df74f29c46,89db2b5ae2,93123ef32cand9a2b40f233. The rest is #11436 (at752958c135), merged in because it lands first, as agreed with Sam-mon7. Whichever of the two lands first, the other needs a merge ofmain.On Windows,
agc_frame_replayfails about 1 run in 30 at startup withfixed guest mapping 0x2324a0000+0x133d80000 overlaps a host region in the guest arena. #3371 diagnosed the cause: the main thread's stack and the loader's thread stacks exist before libc reserves the guest arena, and withHIGH_ENTROPY_VAWindows places them anywhere in the first TiB, so the arena keeps them as host holes. A title can avoid them. #3683 moved the AMM ranges to the highest free window for that reason. A replay can't, because it has to map each captured range at its captured address. A host hole inside a GPU-visible range is fatal, while other ranges are skipped.relaunchIfHostRegionBlockschecks the GPU-visible captured ranges withGuestArenaHostRegionOverlaps_nid_postfix. If one overlaps a host region, the replay prints the range, starts its own command line again (the new process gets a fresh ASLR layout), waits for it and exits with its exit code.APS5_FRAME_REPLAY_ATTEMPTcounts the attempts; after 8 the replay continues as it does today and reports the overlap. The count must be a whole number from 0 to 8, otherwise the replay stops with an error, and a relaunch stops if the count cannot be passed to the next process.run(), and the logic doesn't overlap. This branch now includes feat(agc): list a capture's shaders and submissions and trace replay serials #11436, with that conflict resolved by keeping both insertions.93123ef32cis part of this PR:SKIP_RETURN_CODE 77onagc_driver_frame_replay,_cold_pipelines,_reservation_errorand_concurrent, so they skip on a runner with no Vulkan driver.0x7f…, and Windows: guest_ampr_markers fails intermittently with a fixed guest mapping at 0xec00000000 overlapping a host region #3371 saw no collisions there.HIGH_ENTROPY_VAfor the replay, as fix(relinker): keep Windows startup stacks below the guest arena #679 did for relinked titles, doesn't help: it moves the stacks to about 0x5ff000-0x1c6f000, inside the title image range at 0x400000 (fix(relinker): prefer 0x400000 for Windows executables #9332) that every capture maps. That range is not GPU-visible, so the replay then skipped 51.7 MiB of it on every run, where it normally skips none.Tested
Windows 11 Pro 26220, WinLibs MinGW-w64 GCC 15.2.0, Release, RTX 3080, GTA V (PPSA04263) frame capture.
skipped_mib0.0, exit 0. Run 16 hit the same range, 0x2324a0000+0x133d80000, relaunched once and finished normally.--disable-high-entropy-va, every attempt overlaps the 0x400000 range. It relaunched 8 times, then continued down the normal path and exited 0. All 9 processes wrote to the same redirected log, and none was left running.python3 tools/check_conventions.py --base origin/mainpasses.ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ctest --test-dir build -R '^agc_(frame_capture|driver_frame_capture_eop|driver_frame_replay)' -V:mainat466bf10f7f: 11 tests, all passed, 0VUID-lines; this branch at501b4fdf2dmerged into it (e022558084): 18 tests, all passed, 0VUID-lines. Neither log containswas not found but was requested by env var VK_INSTANCE_LAYERS.4c144e8108(merged withmain5bae1a4bc2), RTX 3080, with the command above: 19 of 19 tests passed, 0VUID-lines, no missing-layer message. Without the layer, 18 of 19:agc_driver_frame_replay_reservation_errortimes out, which is the Windows exit hang fix(agc): shut the driver down before frame replay exits with an error #14100 fixes.agc_driver_frame_replay_relaunch: linked with--disable-high-entropy-va, so its stack is an arena host region in every process. It relaunches eight times and then continues, with the count seen by each process checked; passes a failing exit code (42) back through all nine processes; relaunches once from 7 and not at all from 8; and exits 2 without relaunching for-1,-2147483648,9,99999999999,abc,1x,1and+1. It passed 5 of 5 runs. Negative control: with the oldatoiline restored it fails with-1: exited with 0. It skips with 77 if the stack is not a host region. A failed_putenv_sis not covered.93123ef32c: on the previous headf2ba0a7c78, with the RTX 3080 they ran and passed; withVK_DRIVER_FILESandVK_ICD_FILENAMESpointing at a missing file, all four reportedSkipped. That no-Vulkan run was not repeated on9a2b40f233or4c144e8108, which do not touch them._WIN32).Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code