Repository navigation
Conversation
|
I traced the new scan against the driver paths: I did not find a concrete correctness issue in the diff. I attempted the focused Linux build locally, but GCC 12 stops earlier in unchanged |
|
One small regression-coverage gap: in Could the fixture queue the bound preparation through |
|
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.
|
jotitadev
left a comment
There was a problem hiding this comment.
A Linux run of the regression, which the description (Windows) and the review above (GCC 12 stopped before it) do not have.
Machine: NVIDIA GeForce RTX 3070, driver 595.99.02, Vulkan 1.4.329, plus lavapipe (Mesa 26.0.3, LLVM 21.1.8) on the same machine. Ubuntu 26.04, i7-8700, GCC 15.2, Release, BUILD_TESTING=ON. Head 20cc5ae56 merged into main 452494439 (clean merge). The build of PreparedShaders.cpp and the changed driver sources goes through on GCC 15.2.
agc_driver_prepared_shaders: 3/3 pass on the RTX 3070 (Selected GPU name=NVIDIA GeForce RTX 3070) and 3/3 on lavapipe, about 3.4 to 3.9 s per run (1.1 s onmainwithmain's test).^agc_driver_(prepared|registered), 18 tests,-j1: 18/18 on both devices, no skips.- No negative control: with
main'sSubmission.*andShaderRegistry.*the new test does not compile (ReferencedProgramsis not a member ofAgcDriver::DriverDetail).
This does not address the coverage gap raised above (the bound snapshot's own task queued in RegistrationPreparePool); I did not try that variant.
Not run: Windows, AMD, the full suite, any title.
GPUs tested: NVIDIA GeForce RTX 3070 (595.99.02), lavapipe (Mesa 26.0.3, LLVM 21.1.8), Ubuntu 26.04
Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.
|
Thanks, good catch. 7241b05 now queues the bound preparation through |
|
Timed this on Ghost of Yōtei (PPSA26344) on Linux with lavapipe, cold shader cache on every run, base and PR runs interleaved: Base averages 221 s and the PR 171 s (2 runs each), so the first frame came about 50 s (23%) earlier. The ranges do not overlap (base 211–231 s, PR 161–181 s). The time comes from a memory probe that logs every 10 s, so each value can be up to 10 s after the actual first frame. Setup: both builds are For comparison, your Windows runs had the first frame at 40 s with this PR against 101 s on AI-assisted: yes |
|
Data point: RTX 3060 12 GB (NVIDIA 617.42), i5-12400F, Windows 10 19045, MinGW GCC Release. Minecraft Dungeons II (PPSA16064 01.100.100), title screen, no input, 200 s rows,
Neutral on this scene (mean +0.7 %, within the row spread); no regression. 0 fatal. AI-assisted: yes (Claude Code) |
|
I have an independent follow-up in progress for #8470: at shutdown, finish the running library prebuild but discard queued speculative prebuilds, leaving registration preparation and device-replacement waits unchanged. The candidate touches |
CnRJay
left a comment
There was a problem hiding this comment.
The result is large and measured (Ghost of Yotei, cold cache, first frame 101 s to 40 s, first submission wait 76.3 s to under 3 s), and moving a bound program's preparation to the front of the queue (#4404) is the right use of the scan. The part I would not merge as is is the fallback.
- #5007 made
Driver::Submitwait for every queued preparation for one reason: a title that sees a submission take seconds treats the GPU as hung. Goat Simulator 3 (PPSA04159) failed a 10 s timeout when the wait sat in the queue worker. Waiting "in the queue worker at first use" is what this PR leaves for any program the scan misses: bound by an earlier submission, a half-written address, an address reached another way, or an indirect buffer the scan didn't follow. Those cases reproduce the Goat Simulator situation (the GPU side of a submission blocked on a long preparation), and the PR does not say how long such a wait can be. The cold-cache 55,144-dword shader this was found on took 74 s on one thread. If a program the scan misses is bound by a draw, the queue worker blocks for that long. - Please add a test where the program is reachable only through a path the scan doesn't see (address written in two halves across submissions; address in an indirect buffer), with a slow preparation, and state the resulting wait. If it is long, the scan needs the missing paths, or the fallback needs a bound (after N seconds, report and continue).
- The 2.6 s longest wait for 83 bound programs is still a seconds-long submit. It is under the 10 s limit that failed, but the margin is a property of this title on a 4090; a slower machine's cold cache would be longer. State the worst wait by machine, or the time the scan assumes.
- The numbers are from a tree with #6227 and two local diagnostics. The runs are cold-cache only. Post a warm-cache pair as well to show the scan costs nothing when preparations are already done (
ReferencedProgramswalks every copied command on every submit). - Marked conflicting with
main; rebase before it can be tested again.
|
Follow-up to my lavapipe timings above, now on an NVIDIA GPU, with the warm-cache pair @CnRJay asked for. Ghost of Yōtei (PPSA26344), RTX 3080 Ti (driver 615.78.08), Linux. The base build is Cold shader cache (deleted before every run), 3 runs each: On Warm shader cache (each build reusing its own cache from its previous run), 2 runs each: With a warm cache, the PR's median, p90 and present count are no worse than What this does not answer from the review:
How the PR was applied: 20cc5ae does not cherry-pick cleanly onto 2b3baac. It conflicts in Caveats:
AI-assisted: yes |
…st from raw code 0x8000083400 (Pipodi's 74 s structurizer front end in boykopovar#6867) has no capture: only its raw guest code (shader_samples/main-8000083400.bin) and its registration environment (sweep/programs/32ac8b907b12797b.env) exist. --make-request <target.req> <shader.bin> <shader.env> <address> <out.req> writes a standalone compute request from them with a captured request's target, the same reconstruction as the earlier --prepare-pair-raw (4fa3b17e1): header omitted, user data zero. The result replays through every existing mode (--prepare-only, --spv, --materialize).
7241b05 to
d5bcd0c
Compare
|
This pull request is labeled |
… submission binds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
08fe590 to
447087a
Compare
|
@Pipodi A gap in the register list at head 447087a, found while reading the PR for a PS4 GCN title (Crysis Remastered, CUSA18659).
constexpr std::array<std::uint32_t, 6> programRegisters{0x008u, 0x088u, 0x0c8u, 0x108u, 0x148u, 0x20cu};
Effect: a submission whose draws bind a VS pair together with a PS pair (the usual shape on GCN) sets a graphics pair through Adding I have not run the branch; this is from reading the code. The rest of the scan (the indirect register lists, the REWIND fallback) looked consistent to me. AI-assisted: yes |
✅ 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 (4, 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)Validation IDs already present on main (5 IDs in 484 tests)Skipped (46)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. |
|
I reproduced @ntamas94's missing ccb8e15fa76 — include classic vertex programs in preparation scans. This commit is directly on your PR head, changes the scan's array from six pairs to seven, and keeps Regression control: the identical frozen test executable ( Linux gates: the AGC code from main I also replayed one private Severed Steel post-movie frame with the fixed integration: both display-buffer references match pixel-for-pixel, maximum channel difference 0, zero unfinished submissions and zero synthesized waits, with validation mapped and 0 VUIDs. This is a rendering-correctness check on the recorded workload; a cold-cache title comparison remains necessary for a title speed claim. Patch, synthetic GPU-test logs, JUnit, hashes and numeric replay receipt — SHA-256 GPU: AMD Radeon RX 6650 XT (RADV NAVI23), Mesa |
|
Native cold-start pilot for PPSA05106, Severed Steel 01.000.000, following the classic-VS follow-up above. The candidate is this PR at With identical saves/settings, no injected inputs, empty private shader/Mesa cache directories and Mesa disk caching disabled, the first reviewed Campaign-menu screenshots were:
All three runs closed normally with exit 0 and passed protected-input/SDK/generated-module, kernel-restoration and process-cleanup checks. Native stdout remained on a PTY. A two-second host sampler saw no compiler process samples; a stopped CMake process and brief Ninja appearances are documented in the receipt, so exclusive machine use is not claimed. Completed main/change traces, summary lines, trace digests, menu images and pilot receipt, SHA-256 The completed traces have the same Coverage limit: the profiler starts at the first present. Its recording message was observed about 73–75 s into baseline startup and about 4 s into candidate startup. Earlier work is absent, so these traces cannot supply whole-startup shader-compilation time, and their aggregate FPS mixes loading and menu time. This is an earlier-menu observation in one candidate run, not a gameplay-FPS result. Baseline SDK |
|
@ntamas94 thanks, confirmed: @JJenkx thanks for the fix and the tests. I cherry-picked ccb8e15 unchanged, with you as the author, and thanks for the Severed Steel cold-start numbers (160.2 s -> 130.0 s to the Campaign menu). New head |
XairRrR
left a comment
There was a problem hiding this comment.
Reviewed — approved
The merged tree builds, and all 24 agc_driver_prepared_shaders* tests pass with the Khronos validation layer. Three targeted negative controls each fail with the expected message, and the one new VUID in the script's comparison also appears with main's production files.
What I ran
Head 36fc8f9cc93098b621694564d4432fc9a3973c75, main 4f41f4c375f5abb487dbd184fbc150f31994d762, merged tree 2e2c8ac56814ee32fb9eab40be05cf8b4c32771d, in a clean worktree. Debian 13 VM, 2× Xeon Gold 6136 (32 vCPU), GCC 14.2.0, Release, lavapipe (Mesa 26.1.6, LLVM 19).
git diff --check 4f41f4c375f5abb487dbd184fbc150f31994d762...36fc8f9cc93098b621694564d4432fc9a3973c75
python3 tools/check_conventions.py --base 4f41f4c375f5abb487dbd184fbc150f31994d762
VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ANYPS5_NO_SHADER_CACHE=1 ANYPS5_REQUIRE_VULKAN=1 VK_LOADER_DEBUG=error,warn,layer \
ctest --test-dir build -j8 --test-load 32 -V -R "agc_driver_prepared_shaders|agc_driver_native_depth_uniform_planes"
# main's four production files restored (Submission.hpp/.cpp, ShaderRegistry.hpp/.cpp):
ninja -C build -j32 -l32 libs agc_driver_native_multisample_depth_tests agc_driver_prepared_shaders_tests
VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ... ctest --test-dir build -V -R "^agc_driver_native_depth_uniform_planes$"
# partial controls on the merged Submission.cpp, each rebuilt and run as build/tests/agc_driver_prepared_shaders_tests
# finally the merged files restored, rebuilt, test rerun, git status --porcelain
Results
| Check | Result |
|---|---|
git diff --check |
clean |
check_conventions.py |
all checks passed |
Configure / build / libs (script) |
ok |
| Script test run (2169 tests) | no new failures, no timeouts; 7 known failures that also fail on main |
agc_driver_prepared_shaders* (23) + agc_driver_native_depth_uniform_planes, with validation |
24/24 pass; the layer loaded; agc_driver_prepared_shaders 9.3 s (longest of the four *_shaders variants: 10.1 s), all under 30 s |
Waits measured by UnprovenProgramsAtSubmit on this machine |
low-only 1500 ms, high-only 1500–1505 ms, low-only through an INDIRECT_BUFFER 1500 ms, proven pair 0 ms |
Script's validation comparison, new VUID in agc_driver_native_depth_uniform_planes |
not caused by this PR: the same 4 VUID-vkCmdDispatch-groupCountX-00386 errors appear with main's production files (the baseline run was on an older main, d1ae628bc2, where this test did not run) |
VUID check with main's production files
ctest -R ^agc_driver_native_depth_uniform_planes$ -V -> exit 0
Validation Error: [ VUID-vkCmdDispatch-groupCountX-00386 ] x4 (same count as the merged tree)
Insert instance layer x4
Negative control
When main's four production files are restored, the test does not compile ('ReferencedPrograms' is not a member of 'AgcDriver::DriverDetail'), as jotitadev already reported. So I changed single lines in the merged Submission.cpp instead, rebuilding and running the test after each change:
| Change | Result |
|---|---|
0x048u removed from programRegisters (the classic-VS fix taken from JJenkx) |
fails: a pixel and classic vertex program pair did not both reach the submit preparation wait |
Submit always waits for every queued preparation (main's behaviour) |
fails: a submission writing a whole program address waited for an unrelated preparation |
!scan.complete fallback removed |
fails: a submission writing half of a program address did not wait for the queued preparations |
Afterwards I restored the merged file and rebuilt. The test passes again, and git status --porcelain is empty. This confirms on Linux and lavapipe the controls jotitadev ran and the classic-VS regression JJenkx reported.
Findings
Blocking
None.
Non-blocking
- The Yōtei traces are not attached. CONTRIBUTING asks a
perfPR to attach its traces. The description has both summary lines and a digest table, but says the traces "are kept locally and can be shared on request". JJenkx's archive has amain/change trace pair, but it is for Severed Steel. Suggested fix: attach the twoaps5-trace-*.json.gzfiles that the summary lines name. - The measured revision is older than the head. The Yōtei numbers come from
4703b22bde. Since then the branch gained the pool-ownership wait (761ef1105e) and the0x048vertex pair. The0x048fix makes submit wait for more programs. So the "3.2 s longest, 7 s total" figure indocs/dev/debt/libSceAgcDriver.md:333may be too low for the current code. Suggested fix: re-measure, or say in the debt entry which revision the figure is from. - The Unblocks line has no discussion link. The line names PPSA26344 but not its Game bring-up discussion (
Unblocks: PPSAxxxxx #N), which CONTRIBUTING asks for.
What I checked in the code without finding a problem:
AwaitReferencedPreparations(core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp:1919) uses the sameupper_boundand code-range lookup asRegisteredProgram.AwaitOwned(ShaderRegistry.cpp:1658) waits on the pool'sunfinishedsequences under the pool mutex.ownedis cleaned up both when a worker finishes a task and when queued tasks are dropped. Thependingcheck takesprepared.mutexand releases it before the pool lock, so the two locks are never held together.ReferencedPrograms(core/libs/prx/libSceAgcDriver/Execution/src/Driver/Queues/Submission.cpp:229) builds the address the same way asBoundGraphicsPrograms, and its register list now matchesBoundGraphicsProgramsplus0x20c.
Not verified
- Hardware GPUs: I ran only on lavapipe.
- Any title, and the Yōtei and Severed Steel timings.
- How long submit waits are under the current head on a real workload.
- The full test suite: I ran only the tests this change reaches.
✅ NVIDIA GPU test: passedPR head
Unstable on main (2, 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 517 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. |
|
AMD Windows run of this head (the RX 9070 XT run above was on
Not run: Ghost of Yōtei or any other title, so no speed figure; negative controls; a AI-assisted: yes (Claude Code) |
✅ 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 (7, not counted against this PR)Validation IDs already present on main (8 IDs in 544 tests)Skipped (58)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. |
…ration-wait-1025 # Conflicts: # core/libs/prx/libSceAgcDriver/Execution/src/Driver/Queues/Submission.cpp
✅ NVIDIA GPU test: passedPR head
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)Validation IDs already present on main (9 IDs in 556 tests)Skipped (55)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
Failing on main too (6, 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 (56, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 547 tests)Skipped (109)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 (2, 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)Passed on retry (2, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)Validation IDs already present on main (9 IDs in 592 tests)Skipped (51)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. |
What
Driver::Submitwaits on the submitting thread only for the registration preparations of the programs the submission binds, and moves each to the front of the queue (PrioritizeRegistrationPreparation), instead of waiting for every queued preparation (#5007). The scan reads the program address registers (SPI_SHADER_PGM_LO/HIof the pixel, geometry, export, hull and local stages,COMPUTE_PGM_LO/HI) written bySET_SH_REGand bySET_SH_REG_INDIRECTlists, including packets insideINDIRECT_BUFFERandCOND_INDIRECT_BUFFERtargets (they are copied into the submission before the scan).Rebased on
mainbb04a4f1ea. The pool part reusesmain'sPrioritizeRegistrationPreparation, as Dextroid17's port did.AwaitRegistrationPreparationand the pool's sequence tracking stay as they are, because the wait-for-all fallback below uses them. The pool also records which preparation owns each queued or running task, so the submit wait can wait for that task.Change since the review: a submission that writes only one register of a program pair (the other half came from an earlier submission) is not proven by the scan. It now waits for all queued preparations at submit, as
maindoes, instead of leaving that program to an unbounded wait in the queue worker at first use (CnRJay's #5007 concern). A bound after N seconds was not chosen: continuing without the program would skip the draw, which is invented behaviour.Change since jotitadev's run on 10-27: the wait for a bound program waited on its snapshot's
settledcondition wheneverpendingwas set. A preparation marked pending with no pool task, asagc_driver_prepared_shaders_dispatch_ahead_prewarm(#8735) does, was never settled, and the submission hung. The wait now moves the program's pool task to the front and waits for that task to finish. It does not wait for a preparation the pool does not hold.The scan also falls back to the wait-for-all when it cannot see every program the submission uses: the submission ends in a
REWIND(the tail is copied later in the queue worker), aSET_SH_REG_INDIRECTlist has an invalid register (the worker reads such a list again at execution), a draw (a dispatch) comes before any graphics (the compute) program pair written in the same submission, so the program may have been bound by an earlier submission, or a program address is written by a predicatedSET_SH_REGor one inside aCOND_EXECrange, which may not run.Not covered, and recorded in the technical debt entry: a draw that writes one graphics pair but also uses a stage bound by an earlier submission, and a program registered again at an address an earlier submission bound, then used without rebinding while the submission writes a different graphics pair. Their first draw waits in the queue worker with no bound. The longest preparation seen is 74 s on one thread (cold, 55,144-dword shader, Ghost of Yōtei), and a submission that binds such a shader waits as long at submit. A submission the scan cannot prove waits for every queued preparation, as on
main(76.3 s first-submission wait on Yōtei, cold, earlier measurement). The measured waits below are machine and cache dependent; no bound is claimed.Tested
Tests on the rebased branch (Windows, MinGW GCC 15.2, Release, RTX, ANYPS5_REQUIRE_VULKAN=1)
^agc_driver_(prepared|registered), 28 tests,--repeat until-fail:3: 28/28 (a3c2759); the fouragc_driver_prepared_shaders*variants pass again on ccbf4f2.maine5f2355 and on this branch,ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ctest -R "^agc_driver_(prepared|registered)" -V: 28/28 on both. Neither log has the "was not found but was requested" line. Both logs have the same 14VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605errors, all inagc_driver_prepared_exports, so this branch adds no new validation errors.UnprovenProgramsAtSubmit(inagc_driver_prepared_shaders): a slow (1500 ms) queued preparation, then a realsceAgcDriverSubmitDcb:SET_SH_REG)INDIRECT_BUFFERtargetREWIND(tail not scanned)The rows prove the early return or the wait by whether the preparation had finished when Submit returned, not by a time bound. Scan-level rows cover an invalid indirect list, a draw or dispatch with no pair written before it in the submission (a bind by an earlier submission and none now), a predicated pair, a pair inside a
COND_EXECrange (not complete, no address resolved), and a pair after aCOND_EXECrange that holds only another register (still complete). The invalid-list fallback is tested at scan level only: through Submit, the queue worker throws on such a list ("indirect register sentinel semantics are not implemented"), so it never reaches the wait.if (false && !scan.complete)) the test fails at the first row ("a submission writing half of a program address did not wait for the queued preparations"); with the REWIND fallback removed it fails with "a submission ending in a REWIND did not wait ..."; with the draw/dispatch check disabled it fails with "a dispatch that binds no program in its submission was reported as fully scanned"; without the predication check it fails with "a predicated program pair was reported as fully scanned", and without theCOND_EXECcheck with "a program pair inside a conditional execution range was reported as fully scanned". In that state the program would be waited for at first use in the queue worker, for the whole remaining preparation (1500 ms here; 74 s for the cold shader above).AwaitedRegistrationPreparation(main's ticket-rule test) is kept.mainbb04a4f): 3028/3029;guest_freebsd_clocksaborts with 0xc0000409 as in Tests: guest_freebsd_clocks aborts where the host zone is not UTC #12736 (host zone not UTC), a libkernel test this branch does not touch.agc_host_import_cut_lifetimeandagc_driver_depth_plane_partial_storefail; both fail the same way on plainmaine5f2355 on this machine.Ghost of Yōtei, this revision, cold: total submit wait 182 s → 7 s, first wait 49–52 s → 1 s
Windows, RTX 4090, driver 617.42. Both builds have a fully cold recompiler cache and a drained NVIDIA pipeline cache, a fresh profile, and the same environment. Each run is 900 s. A is
maine5f2355 (run499, and run501 as a rerun for the trace). B is this branch, 4703b22 (run500). Both builds carry the same local log line for submit waits of 100 ms or more; it is not part of this PR. On plainmainthe intro stays dark for the whole 900 s in all three runs, with or without this PR, so first-lit-frame times are missing.main)Frame 330 is later in B because a 116 s compute compile stall (shader 0x8000196500, the same in both builds) falls earlier there; this PR does not change compile times.
Trace digest, frames 100–200, queue worker (the hottest thread), inclusive ms per frame, A (run501) / B (run500). The window covers 277 s in A and 258 s in B.
The worker waits a third as long for preparations. That time now goes to compiling pipelines that are no longer held back behind the submit wait, so per-frame work in the window is higher, not lower.
Summary lines of the two traces above (aps5-summary.jsonl, frames 100–200)
maine5f2355 (run501), then this branch 4703b22 (run500). Both are markeddirtybecause both builds carry the local submit-wait log line described above. 4703b22 is the measured revision; the head since adds only the fix for a pending preparation with no pool task (761ef11), and was not remeasured. The traces are kept locally and can be shared on request. Thetitlefield is written asY\u014dteihere; the summary writer had stored it double-encoded (\u00c5\u008d), which GitHub does not keep intact.{"commit":"e5f23554c9c7","dirty":true,"env":{"APS5_GPU_CHECKPOINTS":"1","APS5_HOST_IMPORT_MIB":"16384","APS5_NO_PIPELINE_JOURNAL":"1","APS5_NO_RESULT_MEMO":"1","APS5_NO_SNAPSHOT_CHECK":"1","APS5_PIPELINE_DISPATCH":"1","APS5_PREBUILD_THREADS":"2","APS5_PREPARED_SPIRV_MIB":"6144","APS5_PROFILE_DRAW":"1","APS5_RESOURCE_CACHE_ENTRIES":"1024","APS5_SPANNED_WAVE":"1","APS5_STAGING_POOL_MIB":"2048","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_FRAMES":"100:200"},"gpu":"NVIDIA GeForce RTX 4090","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","cpu":"13th Gen Intel(R) Core(TM) i9-13900K","cpu_threads":32,"memory_mib":32476,"title_id":"PPSA26344","title":"Ghost of Y\u014dtei","content_version":"01.008.000","resolution":"3840x2160","window":{"spec":"frames 100:200","first_present":100,"ms":277022.035},"presents":200,"frame_ms":{"p50":128.075,"p90":1197.832,"p99":41793.606,"max":90343.336},"gpu_busy_ms_per_present":78.271,"worker_busy_pct":{"queue worker 0x0":64.237,"queue worker 0x52":3.601,"queue worker 0x53":0.792,"queue worker 0x20":16.643,"queue worker 0x30":32.427,"queue worker 0x38":25.118,"queue worker 0x48":8.323},"top_phases_ms_per_frame":{"Shader.PrepareArtifact":5975.056,"Driver.Packet":2091.511,"Driver.Packet.dispatch":1004.043,"Driver.Dispatch":979.062,"Driver.Packet.memory_wait":912.059,"Vulkan.ComputePipeline":824.439,"Vulkan.GraphicsPipeline":98.891,"Graphics.Draw":76.754},"trace_dropped":true,"trace_dropped_threads":{"title":{"events_full_after_s":69.232,"events_lost":19632,"totals_full":false}},"trace":"aps5-trace-e5f23554c9c7-39372.json.gz"}{"commit":"4703b22bde3c","dirty":true,"env":{"APS5_GPU_CHECKPOINTS":"1","APS5_HOST_IMPORT_MIB":"16384","APS5_NO_PIPELINE_JOURNAL":"1","APS5_NO_RESULT_MEMO":"1","APS5_NO_SNAPSHOT_CHECK":"1","APS5_PIPELINE_DISPATCH":"1","APS5_PREBUILD_THREADS":"2","APS5_PREPARED_SPIRV_MIB":"6144","APS5_PROFILE_DRAW":"1","APS5_RESOURCE_CACHE_ENTRIES":"1024","APS5_SPANNED_WAVE":"1","APS5_STAGING_POOL_MIB":"2048","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_FRAMES":"100:200"},"gpu":"NVIDIA GeForce RTX 4090","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","cpu":"13th Gen Intel(R) Core(TM) i9-13900K","cpu_threads":32,"memory_mib":32476,"title_id":"PPSA26344","title":"Ghost of Y\u014dtei","content_version":"01.008.000","resolution":"3840x2160","window":{"spec":"frames 100:200","first_present":100,"ms":258171.356},"presents":200,"frame_ms":{"p50":147.813,"p90":899.185,"p99":42781.232,"max":92980.382},"gpu_busy_ms_per_present":86.150,"worker_busy_pct":{"queue worker 0x0":87.494,"queue worker 0x20":26.181,"queue worker 0x52":3.969,"queue worker 0x53":0.884,"queue worker 0x30":44.612,"queue worker 0x38":38.061,"queue worker 0x48":13.947},"top_phases_ms_per_frame":{"Shader.PrepareArtifact":6685.836,"Driver.Packet":2774.642,"Driver.Packet.dispatch":1299.561,"Driver.Dispatch":1272.832,"Driver.Packet.memory_wait":1259.496,"Vulkan.ComputePipeline":1071.626,"Vulkan.GraphicsPipeline":145.679,"Vulkan.GraphicsPipelineLibrary":113.949},"trace_dropped":true,"trace_dropped_threads":{"title":{"events_full_after_s":26.225,"events_lost":20046,"totals_full":false}},"trace":"aps5-trace-4703b22bde3c-13556.json.gz"}Earlier measurements (before this revision)
main, 1.6 / 4.9 / 4.2 s with a port of this PR; longest queue-worker WorkerWait 1.5 / 2.7 / 2.0 s.main, 194 / 134 ms with the port; p90 357 / 362 vs 359 / 347 ms; presents 96 / 115 vs 114 / 121. No visible cost ofReferencedPrograms; it was not timed on its own.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🤖 Generated with Claude Code
https://claude.ai/code/session_01Q9BMpf1muQhujJd4AbteUA