10 Commits

Author SHA1 Message Date
chrg6
f7487ceee5 Make the memory census walk once and fire on the process's own commit, not on its private bytes.
With mem_census = 1 the census trigger compared the private bytes with the last census, and Windows charges the video memory to them, so every gigabyte of textures started another 130-260 ms walk on the presenting thread: 22 of the 33 walks of the 2026-11-13 session came from that trigger, while the process's own commit grew 307 MiB in play. The trigger now reads the private bytes less the write-combined memory of the last walk (and what the driver's device-local figure grew since), compares them with the highest figure seen at a census, and waits 60 s after the last walk; the 3600-frame censuses stay.

On Windows one walk of the address space now gives both the commit census and the guest regions' committed bytes, which mem_guest_census walked a second time. The census counts the driver's write-combined views apart instead of as guest memory, counts as guest only the reserved guest regions and the loaded modules, and ranks the process's own allocations wherever they lie. The frame after a walk charges its time to a new "census" cause in the frame-time summary and the stutter map instead of "unattributed".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 15:57:51 -05:00
Tobim6
f3a9d2967f Profiler: name the exe's addresses from its own symbol table, and sample the replay thread alone.
A NX2NAVI_PROFILE profile needed the link map to name its Rips, and the launcher's builds keep none. A MinGW link keeps
the COFF symbol table in the exe, so prof_sampler_write now reads it (runtime/prof_syms.c, plain file reads) and appends
`sym <address> <function>+<offset>` for every exe address in the Rip and chain lists. NX2NAVI_PROFILE_REPLAY=1 samples
only the replay thread: with NX2NAVI_REPLAY_ASYNC=1 the render thread spends 98% of a 37 ms frame waiting, and the
replay thread (22 ms a frame recording Vulkan commands) is the one to look at.

(cherry picked from commit 9d3126ca780d7f0f0b91468d42b8ee70572747c8)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 16:22:00 +01:00
chrg6
2d94ede66a Put the commit census and the per-pool traffic log after the comments they had split from their functions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 08:20:32 -05:00
Tyler
2270664be2 Total each allocation once in the commit census, add a size breakdown, and write the profile on a crash
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HtayeqEG2x5woYzWuEQBGV
2026-11-09 08:20:01 -05:00
Tyler
3e10da4d5c Log where the process's committed memory lies with NX2NAVI_TRACE=perf
Every 3600 frames and whenever private commit grew by 1 GiB since the last census: guest, other private, mapped and image
memory, and the largest private allocations outside the guest's range.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HtayeqEG2x5woYzWuEQBGV
2026-11-09 08:20:01 -05:00
tangerineturtle1
480a197994 Add replay diagnostics that found this session's frame-time dips, all off by default.
lock_time (NX2NAVI_LOCK_TIME) makes the replay threads time each lock they have to wait for, kept per asking site (platform.h plat_lock_timing, plat_mutex_lock_at and plat_rmutex_lock_at carry the site), and the frame-time summary lists the sites with the most wait, the recorder's full-ring and drain waits, and the texture lock's holds over 1 ms with the code that took it. replay_time now also keeps each frame's replay ops: a frame over 25 ms charged to the replay says how many draws, binds and transfers it replayed, their time, its slowest op, and how much of the replay's wall time the thread was on the CPU. NX2NAVI_PROFILE_REPLAY=1 samples only the replay thread without call chains, and the profiler now follows the thread that replays instead of the one that started the back end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 08:09:26 -05:00
epicmeme546
754ded99e0 Raise the frame rate in Kokiri Forest and apply more settings during a run.
The foliage's sun shadows took most of the GPU time: one mesh draw shaded about 1,000 million fragments in the far cascade. The far cascade now shades them at a 2x2 rate, and the two far cascades drop one side of the double-sided cards. At the forest entrance the frame rate went from 18 to about 43 fps on an RX 7900 XT.

FSR 3.1, its frame generation and the console mode now take effect without a restart. The full performance overlay lists the settings shown in the options menu.

NX2NAVI_GPU_PASSES times each pass and counts its fragments, and NX2NAVI_SET_AT changes settings at a given frame for test runs. Both are off by default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 02:40:51 -05:00
chrg6
9dcfc5723b Profiler: unwind through vendor DLLs only while they are pinned, so slow-frame captures no longer crash at start.
NX2NAVI_PROFILE_SLOW unwound threads in any module, and one being unloaded while the game started (a driver or vendor
DLL) had its unwind tables freed under the sampler. The exe and the system DLLs are walked freely; any other module is
held with GetModuleHandleEx for the step, and one that is unloading ends the chain. The block-linear copy probe gains
two cases of 256 KiB and more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 18:44:56 -05:00
chrg6
c7257fe652 Fix NVN2 compute constants, indirect mesh draws and empty descriptor sets, and cut the texture pool refresh.
NVN2 compute banks get the dispatch's group counts in bytes 0-0xb, for direct and indirect dispatches; the fog pass
after the integration divided by them. Indirect mesh draws read NVN's {count, first} record as {x, y, z}, so y = 0
drew nothing: each now draws from a ring entry holding {count, 1, 1}, copied on the GPU before the draw. An empty set 1
no longer leaves set 0 pushed with 0 bytes. Compute stages with subgroup operations whose width is a whole number of
subgroups require full subgroups.

The texture pool refresh fell from 3.1-3.7 ms to 1.0 ms a frame in Kokiri Forest: slots with the same descriptor,
address generation and entry generation share one lookup (about 14,500 of 15,000 refills a frame), and registering a
texture and view identical to what the slot holds keeps its resolution. Under 20 GiB of VRAM, ASTC textures are
encoded to BC3 by default (Kokiri: 15.9 to 8.2 GiB, same GPU time). The pool log counts refills by cause and what
invalidates them; frame dumps write BC textures as raw blocks and print a storage buffer's backing span; a profile with
NX2NAVI_PROFILE_FRAMES is written when its window ends; the alpha test logs once that it is not applied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:39 -05:00
Valiantsin Dzerakh
0478c13e45 Import the base tree (MIT, see LICENSE) 2026-11-07 05:04:38 -05:00