Files
nxnative-easy/docs
seedds 066f2afc76 Pokémon Legends: Z-A's GPU page fault and crashes (GitHub issue #101): image atomics that are not followed go to a scratch buffer as large as the image, and the transform feedback draw ends the copy encoder before it opens its own
On the Mac, the fresh-save route of the docs crashed at about frame 3390 and from about frame 5300 page-faulted or crashed on corrupted pointers, with the encoding thread on and off; issue #101 reports an iPhone 17 freezing on kIOGPUCommandBufferCallbackErrorPageFault.

- tf_draw opened its render encoder while the copy encoder (g_blit) was open: ubd_land's inline updates leave it open, as does a copy or a dispatch just before. Metal validation: "Command buffer already has an open command encoder"; the driver then crashed in -[AGXG18GFamilyComputeContext_mtlnext performEndEncoding] (or its dealloc on the encoding thread). Every other helper pass ends g_blit before it opens its own encoder; tf_draw now does too. A host built from before PR #62 crashed the same way.
- A block-linear image's atomics went to the 64 KB dummy buffer, but SPIRV-Cross indexes them by the image bound in the same slot (spvImage2DAtomicCoord: x + y × its width). Z-A's atomic max into a 480x270 r32ui 2D array (texture ID 302, fragment shader 2bd5037003980716) ran about 1.4 MB past the dummy: into zero-copy pools over the game's heap (pointers in the game's objects and the host's program objects had their upper 4 bytes replaced by packed values, rewritten every frame) and into unmapped addresses (the page fault, after which macOS ignores the process's command buffers). MTL_SHADER_VALIDATION=1, which stops out-of-bounds accesses, let the scene play. Such atomics now go to a scratch buffer at least as large as the image (atom_scratch: width × height × layers × texel size, at least the NVN storage size; 3 MB here), grown when a larger image needs it; the results are discarded as before. An unbound image keeps the 64 KB dummy, since its slot holds the 1x1 dummy image. The bring-up host (d34e044) with today's shaders page-faulted the same way.

Three headless Mac runs of the whole route (encoding thread on, off, on) reached frame 12,300 with no GPU error and no crash; before, every run crashed or page-faulted between frames 5230 and 5480. t_nvn 102/102, t_ub 47/47, t_geometry 95/95, t_vbuf 43/43. docs/agents/04-graphics.md and Z-A's notes in docs/development.md say so.
2026-10-24 12:43:39 +08:00
..
Taiko Risshiden V DX (0100346017304000, update 1.1.1, Koei Tecmo's KTGL on SDK 12.3.3): game profile plus two general host changes. Plays on the iPhone by touch (IPA 3.3 GB, Japanese; the game has no English). On the Mac from the notice, the logos and the opening movie through the title, a new game (1560, Kinoshita Tokichiro) with its opening story, the town, a council with a battle proposal, the territory map, a rest at home, a save and a load, and the field battle tutorial, docked with buttons and in handheld mode by touch: 60 fps (frame time p50 16.66 / p95 16.85 ms in the town), sound, about 0.7 GB resident and 1.6 GB of Metal allocations, flat over 15 minutes, no red line on that route. hle_oe.c: oe::SetCpuOverclockEnabled, the first boot's crash (nnMain at main+0x2e1e4c; the SDK's setter reads the apm session the host never opened, null read at sdk+0x362b8, as IsCpuOverclockEnabled did for Monster Hunter Rise); the host keeps the flag and the query reports it. hle_touch.c / hle_hid.c: gestures for hid::GetGestureStates, which answered no entries: the game takes its taps, drags and flicks only from there (main+0x42f1ac acts on types 5-9; its GetTouchScreenState read only tracks the finger), so no tap registered in handheld mode. The host now recognizes them from the same touch points, only in handheld mode as touches, by yuzu's rules (Touch, Press after 0.5 s, Pan, Pinch / Rotate, Cancel on a change in the finger count, then Tap with IsDoubleTap within 0.35 s, Swipe above 400 px/s or Complete, and Idle) plus an 8 px slop before a touch counts as moving, since a fingertip on a phone wobbles; DM_TOUCH_LOG=1 logs the entries, and a DM_CTL line drag <x0> <y0> <x1> <y1> [seconds] moves a finger for testing pans and swipes on the Mac. New unit test t_gesture (43 checks: tap, double tap, slop, slow pan, swipe, press, finger-count cancel, pinch, a press and lift between two reads). Profile: op_mode handheld and pad_layout touch (the Tap layout: the gamepad's corners would cover the cards, the menu icons and the on-screen B button; the layout button brings it back), shaders from eff/ (167 in the G2S container KTGLEffect.g1s, _S2G3000, and 45 GLSLC outputs in main, read by the existing splitter), a prewarm list recorded on the Mac over the route above (18 lines). patches.py: KTGL's frame end (main+0x443e8c) slept in 2 ms rounds until 1/60 s had passed since the frame started, which with about 2 ms of work ended at 18.2 ms: 55 fps in the menus and the town, every 11th frame on screen two vsyncs. The game presents at interval 1, so a cut on this build skips that wait (b.hs → b at main+0x443fd4) and the host's present pacing holds 60; wakeups 2,050 → 320 a second, CPU energy 1.7 → 0.7 mJ a frame. Checked: the NSP script packs it from the NSPs alone (Mac and iOS), the host unit tests and the four tool test files pass. README (games table, a Mac picture of the town), AGENTS.md (49 → 50), docs/development.md and docs/agents/03-bringup.md say so
2026-10-24 11:31:10 +08:00