8 Commits

Author SHA1 Message Date
chrg6
518d55ed07 Draw lines as wide as the game sets them.
The game's line width was dropped at the call and every line drawn 1 pixel wide; the game draws two lines a frame at 4.5 pixels into a 144x144 mask. The width is now recorded with the draw state and set as dynamic state for draws of the line topology class, held to the device's range. Only pipelines of that class list the new dynamic state, so the others keep their entries in the pipeline caches and the driver's. line_width = 0 draws every line 1 pixel wide as before.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-12 09:31:04 -05:00
chrg6
b5c9a9b38e Answer NVN getters asked of no object with 0, and map a buffer with no pool to memory of its own.
The game's scene-loading thread makes a few NVN calls with a null object while an area loads or Kakariko's time of day
changes: a memory pool's flags (and the other pool getters), a texture builder's storage size or alignment, and the
mapping of a buffer that has no pool, into which it then writes 0x3d0 bytes. Each read the object at address 0 plus a
field's offset, an access violation. The pool getters, nvnMemoryPoolInvalidateMappedRange and the two builder queries
now answer 0 for a null object (nvn_no_object), and nvnBufferMap of a buffer with no pool returns a block of scratch
memory (64 KiB, or the buffer's size when it records a larger one) instead of 0. The first such calls are logged with
their caller. These fit the crash reports in Castle Town and in Kakariko before Death Mountain (#605, #602), which have
not been confirmed to be this.

Checked: --probe-nvn gains three checks (pool getters of no pool, builder queries of no builder, a 0x3d0-byte write
through the mapping of a buffer with no pool) and they pass; its four other failures are the same on the baseline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 19:38:17 -05:00
chrg6
22bbe674be Remove the read-back refresh of the VRAM mirror, which brought back the tree columns.
Copying the invalidated ranges from guest memory into the mirror at every submission put the guest's copy of those pages over GPU results that live only in the mirror. In adult Hyrule Field that wiped tree records, and the trees stretched into columns reaching the sky again. With NX2NAVI_READBACK_SYNC=0 the columns did not appear at the same spot. The memory check (NX2NAVI_MEMORY=verify) still finds mirror pages newer than guest memory there with or without the refresh, about 3 per 60 frames, which is left for later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:51:47 -05:00
chrg6
9a8f74fe53 Refresh read-back ranges in the VRAM mirror, guard the boot pipeline prebuild against driver crashes and count out-of-order event waits.
Small ranges the game invalidates and reads back (the exposure meter) are copied from guest memory into the mirror at every submission that uses their pool, so a CPU write made between recording and the GPU's run is not lost; NX2NAVI_READBACK_SYNC=0 turns it off.

While the boot builds the recorded pipelines a marker file exists next to the pipeline cache. A start that finds it left over records the GPU and driver in pipeline-prewarm-skip.txt, and starts on them build those pipelines at their first draw instead.

CommandBufferWaitEvent is now recorded as OP_WAIT_EVENT. The replay waits for nothing but counts the waits it reaches before their signal, and how many submissions later that signal comes, in the NX2NAVI_TRACE=gfx frame line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 15:51:47 -05:00
chrg6
99de7b943f Give each file of copied code one license line.
Each file that contains copied code names its copyright holder and license and points at THIRD_PARTY_NOTICES.md; zlib code keeps its full notice and the mark that it was altered. Comments and probe text only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:40 -05:00
chrg6
1b39aabd37 Describe what the code does in comments and docs.
Comments say what the code does and why, docs/maxwell.md keeps the Maxwell facts, and fetch_refs.sh clones only the checkout the build reads. Code is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 05:04:40 -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