Skip to content

AGC: ProsperoAI (PPSA99004) aborts on its first runs on AMD: a 403k-word fragment shader's pipeline library takes 8+ s to build and the title's 10 s GPU wait gives up #6742

Closed

Description

@LeandroLP23

ProsperoAI (PPSA99004) aborts about 18 s in on its first runs on a Radeon 860M, and runs once the driver and emulator caches are warm. The build of one fragment shader is what goes past the title's own 10 s wait.

Setup. Windows 11 Home 26300, AMD Radeon 860M (RDNA 3.5, 1002:1114, driver 32.0.13058.8001), WinLibs GCC 15.2.0, Release, main 5d9dcc42d. Catalog release 01.005.000, relinked with --windows --trap-sdk-syscall-stubs (without the flag the relinker stops on a raw syscall at code offset 0x10e3937, as for the other ps5-payload-dev titles in #2136). 40 s runs, no input.

What happens. A fresh run folder, with %LOCALAPPDATA%\AMD\VkCache emptied first (and restored afterwards):

Run Result
1 (cold) radv/ps5: the GPU has not reached submission 2 (at 1) in 10 s (twice), [ProsperoVKUI] vkQueueWaitIdle(queue) failed: -4, abort(), exit 0xc0000409 after 18–20 s
2 alive at 40 s, 7.90 FPS
3 alive at 40 s, 8.05 FPS

With the driver cache left as it was from other titles, the first two runs both aborted the same way and the third ran, at 7.89 FPS. So it takes one or two runs to warm up.

Where the time goes. I added a local timer (not proposed) around the vkCreateGraphicsPipelines calls in PipelineLibrary.cpp and printed the SPIR-V size of each stage over 50,000 words in Pipeline.cpp:

  • The first draws prepare seven graphics shaders at first use (0x201320000 … 0x201320f00, ReportPreparedAtUse). Exactly one stage is large: a fragment shader of 403,216 SPIR-V words.
  • On a cold driver cache, building that shader's fragment-shader library took 7,951 ms in one run. In two other cold runs it had not finished when the title aborted, 10 s after its submission.
  • On the next run the same library took 877 ms, and the pre-rasterization library 570 ms. After that no build passed 500 ms.

The title is a Vulkan UI over the PS5 RADV port (radv/ps5), which waits 10 s for a submission's fence before it gives up. Submission 2 waits behind the draw that needs this pipeline. So the stop is the same kind as #6118 (FSR4 Showcase, compute pipelines), #5876 (Surround Sound Studio, a 447k-word fragment library) and #4399: a pipeline that only an uncached first run has to build, under a guest timeout.

Fixes in flight that target this kind of stop: #5925 (submission lookahead) and #5875 (journal a run's pipelines and build them ahead on the next one). Neither helps a very first run, which still has to build the library once inside the title's budget.

Not tested: other GPUs (on Linux with an RTX 2070 the title runs, per the catalog report in #5745); which part of the 403k words dominates the build; a build from before the recompiler changes that grew this shader.

AI-assisted: yes (Claude Code)

Activity

  1. LeandroLP23 commented on Oct 17, 2026

    @LeandroLP23
    ContributorAuthor

    Rechecked on main 6a32550fd, which now has the pipeline journal (#5875) and lazy shader preparation (#5872). Same machine and relink (--windows --trap-sdk-syscall-stubs), 60 s runs, VkCache emptied before each run:

    Run Shader cache Result
    1 empty abort at 24 s: radv/ps5: the GPU has not reached submission 2 (at 1) in 10 s
    2 run 1's, with its journal [pipeline-journal] loaded 4 pipelines and 9 modules, then the same abort at 20 s
    3 run 2's same as run 2

    The journal doesn't carry this case over: the slow pipeline library is still building when the title gives up, so it never completes and is never recorded, and every run that starts without the driver's cache stops at the same place.

    AI-assisted: yes (Claude Code).

  2. plokmklo commented on Oct 18, 2026

    @plokmklo
    Contributor

    Root cause found, fix on https://github.com/plokmklo/AnyPS5/tree/contrib/6742-prosperoai (commits 687c3f91e, 2f5e87161).

    The journal was designed to carry pipelines across runs, but it recorded one only after its build completed. A pipeline whose cold build outlives the title's GPU wait — the fragment-shader library here, #6118's compute pipelines, #5876's 447k-word library — therefore never completed, never got journaled, and every run that started without the driver's cache repeated the same build and the same abort. That matches the recheck: the journal loaded 4 pipelines, but the slow one was still building when the title gave up, so it was never in the file.

    The fix records a graphics pipeline at the store miss that requests it (before vkCreateGraphicsPipelines runs) and a compute pipeline when its build starts, so a pipeline whose build is interrupted still reaches pipelines.journal — written seconds before the abort, durable across it. The replay now also builds the largest SPIR-V modules first, so the expensive fragment library starts at device creation instead of last. Content dedup keeps the journal from growing per run. A regression test blocks a library build mid-flight and requires the recipe to be journaled while it is still building, then replays it on a simulated next run.

    What I could not verify without an AMD/Vulkan box: whether run 2 survives when the cold build (~8 s) is longer than the head start between device creation and the pipeline's first use (~10 s in the trace). If it doesn't, a draw currently builds a second copy instead of joining the replay's in-flight build — that join is the natural next step, and a warm driver cache covers run 3 regardless. The 403k words themselves are untouched: a title-side dump of that program would settle whether a pre-recompiler-change build produced a smaller shader.

  3. LeandroLP23 commented on Oct 20, 2026

    @LeandroLP23
    ContributorAuthor

    This no longer reproduces on current main, and the fix branch passes too. Both were run on the same machine as the report: Radeon 860M (driver 32.0.13058.8001), Windows 11 26300, WinLibs GCC 15.2.0, Release, ProsperoAI 01.005.000 relinked with --trap-sdk-syscall-stubs. Each run lasted 45 s with no input.

    Each tree got a three-run sequence. AMD's VkCache was moved aside for the sequences and restored afterwards.

    1. Driver cache, AnyPS5 shader cache and journal all empty.
    2. Driver cache emptied again, with the journal and shader cache from run 1 kept. This is the case @plokmklo couldn't check.
    3. Everything warm.
    Tree Run 1 (cold) Run 2 (journal only) Run 3 (warm)
    main aa1b1bf runs, no abort runs, no abort runs, no abort
    main + plokmklo's 687c3f91e, 2f5e87161 runs, no abort runs, no abort runs, no abort

    In an extra cold run on plain main, a screenshot at 35 s shows the full Workspace screen ("Big ideas. Right here.", the four model tiles) at about 11 FPS, with no has not reached submission line. So on main the slow first pipeline no longer outlasts the title's 10 s wait here. I haven't bisected which change did it.

    @plokmklo, thanks for digging into this. Recording a pipeline when its build starts still covers a real gap: the journal only learns a pipeline once its build completes. #6118's compute pipelines and the 447k-word library in #5876 may still need it. That looks worth a PR of its own, measured on one of those. I'll close this issue since the title runs, and reopen it if a cold run aborts again.

    AI-assisted: yes (Claude Code)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions