Skip to content

nx-gfx (2026-10-26): Animal Crossing window pass investigation (stopgap kept); wrap-up cut short

Mac, scripted headless runs only (nobody played). The session was asked to wrap up early, so only list item (1) was worked; items (2)-(5) were NOT started.

Done

  • Merged nx-shader and main; one VMNMX (nx-shader's exact 64-bit version, executed tests), same as main. make -C gfx test: ALL TESTS PASSED.
  • Diagnostics (env only, no behaviour change): NAPPLE_NVNTRACE=1 (record-order op stream per command buffer), NAPPLE_REGSLOT=<id> (every texture-pool registration of a slot), NAPPLE_PRESENTLOG=<n> (present index / texture vs window textures after n presents), NAPPLE_MAPLOG=1 (MapVirtual dst/src ranges).

AC window pass: findings (root cause NOT found, stopgap mtl_frame_present_pick stays)

  • Record order (NVNTRACE) matches replay: the window pass is SET_RT, cond-render+clears, scissor/viewport/depth, VATTR, VSTREAM, VBUF, DRAW_ELEMENTS(6); no BindProgram/BindTexture/BindUBO/SSBO between the previous pass and the window draw. The guest inherits state from earlier draws, so the window quad is the 500x110 text-label quad again (UBO0 vec4 at 0x210 = 500 110 -250 55, texture = the 500x110 label render target). It never samples the composite.
  • Ruled out: texture-pool slot overwrite (REGSLOT: the slot the draw samples is not re-registered around the frame); wrong present index (PRESENTLOG: 3 window textures rotate 0,1,2, the window pass targets the presented one); aliasing of the composite with the window texture through MapVirtual (MAPLOG: one virtual range 0x121e74000..0x126a74000 mapped from physical pool 0x733dedc000, the window textures live in another pool); Deferred NVN binds (nvnCommandBufferBind*Deferred, nvnProgramGetSubtileSize etc. are unknown names in our table; the game does not crash on them, so it does not call them, but this was not proven).
  • Open leads for the next session: 17+ ProgramSetShaders calls with pool-relative code addresses (0xe00, 0x900, 0xea00..) or null code are rejected, so those programs have hash 0; one of them may be what the missing window-pass program bind should have been. The guest function that builds the window pass is the Ui2d-style helper around main+0x3802394 (view format 0x38 set when flag at main+0x21e5948... is non-zero).
  • nxnative shows this picture, and its README says AC needs render_cond (done by ac-render) - so the composite->window path exists there; compare how nxnative resolves ProgramSetShaders data addresses.
  • Flake seen in 1 of 5 runs: SIGBUS at sdk+0x383f78 (fault in a 0xa0000-byte region, prot 0x700) about 28 s in; not investigated (kernel/memory area).

Not done (list items 2-5)

MK8D storage-out-of-range / block-compressed RT copy-back / vertex stream outside a pool / 45 fps ceiling; G11 pipeline look-ahead; G2/G3/G18; SMO title-menu regression check. Gates not re-run: make -C runtime test test-services, LAS/SMO 45 s runs, ACNH/MK8D runs (only AC 40-90 s runs, exit 0).

Files

Napple/gfx/src/api_cmd.c, api_memory.c, api_texture.c, api_window.c (env-guarded logging only).