The flat list resolved an exe address without the image base a GNU ld map's addresses include, so with the launcher's build-cache/ocarina.map every sample inside the exe came out as "?"; it now resolves as the call chains do. In the map's place the report takes the output of nm -n of the exe, which names the static functions a map leaves out (their time landed on the global function before them). A new table gives the self time of the running call chains: the innermost exe function of every chain that does not end in a wait.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Large compute shaders that no cache holds are built on one background thread after the boot prebuild, smallest first, so their first dispatch no longer compiles them on the replay thread. NX2NAVI_BIG_BUILD_MAX_MB stops that builder once the process has grown by that much: on a 31 GB machine one of these shaders took the process up by 12.8 GB and the game stuttered while Windows paged. The builder takes the queue under its lock and copies each entry out before compiling it, so a shader queued meanwhile cannot free the arrays under it. The same change reports what pipeline-cache.bin gives back, and starts over when the file grows past NX2NAVI_PIPELINE_CACHE_MAX_MB.
A tensor-core program is now tested before its shader is asked for, in both dispatch paths. It runs the stand-in while NX2NAVI_NATIVE_TENSOR is off, and translating it anyway recorded four AI-upscaler shaders of 0.87 to 4.4 million SPIR-V words that this game never dispatches natively. Process memory went from 29.3 GB to 24 GB and the multi-gigabyte builds during play are gone.
The frame-time summary says which part a slow frame went to, and with NX2NAVI_REPLAY_TIME how the replay splits between draws, binds and transfers; NX2NAVI_SVC_SLOW_MS logs the kernel services that block, with the thread they blocked on. prof_report.py reads the map this build writes and adds the image base to a runtime Rip, so a profile resolves to function names instead of question marks.
build_xlate.py applies the patches with GIT_CEILING_DIRECTORIES set to the build folder's parent. Inside a checkout git read 0021-prmt-byte-permute.patch's paths from the repository's top, skipped every file of it and still exited 0, so PRMT was missing from locally built translators and every byte permute was a no-op. A Skipped patch line now fails the build. The note in AmpereLowering.cs that said the translator emits nothing for PRMT is corrected.