Skip to content

feat(agc): store the pipeline journal's modules compressed - #8365

Open
milescoviello wants to merge 4 commits into
boykopovar:mainfrom
milescoviello:feat/journal-compressed-modules
Open

milescoviello wants to merge 4 commits into
boykopovar:mainfrom
milescoviello:feat/journal-compressed-modules

Conversation

@milescoviello

@milescoviello milescoviello commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What

Pipeline journal module records are SPIR-V, and they take almost all of a journal's bytes. #8309 shows that APS5_PIPELINE_JOURNAL_MAX_MIB (1024 MiB) fills with them during a level load, after which later pipelines are never recorded. A module record now stores the module's identity, its stage and the size of its encoded RecompileResult, then a zstd frame (level 1) of that encoding. Loading expands each module once to check that it decodes, as it decoded the raw payload before. Replay expands a module when the entry that needs it is built, on the replay thread, building on #8213's per-module reads. The held-module accounting counts expanded bytes, which is what replay holds in memory. The file format becomes 6 (#5656 took 5 on main for its recipe codec change), so an older journal starts over. Since the journal's source version already changes with every recompiler build, that costs no extra rebuilds.

zstd is the vendored copy (3rdparty/zstd, already built as libzstd_static for ZArchive). libSceAgcDriver links it statically, and on Linux it's kept out of the library's exports with --exclude-libs,libzstd.a, as cmake/ZArchive.cmake does. nm -D --defined-only libSceAgcDriver.prx | grep -i zstd prints nothing.

Why

The same cap then holds about 3.5 times as many modules:

Stacked on #8213

This branch holds #8213's three commits and then its own, e582540, which is the only one to review here. It changes the module read path that #8213 adds, so it waits for #8213.

Tested

Restacked onto #8213's rebased head 8abecc1, on main d6e7ab4, as e5825406b4. The branch now carries #8213's three commits unchanged and then this PR's one commit. Its copy of #8213's HostThreadLocal fix was identical, so the rebase dropped it. The change against main has the same git patch-id as before. On that head, Ubuntu 26.04.1, GCC 15.2, RTX 4070 Ti (615.71.09):

Earlier results, on the heads named in them:

Ubuntu 24.04 (Linux 6.8), GCC 13.3, NVIDIA RTX 4070 Ti, driver 595.99.02.

  • agc_driver_pipeline_journal: HeldModuleTests now also encodes its 16 compute modules and requires the whole journal file to be smaller than those encodings. With fix(agc): read the pipeline journal's modules at replay instead of holding the file #8213's uncompressed records it fails (the journal is 467,960 bytes with 16 of its modules alone encoding to 430,144 bytes), 3 of 3. With this PR both journal tests pass 3 of 3, the held-module bound among them.

  • Khronos validation layer (LunarG SDK 1.4.363), NVIDIA RTX 4070 Ti (595.99.02), Ubuntu 24.04: VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ANYPS5_NO_SHADER_CACHE=1 ANYPS5_REQUIRE_VULKAN=1 ctest -R 'pipeline_journal' -V on fix(agc): read the pipeline journal's modules at replay instead of holding the file #8213's head 5778288 and on this PR (f5504d2). 2 of 2 pass on each. Neither log reports the layer missing, and neither has a VUID- error.

  • tools/check_conventions.py --base upstream/main passes, apart from the existing debt-length warning on the pipeline journal entry. This PR doesn't change that entry, since nothing in it becomes false.

  • PPSA11386, by @SleglJan (comment), RTX 3080 (NVIDIA 615.78.08), Linux, on a main 68323ba integration with the title's open PRs, fix(agc): read the pipeline journal's modules at replay instead of holding the file #8213 and this PR: with the default 1024 MiB cap, the first level's load now records completely, and the cap is reached about 455 s into gameplay. Before this, it was reached during that load. The journal records 628 graphics, 694 compute and 1,292 modules, against 330, 377 and 664. The warm level entry has no gap, against 280 s from Resume to the first gameplay frame: 4,107 draws built in 7.2 s, against 772 in 284.5 s.

  • Windows 10 Pro 22H2, WinLibs GCC 15.2.0, Release, by @TheSovietWaffle on f5504d2ec: agc_driver_pipeline_journal and agc_pipeline_journal pass 3 of 3 on an NVIDIA RTX 3080 (617.42) and on an AMD Radeon RDNA 2 iGPU (1002:164e, 32.0.21045.5002).

Checklist

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 20, 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 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1896 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 4448 docs/dev/debt/libSceAgcDriver.md
PR 4449 docs/dev/debt/libSceAgcDriver.md
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5372 docs/dev/debt/libSceAgcDriver.md
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5431 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/PipelineJournal.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
core/libs/prx/libSceAgcDriver/tests/execution/PipelineJournal.cpp
docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ARCHITECTURE.md
PR 6146 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6182 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6194 docs/dev/debt/libSceAgcDriver.md
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6249 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6273 docs/dev/debt/libSceAgcDriver.md
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6498 docs/dev/debt/libSceAgcDriver.md
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6548 docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6743 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 6804 docs/dev/debt/libSceAgcDriver.md
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6820 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6905 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6926 docs/dev/debt/libSceAgcDriver.md
PR 6959 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6973 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6977 docs/dev/debt/libSceAgcDriver.md
PR 6987 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6995 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7002 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7085 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7256 docs/dev/debt/libSceAgcDriver.md
PR 7275 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7307 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7310 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7446 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7449 docs/dev/debt/libSceAgcDriver.md
PR 7457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7464 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7505 docs/dev/debt/libSceAgcDriver.md
PR 7508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7535 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7618 docs/dev/debt/libSceAgcDriver.md
PR 7622 core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
core/libs/prx/libSceAgcDriver/tests/execution/PipelineJournal.cpp
docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 7668 docs/dev/debt/libSceAgcDriver.md
PR 7677 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7684 docs/dev/ARCHITECTURE.md
PR 7705 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7717 docs/dev/debt/libSceAgcDriver.md
PR 7844 docs/dev/debt/libSceAgcDriver.md
PR 7893 docs/dev/debt/libSceAgcDriver.md
PR 7910 docs/dev/debt/libSceAgcDriver.md
PR 7978 docs/dev/debt/libSceAgcDriver.md
PR 8014 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8089 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8105 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8123 docs/dev/debt/libSceAgcDriver.md
PR 8160 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8161 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8212 core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
docs/dev/ARCHITECTURE.md
PR 8223 docs/dev/debt/libSceAgcDriver.md
PR 8246 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8281 docs/dev/debt/libSceAgcDriver.md
PR 8319 docs/dev/debt/libSceAgcDriver.md
PR 8395 docs/dev/debt/libSceAgcDriver.md
PR 8401 docs/dev/debt/libSceAgcDriver.md
PR 8412 docs/dev/debt/libSceAgcDriver.md
PR 8419 docs/dev/debt/libSceAgcDriver.md
PR 8420 docs/dev/debt/libSceAgcDriver.md
PR 8423 docs/dev/debt/libSceAgcDriver.md
PR 8424 docs/dev/debt/libSceAgcDriver.md
PR 8426 docs/dev/debt/libSceAgcDriver.md
PR 8484 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8592 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8639 docs/dev/debt/libSceAgcDriver.md
PR 8658 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8707 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8735 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ARCHITECTURE.md
PR 8740 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8874 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8887 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8939 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9007 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9013 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9017 docs/dev/debt/libSceAgcDriver.md
PR 9020 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9022 docs/dev/debt/libSceAgcDriver.md
PR 9068 docs/dev/debt/libSceAgcDriver.md
PR 9077 docs/dev/debt/libSceAgcDriver.md
PR 9098 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9159 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9176 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9185 docs/dev/debt/libSceAgcDriver.md
PR 9186 docs/dev/debt/libSceAgcDriver.md
PR 9188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9243 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9248 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9275 docs/dev/debt/libSceAgcDriver.md
PR 9287 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9289 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9305 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9318 docs/dev/debt/libSceAgcDriver.md
PR 9335 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9348 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9352 docs/dev/debt/libSceAgcDriver.md
PR 9356 docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 9361 docs/dev/debt/libSceAgcDriver.md
PR 9385 docs/dev/ARCHITECTURE.md
PR 9387 docs/dev/debt/libSceAgcDriver.md
PR 9393 docs/dev/debt/libSceAgcDriver.md
PR 9396 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9400 docs/dev/ARCHITECTURE.md
PR 9401 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 9402 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9406 docs/dev/debt/libSceAgcDriver.md
PR 9424 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9431 docs/dev/debt/libSceAgcDriver.md
PR 9432 docs/dev/debt/libSceAgcDriver.md
PR 9443 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9445 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9450 core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
PR 9457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9495 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
core/libs/prx/libSceAgcDriver/tests/execution/PipelineJournal.cpp
docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 9514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9521 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9533 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9565 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9592 docs/dev/debt/libSceAgcDriver.md
PR 9626 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9633 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9652 docs/dev/debt/libSceAgcDriver.md
PR 9670 docs/dev/debt/libSceAgcDriver.md
PR 9671 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9672 docs/dev/debt/libSceAgcDriver.md
PR 9673 docs/dev/debt/libSceAgcDriver.md
PR 9674 docs/dev/debt/libSceAgcDriver.md
PR 9675 docs/dev/debt/libSceAgcDriver.md
PR 9676 docs/dev/debt/libSceAgcDriver.md
PR 9685 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9696 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9700 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9702 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9703 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9712 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9717 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9721 docs/dev/debt/libSceAgcDriver.md
PR 9723 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9737 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9742 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9748 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9749 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9789 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9790 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9836 core/libs/prx/libSceAgcDriver/Graphics/include/PipelineJournal.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
core/libs/prx/libSceAgcDriver/tests/execution/PipelineJournal.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9842 docs/dev/debt/libSceAgcDriver.md
PR 9852 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9856 docs/dev/debt/libSceAgcDriver.md
PR 9875 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9879 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9890 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9891 docs/dev/debt/libSceAgcDriver.md
PR 9892 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9893 docs/dev/debt/libSceAgcDriver.md
PR 9895 docs/dev/debt/libSceAgcDriver.md
PR 9897 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9898 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9899 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9904 docs/dev/debt/libSceAgcDriver.md
PR 9905 docs/dev/debt/libSceAgcDriver.md
PR 9906 docs/dev/debt/libSceAgcDriver.md
PR 9907 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9913 docs/dev/debt/libSceAgcDriver.md
PR 9915 docs/dev/debt/libSceAgcDriver.md
PR 9940 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9941 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 9950 docs/dev/debt/libSceAgcDriver.md
PR 9961 docs/dev/debt/libSceAgcDriver.md
PR 9965 docs/dev/ARCHITECTURE.md
PR 9969 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9988 docs/dev/debt/libSceAgcDriver.md
PR 10000 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10026 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10043 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10044 docs/dev/debt/libSceAgcDriver.md
PR 10046 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10049 docs/dev/debt/libSceAgcDriver.md
PR 10062 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10064 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10066 docs/dev/debt/libSceAgcDriver.md
PR 10069 docs/dev/ARCHITECTURE.md
PR 10141 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10159 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10164 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10179 docs/dev/debt/libSceAgcDriver.md
PR 10191 docs/dev/debt/libSceAgcDriver.md
PR 10193 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
core/libs/prx/libSceAgcDriver/tests/execution/PipelineJournal.cpp
docs/dev/ARCHITECTURE.md
docs/dev/debt/libSceAgcDriver.md
PR 10194 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10233 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10249 core/libs/prx/libSceAgcDriver/Graphics/src/PipelineJournal.cpp
PR 10307 docs/dev/debt/libSceAgcDriver.md
PR 10333 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10351 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10359 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 10382 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10388 core/libs/prx/libSceAgcDriver/CMakeLists.txt

@github-actions github-actions Bot added the fix error Closes an issue (Fixes #N) label Oct 20, 2026
@TheSovietWaffle

Copy link
Copy Markdown
Contributor

Windows data point: RTX 3080 (NVIDIA 617.42) and AMD Radeon RDNA 2 iGPU (1002:164e, 32.0.21045.5002), Windows 10 Pro 22H2, WinLibs GCC 15.2.0, Release, head f5504d2ec: agc_driver_pipeline_journal and agc_pipeline_journal pass 3 of 3 on both GPUs.

AI-assisted: yes (Claude Code).

@milescoviello

Copy link
Copy Markdown
Contributor Author

Thanks @TheSovietWaffle. That covers Windows, which I hadn't run, and adds an AMD GPU. I added both to the Tested section of the description.

AI-assisted: yes (Claude Code)

@SleglJan

Copy link
Copy Markdown
Contributor

@milescoviello PPSA11386 (007 First Light) with f5504d2, compared with the runs in #8309:

  • With the default cap, the level's load now records completely. The cap is reached about 455 s into gameplay.
  • The warm level entry has no gap.
  • I didn't rerun the 2 GiB seed. The default-cap seed now holds 1,322 pipelines and 1,292 modules, against that seed's 958 and 924.

Setup:

Cold seed with the default cap (1024 MiB):

before (#8309) this PR
journal at Resume – 200 MB
journal at the first gameplay frame at the cap 344–428 MB
cap reached during the first level's load about 455 s into gameplay
recorded 330 graphics, 377 compute, 664 modules 628 graphics, 694 compute, 1,292 modules
writes refused after the cap 617 75

Warm run from that seed:

before (#8309, default-cap seed) this PR
boot to Resume 385 s 385 s
journal load – 4.0 s (1,322 pipelines, 1,292 modules)
replay, 16 threads 258 s: 330 graphics, 374 compute 273 s: 481 graphics, 526 compute, 17 already present; 0 skipped, rejected or failed
Resume to the first gameplay frame 280 s no gap: a new frame in every 10 s sample
draws built from scratch during the level entry (the draw profile's "build" count, which #8309 called graphics pipelines built) 772, taking 284.5 s 4,107, taking 7.2 s
first 200 presents 0.67 FPS 0.73 FPS

The 2 GiB seed in #8309 gave 2,505 builds taking 5.4 s and 0.70 FPS, so the default cap now does about what that seed did.

The entry limit now binds before the byte cap. The replay takes the first APS5_PIPELINE_JOURNAL_ENTRIES entries (1024, documented in ARCHITECTURE.md as the pipeline store's bound; PipelineJournal.cpp:915 on main 2ee20b4):

  • The warm run replayed exactly 1,024 of the 1,322 entries: 481 + 526 + 17. The load line still says 1,322.
  • The 298 not replayed are the journal's tail. Entry 1,024 was recorded 1–1.5 minutes into gameplay, so the level entry is unaffected, and the rest are compiled when first used, as before.
  • The store's bound applies to graphics pipelines (CachedPipeline, APS5_PIPELINE_STORE_ENTRIES), and only 628 of the 1,322 are graphics. So a separate entry bound for compute, or a log line when the replay truncates, might suit a follow-up rather than this PR.

AI-assisted: yes (Claude Code)

@milescoviello

Copy link
Copy Markdown
Contributor Author

Thanks @SleglJan, that's the result #8309 was after: the default cap now covers the level load that the 2 GiB seed needed.

Good catch on the entry limit. The replay cuts the loaded journal to its first APS5_PIPELINE_JOURNAL_ENTRIES silently, and compute entries count against a bound meant for the graphics pipeline store. I'll take that as a separate small PR: graphics entries bounded as now, compute entries bounded on their own, and a line when the replay leaves entries out. That keeps this one to the module encoding.

AI-assisted: yes (Claude Code)

@milescoviello

Copy link
Copy Markdown
Contributor Author

@SleglJan the entry-limit follow-up is #8542, stacked on this PR. Graphics entries keep the current bound, compute entries get APS5_PIPELINE_JOURNAL_COMPUTE_ENTRIES (1024), and a line says how many of each a replay leaves out.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 20, 2026
@milescoviello
milescoviello force-pushed the feat/journal-compressed-modules branch from f5504d2 to 30c643b Compare October 20, 2026 19:39
@milescoviello

Copy link
Copy Markdown
Contributor Author

Rebased onto main 2185dbf. The stack is #8213's two commits (unchanged) plus this one, now 30c643b. It conflicted in PipelineJournal.cpp with #5656, which also bumped the journal's FileFormat from 4 to 5 for its recipe codec change. This PR's format is now 6, so a journal written by main in format 5 (uncompressed modules) starts over instead of being read as compressed. The commit message and the description say so. On the rebased head, the journal tests (agc_driver_pipeline_journal, agc_driver_graphics, savedata_memory_journal) pass 3 of 3.

AI-assisted: yes (Claude Code)

@milescoviello

Copy link
Copy Markdown
Contributor Author

Windows results for this head (30c643b, which carries #8213), since the description only has Linux. Setup: Windows 11 Enterprise (build 22631), NVIDIA GeForce GT 1030 (driver 582.66), WinLibs GCC 15.2.0 r7 (UCRT), Release, BUILD_TESTING=ON.

AI-assisted: yes (Claude Code)

@milescoviello

Copy link
Copy Markdown
Contributor Author

Rebased onto main 275e896. The new head is a2eb629939, same three commits. #7869 (polygon modes) took journal format 6, so this PR's format moves to 7, and the module-record commit's message says so. The one conflict was the comment above FileFormat, where this PR's wording is kept. The 4 journal tests pass 2 of 2.

#8542 is restacked on this head.

AI-assisted: yes (Claude Code)

@oneandonlydean

Copy link
Copy Markdown
Collaborator

@milescoviello the rebase onto FileFormat 7 looks right. Full CI on a2eb629 fails one Windows test, twice: prx_thread_local_destructors (attempts 1 and 2 of run 39703474248, both ~48.5 s). Linux passes.

The test's message names the cause:

On Windows a thread_local destructor in a module runs after emulated TLS
freed the object; keep such objects in HostThreadLocal:

  libSceAgcDriver.prx: ...JournalFile4Read... registers a thread_local destructor

That's the new static thread_local ReadEvent completion; in JournalFile::Read (PipelineJournal.cpp, the _WIN32 branch). ReadEvent has a destructor (CloseHandle), so the module registers a TLS destructor, which this check forbids on Windows.

Moving it to HostThreadLocal (prx/libc/include/HostThreadLocal.hpp) should fix it, the same way PreciseWait.hpp and Submission.cpp keep their per-thread state. Something like:

struct ReadEventStorage;
auto& completion = HostThreadLocal<ReadEvent, ReadEventStorage>();

With that change, prx_thread_local_destructors should pass on Windows CI.

@milescoviello

Copy link
Copy Markdown
Contributor Author

@oneandonlydean thanks for tracking that down. Pushed e867237953: the read event in JournalFile::Read now comes from HostThreadLocal<ReadEvent, ReadEvent>() instead of a static thread_local, as you suggested. That follows PerformanceOverlay.cpp's HostThreadLocal<PacketCounterLease, PacketCounterLease>(), with the event type as its own tag.

#8213 has the same static thread_local ReadEvent (that's where the overlapped read came from), so I pushed the same change there as 0d34f90fab.

My Windows 11 VM (WinLibs GCC 15.2.0) is building all modules for prx_thread_local_destructors on main and on e867237953. I'll post the result here when it finishes.

AI-assisted: yes (Claude Code)

@milescoviello

Copy link
Copy Markdown
Contributor Author

Windows 11 VM, WinLibs GCC 15.2.0, Release, every module built (--target libs): prx_thread_local_destructors passes on e867237953 and on its merge base 275e896797. So the HostThreadLocal change clears the module's thread_local destructor; the red side is your CI run on a2eb629939. #8213 carries the same change as 0d34f90fab.

AI-assisted: yes (Claude Code)

milescoviello and others added 4 commits October 22, 2026 19:31
…lding the file

The journal was read whole into one buffer that the decoded modules
viewed, so a replay held the entire file (1 GiB at the default
APS5_PIPELINE_JOURNAL_MAX_MIB) until its last entry was built. The load
now parses the file a record at a time through positioned reads and keeps
it open; a replay thread reads an entry's modules again when it builds the
entry and rejects it when a record no longer reads back as loaded. The
replay report gains the peak module bytes held at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…indows

A handle opened without FILE_FLAG_OVERLAPPED serializes its reads, so
replay threads reading modules from the journal waited for each other on
Windows even though each ReadFile passed its own offset. The journal is
now opened overlapped, and each read waits on a per-thread event with
GetOverlappedResult.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A thread_local with a destructor in a module runs after emulated TLS freed
it on Windows, which prx_thread_local_destructors refuses. The per-thread
read event now lives in HostThreadLocal, as the other per-thread driver
state does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Module records are SPIR-V and take almost all of a journal's bytes, so
APS5_PIPELINE_JOURNAL_MAX_MIB fills with modules and later pipelines
are not recorded (boykopovar#8309). A module record now keeps its identity, stage
and encoded size, followed by a zstd frame (level 1) of the encoded
result; loading and replay expand it before decoding. The journal format
becomes 7 (main took 5 for the recipe codec change of boykopovar#5656 and 6 for
the polygon modes of boykopovar#7869).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@milescoviello
milescoviello force-pushed the feat/journal-compressed-modules branch from e867237 to e582540 Compare October 22, 2026 19:40
@oneandonlydean

Copy link
Copy Markdown
Collaborator

@milescoviello #8115 merged with the pipeline journal at FileFormat = 7u, which this branch also claims, so PipelineJournal.cpp conflicts now. Two more journal changes are queued ahead of this one: #6801 takes 8 and #6612 the next number after it.

Could you rebase when this one's turn comes and set FileFormat to main's value + 1 at that point? This PR doesn't change State, so that's the only edit. I'll ping here when it's next.

@milescoviello

Copy link
Copy Markdown
Contributor Author

@oneandonlydean will do. When it's this one's turn I'll rebase it and set FileFormat to main's value + 1. #8542 is stacked on it and will follow with the same number.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 22, 2026
@adriadam10 adriadam10 self-assigned this Oct 22, 2026
@oneandonlydean oneandonlydean self-assigned this Oct 23, 2026
@oneandonlydean

Copy link
Copy Markdown
Collaborator

@adriadam10 I've added myself as a co-assignee here so we can run this through our local Astro and Sarah regression gate alongside your review. Your assignment stays as it is, and I'll post the gate result here once it has run.

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* build docs fix error Closes an issue (Fixes #N) needs rebase Conflicts with main, rebase needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AGC: pipelines first built after the journal reaches APS5_PIPELINE_JOURNAL_MAX_MIB are compiled again on every warm boot

5 participants