Skip to content

The Legend of Zelda: Ocarina of Time (Switch 2, 0400486024DEC000, v0 & v131072): playable at 60 fps through Dodongo's Cavern - #1444

Closed
ksolenk38ze wants to merge 2 commits into
seedds:mainfrom
ksolenk38ze:oot-switch2-fixes
Closed

ksolenk38ze wants to merge 2 commits into
seedds:mainfrom
ksolenk38ze:oot-switch2-fixes

Conversation

@ksolenk38ze

Copy link
Copy Markdown
Contributor

What and why

This completes the profile and host/renderer fixes for The Legend of Zelda: Ocarina of Time (Switch 2 Edition, title ID 0400486024DEC000, base dump v0 and update 1.2.0 v131072, Nintendo SDK 22.2.8, NVN2), building on the initial Kokiri Forest draft (#1299).

On the Mac it boots, plays the 1920×1080 AV1 title movie at 60 fps, and runs continuously at ~60 fps (frame p50 16.29–16.73 ms, GPU p50 10.8–13.9 ms on Apple M5 Pro) across Kokiri Forest, the Great Deku Tree (including the Queen Gohma boss fight and Triforce cutscene), Hyrule Field, Market, Hyrule Castle, Kakariko Village, Death Mountain Trail, the Great Fairy Fountain, and Dodongo's Cavern (including the King Dodongo boss fight and Spiritual Stone cutscene) over a 274,851-frame (94-minute) continuous gameplay session with zero crashes.


Summary of Changes

1. Title screen, audio, movie & Kokiri Forest entry (from #1299)

Symptom Cause Fix
gRPC poll engine assert at boot Offline socket calls failed wake-up eventfd creation hle_net.c serves nn::socket::EventFd / EventFdRead / EventFdWrite (fds 512..575) across Poll, Select, Close and Fcntl (t_net_eventfd, 23 checks)
auddmg:u abort (0xa99) & SDK 22 audren lock SDK 22 calls nn::audio::ListVirtualInputDevices and moves the AudioRenderSystem update lock offset hle_audio.c answers with 0 virtual input devices; hle_audren.c reads the SDK 22 update lock offset dynamically from UpdateImpl
Missing movie background & NDSR upscaler shaders 22 compute shaders live in NDVE (zstd dictionary pack) and 3 in Shader/agl_ndsr.pck (NDSR v0x102) shader_split.py extracts both ndve_shaders and ndsr_shaders; all 42,853 shaders in shader_map.tsv translate and compile
prepo:u abort (0xe15) at first scene transition PlayReport::Send waits on an AsyncContext hle_offline.c completes the guest SDK AsyncContext(Result) in caller storage
White 3D scene agl clears a copy of prepass depth under a render condition skipped on console Profile sets render_cond on
Missing mesh-shaded models & GPU hang after opening cutscene NVN2 stores task/mesh stages in BNSH slots 7 & 8; unskinned (#var0) task/mesh shaders had an unbounded 2^32 loop when c0_u[8] == 0; 521 contiguous 64 KB pools overflowed the 256-entry GMEM_RUN_MAX table shader_split.py reads BNSH slots 7 & 8; loop_guard in dmsh_build.py bounds loops at 262,144 iterations; nvnCommandBufferDrawMeshTasksIndirect is implemented with dpc_clamp; GMEM_RUN_MAX raised to 1024; BarrierExits and tg_fence handle divergent barriers and shared-memory fences

2. Foliage, water, terrain, memory & scene transitions

Symptom Cause Fix
Foliage vertex jitter & missing fairy/water volume Ampere F2FP (0x23e/0x83e, mode 0x4ff MERGE_AB) and I2FP (0x243, sA != RZ) missing; SULD dead-code elimination dropped coordinate inputs when one component was unused; a5288d0a6c4971fd's 3D texture typed as Texture2D Added F2FP and I2FP in InstEmitAmpereAlu.cs; kept SULD coordinate inputs live in InstEmitMemory.cs; recorded Texture3D in shader_facts.tsv
Point-cloud foliage culling & uninitialized fragment inputs on mesh draws 5 foliage mesh shaders declare point topology at control +0x5f == 1; shader_pairs.tsv only paired (vs, ps), leaving 21 mesh shaders without vs_pad padding for unwritten fragment inputs (locn5, locn2..15) dmsh_meshstage.py reads point topology at +0x5f == 1; shader_split.py emits the 1,284 (ms, ps) BNSH variation pairs into shader_pairs.tsv
Black screen hang exiting Deku Tree (OptimizeChangeBanc) & long-session AllocateAddressRegion failures 2.38 GiB alias region (mem_alias 0x98000000) exhausted virtual space; long sessions mapped/unmapped scene heaps past the 2.80 GiB app_pool - heap budget without triggering sead::StandardAllocator unmapping Profile sets mem_alias 0x400000000, mem_reserve 0x668000000, and mem_map_limit on (0x10801 ResultLimitReached); hle_nvn.c guards h_nvnBuffer* / h_nvnMemoryPool* against NULL pools
Crash when playing the Ocarina nn::hid::IsOunceVibrationDeviceMounted(VibrationDeviceHandle) was unbridged Bridged in hle_hid.c
Transparent ground patches, multi-level floating grass slabs (Kakariko / Death Mountain / Fairy Fountain), and 50–136 ms stutters tera's bordered 260×260 / 68×68 heightmap and blend-weight tiles shared a 2.43 GB pool with GPU render targets; attach() called nvn_pool_mark_gpu_written inside tex_mtl(t), and alias_take_over / retired descriptors evicted live terrain textures from g_ghost Profile enables tex_flush_upload on and tex_dirty_upload on; g_in_rt_attach guards attach(); tex_cpu_content recognizes 260×260 and 68×68 bordered terrain tiles; ft_add excludes NVN_MEMORY_POOL_FLAGS_VIRTUAL pools (t_sparse_tiles)
Sky & water reflection baking into BC1/BC4 targets Game renders reflections into format 66 (RGB_DXT1) and format 73 (RGTC1_UNORM) targets (COMPRESSIBLE) bcrt_attach redirects BC1/BC4 colour attachments to RGBA8Unorm / R8Unorm shadow textures and encodes their mips via bc_encode_bc1 / bc_encode_bc4 on rp_end
16 fps slowdown in Hyrule Castle & 10 GB g_mrbuf growth fb_prepare scanned g_by_serial on every draw in bindless scenes and matched active attachments against themselves fb_prepare skips g_by_serial scans unless s_same_pass > 0 and excludes active attachments; mrbuf_put caps g_mrbuf at 64 buffers / 256 MB

3. Dodongo's Cavern, King Dodongo & Kakariko / Market frame-pacing fixes

Symptom Cause Fix
AGX::RenderContext crash (renderCommandEncoderWithDescriptor:) & 1,621 MTLCompilerService crashes Calling [base newRenderPipelineDescriptorForSpecialization] on a mesh pipeline (base.meshFunction != nil) returned a descriptor with vertexFunction == nil and meshFunction == nil; creating MTL4LibraryFunctionDescriptor on background threads crashed MTLCompilerService pso_build_ex returns base directly when d.meshFunction != nil and colour attachments match (or compiles via arch_capture); mesh_fn and pso_offline.py skip MTL4LibraryFunctionDescriptor for mesh shaders
Blocky mosaic corruption on volcanic rocks, lava pools & boss cutscenes Upgrading a texture (tex_upgrade / tex_upgrade_pfv) that was an sRGB/linear view (view.parentTexture == base) or backed by an NvImageHeap lost the heap owner, left g_by_serial / g_ghost / g_alias stale, or recreated an RGBA8Unorm_sRGB view over an R32Uint storage upgrade (agl_ndsr_vr); image_prepare did not persist NVN_TEXTURE_FLAGS_IMAGE on g_treg[tid].t.d.flags tex_upgrade unwraps view.parentTexture, preserves the NvImageHeap owner via MTLTextureDescriptor + newTextureWithDescriptor:offset:, updates g_by_serial / g_ghost / g_alias in place, and only recreates views when pixel formats only differ by sRGB; image_prepare persists NVN_TEXTURE_FLAGS_IMAGE on g_treg[tid] and upgrades need_pfv before the first pass
Severe FPS drop (77.7 ms/frame, 352 sync flushes) in King Dodongo outro cutscene pkg_upload_ forced sparse-pool textures (pool->is_sparse, < 64 MB) onto the synchronous CPU nvn_deswizzle + up_flush() path pkg_upload_ copies gathered sparse pages (sp_gather) into a batch-retained MTLBuffer and takes the batched GPU deswizzle path
21.5 ms/frame res_commit & 965k g_ghost puts in Hyrule Market and Kakariko Village up_big_src created/destroyed a temporary newBufferWithBytesNoCopy MTLBuffer per upload batch; g_pkg_alias had a 512-entry cap, deleted entries on hit (hm_del_id), and ignored !is_live (treg_retired) textures up_big_src caches 16 MB (BIG_S) chunks in g_up_big_src (up_drop_pool invalidates on unmap); g_pkg_alias is unbounded with range-overlap invalidation, retains hits across frames, and caches !is_live packaged textures
Undefined symbol _mtl_present_screen in t_nro / t_symbols under ASan / coverage Upstream 2202d610 added a call to mtl_present_screen in dm/host/loader.c, which t_nro.c and t_symbols.c include directly without linking nvn_mtl.m Added a stub void mtl_present_screen(uint32_t w, uint32_t h) in dm/host/tests/t_nro.c and dm/host/tests/t_symbols.c

Validation & Measurements

1. Continuous Gameplay Session (Apple M5 Pro, macOS 26.4, Metal 4)

  • Duration & Coverage: 274,851 frames (~94 minutes continuous run) across boot, title movie, Kokiri Forest, Great Deku Tree, Hyrule Field, Market, Hyrule Castle, Kakariko Village (including indoors / House of Skulltula), Death Mountain Trail, Great Fairy Fountain, and full completion of Dodongo's Cavern + King Dodongo boss fight + Spiritual Stone cutscene + return to Hyrule.
  • Stability: 0 crashes, 0 GPU timeouts, 0 MTLCompilerService crashes.
  • Performance (steady 300-frame windows across areas):
    • Frame time median (p50): 16.29–16.73 ms (~60.0 fps)
    • GPU execution time median (p50): 10.8–13.9 ms
    • Bindless pool rebuilds: 0 rebuilds during steady scene traversal (100% patched/reused)
    • Residency commit (res_commit): reduced from 6,439.5 ms / 300f (21.5 ms/f) in Market/Kakariko to < 0.5 ms/f

2. Static Shader & Pipeline Interface Validation (scripts/regress.py)

  • Shader build (0400486024DEC000): 42,853 / 42,853 shaders built (.metallib, .metal, .json), 0 failed (chain 73b8c3e231ca).
  • Pipeline interface check (dm/gfx/tools/interface_check.py): 34,474 / 34,474 (vertex/mesh, fragment) pairs checked, "bad": [] (0 interface findings), "not_in_archive": 0.

3. Test Suites & CI

  • make -C dm/host/tests GAME=0400486024DEC000 -j8 run asan tsan: 100% pass (including t_net_eventfd, t_nro, t_symbols under ASan/UBSan/TSan).
  • make -C dm/gfx/tests GAME=0400486024DEC000 run: 100% pass (all GPU and CPU tests, including t_sparse_tiles, t_readback, t_geometry, t_reorder_chain, t_upgrade_alias, t_zskip, t_present_crop, t_tex_fit_root, t_cpu_tex, t_pool_chunks, check_test_dmsh_pull, check_test_tbdr_budget).
  • python3 dm/tools/docs_symptoms.py --check: 0 issues (506 symptoms in docs/reference).
  • All 9 GitHub Actions CI checks (Build check, Coverage, Host unit tests and CPU-only gfx tests, Sanitizers, Tool tests, Unsigned iOS app, clang-tidy (ratchet), ruff and pyright (ratchet), label) pass 100% green on e03bdc8f.
scripts/regress.py impact origin/main..HEAD

regress.py impact origin/main..HEAD

3 games use what the change touches, 1 only through a broad rule (every game of its API), 0 not affected, 142 unknown (no usage manifest); 68 files changed, 67 NVN / HLE entry points reached through the host's callers, 33 rules of dm/tools/impact_map.tsv

game status what it uses of the change (kind: name ×count; for broad, the broad rows)
The Legend of Zelda: Breath of the Wild 01007EF00011E000 affected shader: readable_tile ×6254, shader: vs_pad ×5, present: pipeline_prepare ×1, nvn: nvnBufferGetAddress ×11847691, nvn: nvnMemoryPoolMap ×1786764, nvn: nvnBufferMap ×868786 … (28 in all)
Pokémon Scarlet 0100A3D008C5C000 affected shader: readable_tile ×10824, shader: vs_pad ×450, shader: buffer_atomic ×1, nvn: nvnBufferMap ×701066, nvn: nvnBufferGetAddress ×500327, nvn: nvnBufferGetSize ×450206 … (28 in all)
The Legend of Zelda: Tears of the Kingdom 0100F2C0115B6000 affected shader: readable_tile ×8380, shader: buffer_atomic ×406, shader: vs_pad ×387, shader: image_atomic ×2, shader: image_atomic_result ×2, present: pipeline_prepare ×1 … (32 in all)
Hades 0100535012974000 broad svc: 0xb ×951904347, hle: _ZN2nn4nifm22IsNetworkRequestOnHoldEv ×951890659, hle: _ZN2nn3mem17StandardAllocator8AllocateEm ×4406502, hle: vkCmdBindDescriptorSets ×981592, hle: vkCmdDrawIndexed ×772348, hle: _ZN2nn4nifm20SubmitNetworkRequestEv ×707702 … (183 in all)

Unknown (no usage.tsv): 142 profiles (--all lists them).

Docs

  • Findings documented in dm/games/0400486024DEC000/README.md and docs/reference/ (services.md, audio.md, shaders.md, nvn-objects.md, rendering.md, frame-rate.md), verified with python3 dm/tools/docs_symptoms.py --check.
  • dmsh_chain.py --header run and dm/gfx/nvn/dmsh_chain.h + dm/gfx/tools/dmsh_chain.lock updated (73b8c3e231ca).
  • No game binaries, keys, or proprietary assets included.

@github-actions github-actions Bot added host The Horizon host: SVCs, services, threads, memory (dm/host) nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests) packing Building an IPA or a Mac app: the NSP script, extraction, the shader split, the packers tools Tools and scripts (dm/tools, scripts) docs Documentation shader chain The shader translation chain (DMSH_CHAIN): a change rebuilds every game's shaders game: 0400486024DEC000 A game new game Adds a game profile that main does not have yet labels Nov 6, 2026
@PucaVaz

PucaVaz commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Building this branch (e03bdc8) from my own v131072 NUP on an M4 MacBook with 24 GB to test it on a smaller Mac than the M5 Pro. I'll report how far it gets, plus footprint and GPU-allocated numbers, once the shader build finishes (about 2 hours).

Drafted with Claude; reviewed by me.

@PucaVaz

PucaVaz commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Test report, part 1: a fresh build of e03bdc8 from the v131072 NUP stops at the shader split:

[RED] the split shader tables differ from game profile 0400486024DEC000's:
shader_map.tsv: the same rows in another order

The 42,857 rows are the same; only the order differs. The profile's shader_map.tsv has the 267 cs_lib.bin rows in one block (lines 22719–22985), while this branch's shader_split.py interleaves them by source file. shader_pairs.tsv, shader_facts.tsv and pso_pairs.tsv match byte for byte. Committing the split's table (<work>/shader/pkg.partial/tables/shader_map.tsv) should fix it; with it the build goes past the split here (✓ [3/6] shader split (2:48): 42,854 shaders). Full results after the shader build.

Drafted with Claude; reviewed by me.

fpedrolucas95 added a commit to fpedrolucas95/nxnative that referenced this pull request Nov 6, 2026
…itch 2) playable at 60 fps through Dodongo's Cavern

Resolved against this tree's own Ocarina work:
- Kept this tree's raw pool table (grows past 4,096 entries, two-word hints, per-entry write logs);
  the PR's merged-run table (GMEM_RUN) and one-word hints are left out, with the ABI and translator to match.
- Kept the pool table spares (seedds#1428), type cache, range-tracked GPU writes (seedds#1390), 1430's depth-read rule,
  the synchronous task / mesh pipeline build, and the item walk of NDVE packs.
- Taken from the PR: ALIAS_IDLE 512 and targeted storage notes on takeover, packaged-texture recycling (pkg_tex_put),
  cached zero-copy upload sources (texture-only pools keep a per-batch buffer), retired CPU-written IDs without a
  view get no texture, mesh pipelines without a vertex function, image binding upgrades with pixel-format views,
  F2FP/I2FP and other translator fixes not already here (its second F2IP dropped), loop_guard and tg_fence,
  the GPU watchdog, the eventfd poll timeout, the profile (16 GiB alias region, mem_map_limit, tex_flush_upload,
  tex_dirty_upload) and its shader tables.
- Tests adapted: t_alias_takeover (textures in a pool), t_cpu_tex (retired descriptors), t_res_guard (512-submission
  idle window), t_upgrade_alias (ghost entry), t_pool_chunks (contiguous pools in a growing table), t_present_alloc
  (layer sized to its pictures after upstream's crop change), t_hid (poolstat / texstat stubs).
- Translator rebuilt from the merged source; chain fe655346ea1c.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fpedrolucas95 added a commit to fpedrolucas95/nxnative that referenced this pull request Nov 6, 2026
…n unset offset and dropped agl's shaders

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fpedrolucas95 added a commit to fpedrolucas95/nxnative that referenced this pull request Nov 6, 2026
…mmon match 68bbe98b3bfd9876 this tree's bahs_shaders leaves out (seedds#1444's tables had it)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gnosticgeek pushed a commit to gnosticgeek/nxforge that referenced this pull request Nov 6, 2026
…ead of a host crash

nvnMemoryPoolGetFlags, nvnMemoryPoolMap, nvnMemoryPoolGetSize, nvnBufferGetAddress, nvnBufferMap, nvnBufferGetSize, nvnBufferGetMemoryPool and nvnBufferGetMemoryOffset read through their argument without a check. When the game's allocator gives nvnBufferInitialize no pool (Ocarina of Time on entering Hyrule Field: `BufferInitialize: pool has no storage (pool 0x0 ...)`), the next getter call on the null pool crashed the host (SIGSEGV at 0x4 in h_nvnMemoryPoolGetFlags). They now answer 0 or NULL.

This only moves the failure: what made the game's allocator return no pool is not known. From seedds#1444 (hle_nvn.c); the reference entry notes the case.

Checked: make -C dm/host GAME=040074A01BF12000 builds; test_docs.py and docs_symptoms.py --check pass. Not played.
javierdv7 pushed a commit to javierdv7/nxnative that referenced this pull request Nov 6, 2026
…it: the same rows, so the NSP script's table check passes (PR seedds#1444 had them in another order)
@seedds

seedds commented Nov 6, 2026

Copy link
Copy Markdown
Owner

Thank you for this huge amount of work and the 94-minute run across so many areas. The base port has landed on main in b1d7c70 and 6121fd7, and mem_map_limit is on. I'm leaving this open because it covers areas I haven't played and has fixes I haven't checked, such as finalized texture IDs, copies into uploaded textures and hang guards. It would help to split what still reproduces on current main into small PRs. Final checks on the rebased tree (full shader build, walks, regression) are still running, so please report anything you see.

@PucaVaz

PucaVaz commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Test report, part 1b: past the shader split, the build finished (42,851 of 42,854 shaders), but the Mac app came out without its pipeline archive:

pso_offline: 34474 pairs: 0 bases, ... left out as the host leaves them: reflection 34474, ...
[RED] pso_offline: no base to build

e03bdc8 takes dm/gfx/tools/pso_offline.py back to before cb34473: it drops import romfs, shader_lib, romfs.Path(lib_dir) and shader_lib.view(a.msl). So pso_offline.py looks for each <key>_b.json in shader/cache/b-73b8c3e231ca/, which the build has already packed into b-73b8c3e231ca.img and removed, and every pair is left out. Keeping main's version of the file and adding only this branch's or vj.get('mesh_stage') condition should fix it (git diff c83c48f2 HEAD -- dm/gfx/tools/pso_offline.py is the whole change).

javierdv7 pushed a commit to javierdv7/nxnative that referenced this pull request Nov 6, 2026
…eedds#1444 added a second beside Star Fox's, and the host aborts at load on a duplicate)
@PucaVaz

PucaVaz commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Test report, part 2: e03bdc8 (with the split's shader_map.tsv order from part 1) built from the v131072 NUP on an M4 MacBook with 24 GB, macOS 27.2.

  • Shaders: 42,851 of 42,854 built (chain 73b8c3e231ca). Three agl compute shaders failed: 1f78730053feb036 and e172bd7ec218ab8e (agl_technique_pfx.sharcb) with fatal error: bracket nesting level exceeded maximum of 256 from metal, and 68bbe98b3bfd9876 (agl_common.sharcb) with NotSupportedException: Ampere instruction 481 at 0x0 (…020c0481) is not implemented.
  • Pipeline archive: none, as in part 1b.
  • The app stops right after launch with the duplicate ListVirtualInputDevices takeover yoBoss283 reported: hle_audio.c has this branch's h_ai_ListVirtual and main's h_is_List (67f1d00, already in c83c48f).

With both fixed (this branch's copy of the takeover removed, and c83c48f's pso_offline.py plus the mesh_stage check) the chain stays 73b8c3e231ca, so a rebuild only relinks the host and repacks; I haven't run that build yet. For comparison, main at 75c1a8c (with #1453, #1455, #1332 and #1446 on top) on the same save and settings, in two scripted runs: 600 s in Link's house at 45 fps (frame p50 22.1 ms, p95 23.4 ms); then, from a fresh load, Saria's greeting and 600 s of walking near the house at 39.5 fps (p50 23.9 ms, p95 36.7 ms); footprint up to 11.5 GB, no GPU errors.

@ksolenk38ze

ksolenk38ze commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Hi everyone, and thank you @seedds and @lunks for landing the incremental bindless pool patching (2eb71820), the pool-seen bitmap (88c7e03f), and the sRGB/linear image-view aliasing (a9d06b6f) on main overnight! Also a huge thank you to everyone who has been reporting issues, sharing traces, and testing fixes on Ocarina of Time (@mbanusic, @TheGoldfish11 on #1326, @PucaVaz on #1385/#1332, @PaulEins on #1433/#1445, @aband-goin on #1347, @enjoyerofslop on #1428/#1439, @PromethOps on #1453/#1455/#1459, @aksmith-git on #1436/#1458, @MetaIX on #1375/#1376).

No worries at all on the PR pace — we are continuing our playthrough right now from Dodongo's Cavern / Hyrule Field up to Adult Link, rebasing cleanly onto main as we go, and fixing / verifying each issue step by step so nothing gets lost on either side.

We have rebased oot-switch2-fixes (d2aff9f0) onto 88c7e03f, combining 100% of main's new bindless pool infrastructure with our remaining Ocarina of Time (0400486024DEC000, Switch 2, v0 & v131072) fixes. Here is our current tracking table (we only mark visual or frame-time fixes as verified once confirmed in-game during the playthrough):


1. Indirect mesh draws & GPU page faults / hangs on room transitions (#1326, #1347, #1458)

  • Bug in OOT: GPU page faults (kIOGPUCommandBufferCallbackErrorPageFault / BIF0 page fault) and freezes when entering new rooms or executing indirect mesh draws when threadgroup counts exceed Metal limits or when retired packaged textures are freed while still referenced by in-flight bindless submissions.
  • Code fix:
    • dm/gfx/nvn/hle_nvn.c (h_nvnCommandBufferDrawMeshTasksIndirect), dm/gfx/nvn/nvn_rec.h (OP_DRAW_MESH_INDIRECT), dm/gfx/nvn/nvn_mtl.m (mesh_tasks_draw, dpc_clamp, wk_note / wk_dump): implement DrawMeshTasksIndirect with threadgroup clamping and per-fence shader ring diagnostics.
    • dm/gfx/nvn/nvn_mtl.m (pkg_retire_note, pkg_retire_hold, pkg_tex_put, pkg_tex_take): hold retired packaged textures across a 2-fence grace window for bindless submissions and recycle <= 16 MB textures across a 64-slot pool.
  • Status in OOT: Verified in-game (0 crashes across Kokiri Forest, Inside the Deku Tree, Hyrule Field, Kakariko Village, Goron City, Dodongo's Cavern, and King Dodongo).

2. Terrain / rock blackouts and 50.8 GB / 300-frame residency explosion (#1404, #1455)

  • Bug in OOT: Entering Hyrule Field or Dodongo's Cavern caused g_alias_taken to evict live terrain blend maps and grew residency by 50.8 GB per 300 frames because ~12,000 retired treg_t descriptors over reused storage were re-resolved during bindless pool walks and storage takeovers went un-noted in g_ser_log.
  • Code fix:
    • dm/gfx/nvn/nvn_mtl.m (alias_take_over, alias_note_evicted, alias_overlaps, alias_sweep, tex_mtl_, pool_entry): record evicted serials via ser_note in alias_note_evicted (without an un-noted g_ser_gen++) so pool_gpu patches tables incrementally (t_upgrade_alias); mark retired descriptors over taken storage gone in alias_sweep; skip unread retired packaged descriptors in pool_entry (!pool_seen(id_) && !tex_get(serial), t_cpu_tex & t_pool_chunks).
  • Status in OOT: Verified in-game (g_alias_taken = 0, GPU allocation steady at ~3.0–4.2 GB).

3. Global memory table overflow (>256 contiguous 64 KB pools, related to #1326)

  • Bug in OOT: OOT allocates 521 contiguous 64 KB pools for its 32.56 MB arena; GMEM_RUN_MAX = 256 split them into 3 entries and overflowed the 511-entry DMSH_GMEM_MAP_ENTRIES table (causing raw global memory loads/stores at the tail of the table to miss).
  • Code fix:
    • dm/gfx/nvn/nvn_mtl.m (GMEM_RUN_MAX, gmem_map): raise GMEM_RUN_MAX from 256 to 1024 so contiguous pools merge into a single range.
  • Status in OOT: Verified in-game.

4. Uncompressed 260×260 / 68×68 terrain tiles in GPU-written pools

  • Bug in OOT: Tera-engine 260×260 and 68×68 uncompressed 2D terrain heightmap/blendmap tiles share a memory pool with GPU-written textures, causing tex_cpu_content and cpu_unc_drop to drop their CPU-written classification.
  • Code fix:
    • dm/gfx/nvn/nvn_mtl.m (tex_cpu_content, cpu_unc_drop): preserve CPU-written classification for 260×260 and 68×68 uncompressed 2D tiles.
  • Status in OOT: Verified in-game.

5. Blocky / pixelated lava rocks & King Dodongo heat-haze / lava pool shaders

  • Bug in OOT: Certain non-destructible rocks in Dodongo's Cavern, the central lava pool in King Dodongo's room, and the boss intro cutscene showed blocky mosaic pixelation.
  • Code fix:
    • dm/gfx/nvn/nvn_mtl.m (tex_need_pfv, tex_init_fill, attach, pkg_copy_absorb): add MTLPixelFormatRG8Unorm/RG8Snorm, R16Unorm/R16Snorm/R16Float, RG16Unorm/RG16Snorm/RG16Float, and RGBA16Unorm/RGBA16Snorm/RGBA16Float to g_pfv_srgb so format-reinterpreted views receive MTLTextureUsagePixelFormatView; skip initial zero-fill when an overlapping alias already exists in g_alias; absorb GPU-to-packaged-texture copies without re-uploading stale CPU zeroes.
  • Status in OOT: Fixed — pending in-game verification (will verify on our next trip back to Death Mountain / Dodongo).

6. Frame-time spikes on entering Kakariko Village, Hyrule Field, Skullwalltula drops & boss cutscenes (#1385)

  • Bug in OOT: Noticeable FPS drops / micro-stutters when entering Kakariko Village or Hyrule Field, when Skullwalltulas drop from the ceiling in the House of Skulltula, and during the boss death cutscene.
  • Code fix:
    • dm/gfx/nvn/nvn_dirty.c (nvn_dirty_reprotect_batch): coalesce contiguous dirty pages into a single mprotect syscall instead of one syscall per page.
    • dm/gfx/nvn/nvn_mtl.m (pso_manifest_append, pso_offline_warm), dm/gfx/tools/pso_offline.py, dm/games/0400486024DEC000/pso_manifest.tsv: prewarm 1,705 PSOs offline (including geometry/pulling pipelines) and persist newly compiled PSOs at runtime.
    • dm/gfx/nvn/nvn_mtl.m (sdx_walk, tbdr_on): treat bindless draws (NVN_RB_TEXU) as reading all candidate attachments in store-action lookahead (t_lookahead_bindless).
    • dm/gfx/nvn/nvn_mtl.m (guest_or_mono_ns): fall back to CLOCK_MONOTONIC in gpu_s_guest_ns and rep_ticks when guest_ns() returns 0 in standalone unit tests (t_feedback).
  • Status in OOT: Fixed — pending in-game verification (testing right now in Hyrule Field / Kakariko Village / Zora's Domain / Jabu-Jabu on the way to Adult Link).

fpedrolucas95 added a commit to fpedrolucas95/nxnative that referenced this pull request Nov 6, 2026
…ds#1444 brought back its own beside upstream's, and the loader stops on a duplicate)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mbanusic

mbanusic commented Nov 6, 2026

Copy link
Copy Markdown

Data from main for items 1 and 3. M1 Max, macOS 27.0.1, v131072 .nup, --platform mac-app, main at 0f510fd (chain cfcc3a82c78b), no DM_* switches, same autosave as #1326.

Item 3 is already covered on main. DMSH_GMEM_MAP_ENTRIES is 8192 on main (dmsh_abi.h:81), and GMEM_RUN_MAX no longer exists. This run logged raw global memory: pool table of 2003 ranges with no "more memory pools than the … entries" red line. In OoT the table doesn't overflow on main, so this item can probably be dropped when you rebase.

Item 1: the early page fault still happens on main, so it's a good test case for the retire hold. In every run on main (9 over the last day, including this one on 0f510fd), it faults once, roughly 15–65 s after the autosave loads:

[dm] [nvn-mtl] [RED] segment command buffer execution error: … Caused GPU Address Fault Error (0000000b:kIOGPUCommandBufferCallbackErrorPageFault)
[dm] [nvn-mtl] [RED] game shaders of failed command buffer #1 (fence 6422, segment 11): 140: …
gpuEvent .ips: restart_reason_desc "BIF0 page fault", is_read true, requestor 36, address 0x180ceb6800

It's always segment 11 or 12. Things it isn't, each tested on main with the fault still there:

  • the bound resources (DM_RES_CHECK=1 is clean);
  • argument-buffer reuse (encoded for every draw);
  • indirect-count multi-draw chaining (switched off).

One correlation holds in all 9 runs. The line just before the fault (7–17 log lines earlier) is always the first time raw global stores reach one group of 6 pools that were all created at load:

raw global memory: the stores wrote in 6 pool(s) the host had not learned (log 7501, 8 such pools so far, 9 learned; the pools were added 54794-54794 ms before): 0 of them hold one of the 0 uniform shadows …

The pool age in that line matches the fault time in each run (15 s → early fault, 65 s → late fault). So the fault follows the first raw store into that pool group, not a room change. No uniform shadow lies in those pools, and gmem_map() makes every pool in the table resident, so I haven't found the mechanism. This may be the same fault you're fixing with pkg_retire_hold, or a separate one.

Your item 1 fix (pkg_retire_note / pkg_retire_hold and DrawMeshTasksIndirect with clamping) isn't on main yet. If you split it into its own commit or PR on top of current main, I can run it on this M1 Max: it reproduces within about a minute, so it's a quick yes or no.

@lunks

lunks commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

@mbanusic thanks, that is a useful correlation: "9 of 9 with the same line just before it" is the strongest lead on the page fault so far.

One request, and it is not proven that it helps: could you run #1427 on the same autosave? It changes when the raw global-memory pool table words are taken (at commit, per pool the host has learned), which is the part that line is about. One run is enough. What would tell us something: whether the fault still comes at segment 11/12, and whether the "stores wrote in N pool(s) the host had not learned" line still precedes it. If it faults the same way, that rules the table words out and we are back to the mechanism you were looking for.

@mbanusic

mbanusic commented Nov 6, 2026 •

Copy link
Copy Markdown

@lunks I ran #1427 once, on the same autosave. Same M1 Max, built as 0f510fd + #1427 (4d7f1d1), chain unchanged (cfcc3a82c78b), no DM_* switches.

It faults the same way, so the table words are ruled out.

  • Raw pool table words follow the pools at commit: a pool made after a raw shader was encoded no longer reads 0 #1427 was active: raw pool table words at commit: 7589, of them 16 held an older table than the current one and 17 the current one behind the pools.
  • It's again the first page fault, in segment 11, and the 6-pool line still comes just before it (16 log lines earlier):
    408: raw global memory: the stores wrote in 6 pool(s) the host had not learned (log 5708, 8 such pools so far, 9 learned; the pools were added 25578-25578 ms before): 0 of them hold one of the 0 uniform shadows …
    424: [RED] segment command buffer execution error: … kIOGPUCommandBufferCallbackErrorPageFault
    427: [RED] game shaders of failed command buffer #1 (fence 5390, segment 11): 244: 14b728f8d7b9718c_b fb1ed54be1baced1_b …
    
  • gpuEvent: BIF0 page fault, is_read: true, requestor 20, address 0x17dfbfef40.
  • This time it came earlier (about 26 s after load, pool age 25.6 s), and the game didn't recover. The next submissions failed (2 Hang, then 8 SubmissionsIgnored, plus two MMU interrupt gpuEvents), and the game stopped at the foot of the ladder. That's the original Ocarina of Time (0400486024DEC000 v131072, Mac): GPU hang about 10 minutes into play takes WindowServer down #1326 freeze, following the same first fault.

So the fault still follows the first raw store into that group of 6 pools, even with every argument block's table word pointing at the current table at commit.

@ksolenk38ze

Copy link
Copy Markdown
Contributor Author

Hi everyone! Quick mid-day update as we continue our full playthrough (just finished Hyrule Market / Hyrule Castle / Great Fairy and heading into Zora's River & Zora's Domain right now).

First, to answer the points raised in the comments above:

1. Replies to @PucaVaz, @yoBoss283, @mbanusic & @lunks

  • Build & table issues on the older pre-rebase snapshot (@PucaVaz, @yoBoss283):
    • hle_audio.c duplicate ListVirtualInputDevices hook, shader_map.tsv row ordering, and -fbracket-depth=1024: those came from before our rebase onto current main (which landed those pieces upstream). They are all resolved on our rebased branch.
    • pso_offline.py (no base to build): good catch — after rebasing onto main's pso_offline.py (which keeps import romfs, shader_lib), we kept only the vj.get("mesh_stage") check so mesh-shader pairs in shader_pairs.tsv / pso_pairs.tsv are skipped cleanly during offline vertex/fragment base archive generation instead of failing pre_desc.
    • First-visit stalls without a prebuilt .mtl4a archive (@yoBoss283): spot on — and even with a warm archive, entering Hyrule Market for the first time submits 78+ uncached draws in a single submission (see fix unity: read the pre-2019.3 serialized / Shader formats #2 below).
  • Testing pkg_retire_hold & DrawMeshTasksIndirect against the segment 11/12 BIF0 page fault (@mbanusic, @lunks):
    • Agreed on Item 3 (GMEM_RUN_MAX): main's 8,192-entry DMSH_GMEM_MAP_ENTRIES table already covers the 521 contiguous 64 KB pools without needing the run-limit bump.
    • For @mbanusic: we just pushed our clean rebased branch to our fork (ksolenk38ze/nxnative, branch oot-playthrough-fixes / main) so you can directly test pkg_retire_hold (holding retired packaged MTLTexture allocations across 2 GPU fences + 64-slot recycling pool) and DrawMeshTasksIndirect on your M1 Max Kokiri ladder reproducer whenever you like!

2. Issues encountered after recent merges & how we fixed them today

While playing through Kokiri Forest, Great Deku Tree, Hyrule Field, Kakariko, Death Mountain, Dodongo's Cavern, Hyrule Market, and Hyrule Castle on the rebased codebase, we ran into several regressions and edge cases and fixed them along the way:

  1. Invisible foliage & tree bark on Ampere mesh shaders (DrawMeshTasks):

    • Cause: Mesh shaders in Foliage.Product.110 sample bark and leaf textures from the bindless pool without the translator setting pool_tex=true (!pool_seen(id_)). Skipping any retired descriptor in pool_entry() whenever !pool_seen(id_) && !tex_get(serial) dropped foliage textures that the guest pool manager retired before their first draw even though their backing pool storage was never overwritten.
    • Fix: In pool_entry(), only skip a retired descriptor when g_treg[id_].gone is set (i.e., its backing storage was actually reclaimed/overwritten), allowing never-overwritten mesh-shader textures to lazily resolve on first walk.
  2. Multi-second freeze when entering Hyrule Market (Castle Town):

    • Cause: Entering Hyrule Market submits 78+ uncached draws in a single submission whose vertex shaders have no hybrid pulling stand-ins (!vs->has_pull), while pso_predict_rest only admitted 2 background compiles (PSO_PEND_ACTIVE = 2, PSO_PREDICT_BUDGET = 2) once per submission and compiled the remaining 70+ pipelines serially on the submit thread.
    • Fix: Raised PSO_PEND_ACTIVE and PSO_PREDICT_BUDGET to 8, re-armed lookahead waves across long submissions whenever the previous wave completes, updated pso_predict_rest_ to call hybrid_get_ex(..., 0) (so lookahead never compiles missing pulling bases synchronously on the submit thread), and checked pso_pend_has(&k) before queuing speculative tasks.
  3. Camera-rotation stutters in Hyrule (up_big_src buffer churn):

    • Cause: Even while standing still, rotating the camera in Hyrule caused up_big_src to allocate and retire 3,600+ page-sized newBufferWithBytesNoCopy buffers per 300 frames (~12 per frame).
    • Fix: In up_big_src, reuse any covering MTLStorageModeShared buffer already retained in g_up_keep for the current upload batch and align no-copy windows to 8 MB boundaries within the pool bounds.
  4. 369 render pass splits per 300 frames in Hyrule (image_prepare on read-only integer views):

    • Cause: image_prepare was ending the active render pass (rp_end()) to upgrade textures whenever a shader bound a read-only non-float image view (dpf != NVN_DPF_FLOAT), even though img_binding already creates the typed MTLTexture pixel-format view without needing MTLTextureUsageShaderWrite.
    • Fix: Only split and upgrade in image_prepare when the image binding is writable or atomic (b->rw || b->atom).
  5. Indestructible bombable rocks in Dodongo's Cavern & blocky/pixelated dynamic-resolution cutscenes (agl_ndsr_vr):

    • Cause: Compute/image passes writing R32Uint views over RGBA8Unorm_sRGB targets either lost NVN_TEXTURE_FLAGS_IMAGE across re-registrations, dropped NvImageHeap alias views on upgrade, or replaced the base texture's sRGB pixel format instead of creating a typed view.
    • Fix: Persist NVN_TEXTURE_FLAGS_IMAGE on image bindings, preserve NvImageHeap across tex_upgrade (tex_upgrade_alias_rebind), and create R32Uint views over RGBA8Unorm_sRGB via tex_upgrade_pfv / img_fit.
  6. Sub-second black flickering during cutscenes & door transitions:

    • Cause: Skipping descriptor resolution on the first frame after mtl_reg_tex (pool_seen_clear) caused newly registered cutscene/door textures to bind the black dummy texture for one frame before the GPU feedback flag arrived.
    • Fix: Keep direct descriptor resolution in treg_tex / tex_mtl_ and direct pool walking in pool_gpu.
  7. Mesh shader user(locn5) link failure on Foliage.Product.110 (3a6340a04bf09797_b & a203347bb7bdbd03_b):

    • Cause: Their paired fragment shaders (2a7c48d595feaaeb_b, cd609edc78b467d8_b) read [[user(locn5)]], which the mesh shaders' SPH OMAP did not enable (and vs_pad only padded stage == "vs").
    • Fix: Added mtk_pad_mesh_fn in nvn_geometry.inc (mtk_pso) to automatically pad missing [[user(locnN)]] attributes on dm_vertex_t with float4(0, 0, 0, 1) when a mesh render pipeline fails stage-interface linking.
  8. Crash on scene exit / startup prewarm in MTL4ArchiveImpl::newArchiveReplyForKey+0xc8 (dispatch_retain(NULL)):

    • Cause: Disassembling Metal.framework on macOS 27 showed that when a .mtl4a archive entry in _archiveReader (impl + 0x30) has a zero-length reflection slice (refl1_size == 0), newArchiveReplyForKey sets the reflection dispatch_data_t pointer to NULL, then compares refl2_off == refl1_off (slice_offset + 0 == slice_offset + 0) and calls dispatch_retain(NULL).
    • Fix: Added arch_entries_ok in pso4_init to inspect _MTL4Archive's _archiveReader slices on open, rejecting and unlinking any .mtl4a file that contains a zero-length AIR or reflection slice.

3. Next Steps (New PR tonight)

We are continuing the playthrough right now through Zora's Domain, Lord Jabu-Jabu's Belly, and the transition to Adult Link. Tonight, once today's playtest is complete, we will open a brand-new, cleanly rebased PR containing all of these fixes in atomic commits and post the link right here in #1444 so everyone can follow along!

@mbanusic

mbanusic commented Nov 6, 2026 •

Copy link
Copy Markdown

@ksolenk38ze thanks for the branch. I tested oot-playthrough-fixes at 92c6f2d5 on an M1 Max: the Kokiri ladder reproducer, autosave, about 160 s of play, external monitor.

The segment 11 page fault is still there. It came in the same place as before:

  • The log line "the stores wrote in 6 pool(s) the host had not learned (… added 20279 ms before)" comes first.
  • A few lines later, failed command buffer patch_nso: recognize the whole offset-table jump family, not just x18 #1 (fence 4490, segment 11) reports kIOGPUCommandBufferCallbackErrorPageFault.
  • The gpuEvent says BIF0 page fault, is_read true, address 0x1607edcdc0.

This run recovered: there was 1 failed command buffer, the game played on, and it exited cleanly. Runs on main have done the same about 8 times in 11, so recovering doesn't show an improvement.

That's 13 of 13 runs with this fault, now including:

So retired textures being released early, and runaway indirect mesh counts, don't look like the cause of the segment 11 fault. It still lines up with the newly learned pools from the stores.

Also: on this build the loading video plays with no artifacts. On main 0f510fd and with #1427 it had visible artifacts, so one of the branch's other changes (possibly the up_big_src upload reuse or the descriptor resolution change) fixes that.

@mbanusic

mbanusic commented Nov 6, 2026

Copy link
Copy Markdown

Second run on the same build, from a Deku Tree autosave instead of the ladder: about 8.5 minutes in, during a fight, a whole-frame command buffer page-faulted (fence 133248, frame 22202; gpuEvent: BIF0 page fault, is_read true, 0x15d8a19180). No "pool(s) the host had not learned" line came before it.

On this branch, the new DM_NVN_GPU_WATCHDOG (on by default) then called _exit(70) right away ("stopping after command buffer fault … so no further submissions wedge WindowServer"), so the game closed. On main the same fault ends either in recovery after a few failed buffers or in a freeze; in our runs it recovered about 8 times in 11. Quitting on the first fault turns those recoveries into closes, so it may be worth making it opt-in, or only quitting when submissions actually stop completing (the 4 s timeout path).

@yoBoss283 yoBoss283 mentioned this pull request Nov 6, 2026
@ksolenk38ze

Copy link
Copy Markdown
Contributor Author

Thanks @mbanusic and @yoBoss283 for the detailed tests and feedback!

We have just rebased both oot-switch2-fixes and oot-playthrough-fixes on ksolenk38ze/nxnative onto latest main (e0dc79c9), which includes:

  1. Merged upstream fixes: 339d9f23 (gmem_commit_patch writing raw pool table words at commit when new pools are created, addressing the segment 11 GPU page fault) and deduplicated hle_audio.c (@yoBoss283).
  2. GPU watchdog fault policy (@mbanusic): DM_NVN_GPU_WATCHDOG now only exits after a 4.0 s submission hang timeout by default instead of calling _exit(70) immediately on survivable command-buffer page faults (use DM_NVN_GPU_WATCHDOG=fault only if you explicitly want immediate exit on any fault).
  3. pool_gpu stack overflow fix (SIGBUS / exit 138): moved the incremental pool patch working arrays out of pool_gpu's stack frame so dm_bigstack (1 MB) cannot overflow when REG_LOG/SER_LOG are large.
  4. Pipeline archive shard ordering & compaction cap: large already-compacted .mtl4a shards (>= 256 MB) are now searched first in g_arch4 and excluded from re-compaction (preventing Preparing Shaders from re-capturing 8,000+ bases into a single serializer and hitting LMDB's 1 GiB MDB_MAP_FULL limit on every launch).
  5. Mesh shader (ms) output padding from .img or loose .metal: mtk_pad_mesh_fn now reads via msl_data() (working with both packed b-<chain>.img libraries and loose .metal files) and shader_split.py pairs ms + ps BNSH variations.

… attribute layout, pulling-base archive retention, image-view upgrades and retired alias safety through the Forest Temple

Picture:
- dmsh_meshstage.py lays out all v_blocks of 32 vertices before p_blocks of 32 per-primitive attributes in mesh stage memory (and honors sph[0x35] bit 3 PointSize and ctl[0x5f] point/line topologies), so the Forest Temple paintings (Poe Sisters and Phantom Ganon, rendered by ee4ef51a4fddc28e and 83c0dbc51c5481e3 with max_v = 128, max_p = 64 and per-primitive brush-stroke colors) read p0 from the primitive block instead of vertex block 1's screen-space positions.
- fb_prepare ends the render pass when a draw samples R.rt.depth after an earlier draw in the same pass wrote depth (g_fb_dwrite): translucent geometry that reads the attached depth buffer for soft-depth fade (the Zora's Sapphire pedestal, Jabu-Jabu's interior walls) flickered black blocks on TBDR without a pass boundary.
- image_prepare keeps NVN_TEXTURE_FLAGS_IMAGE on g_treg[tid].t.d.flags and upgrades R32Uint format views over RGBA8Unorm_sRGB before the pass (tex_upgrade_pfv), and tex_upgrade keeps an NvImageHeap owner and rebinds g_by_serial, g_ghost and g_alias views (tex_upgrade_alias_rebind) so agl_ndsr_vr does not leave blocky tiles on volcanic rocks or dynamic-resolution cutscenes.
- bcrt_attach redirects renders into RGB_DXT1 (0x42) and RGTC1_UNORM (0x49) targets (flags 0x8) to an RGBA8Unorm / R8Unorm shadow texture and encodes them back on rp_end (bc_encode_bc1, bc_encode_bc4) for sky and water reflection baking.
- mtk_pad_mesh_fn (nvn_geometry.inc) and var_pairs (shader_split.py) pad missing locnN outputs in mesh shaders (3a6340a04bf09797_b, a203347bb7bdbd03_b) with float4(0, 0, 0, 1) when paired with a fragment shader that reads them.

Frame rate, pipeline archives and memory:
- ArchEpoch separates vd == 0 (pulling base) and vd != 0 (vertex-layout base) flush periods (ep->kind) so pulling bases always serialize into p%05d.mtl4a instead of %05d.mtl4a and survive pso_compact_dir compaction (pso_prebuild also probes PRE_PROBE pairs against g_pull_arch4 before trusting prebuilt.tsv); pso4_init places compacted shards >= 256 MB at the head of g_arch4 outside g_compact_files and validates _MTL4Archive entry sizes (arch_entries_ok).
- shader_prefetch_rest and pso_predict_rest_ copy the OP_CALL return stack (cur.ret) so lookahead continues across sub-command-buffer returns; hybrid_get_ex caches the reusable pulling base (vd == 0) on an uncached miss, and mtk_pso builds task/mesh pipelines on QOS_CLASS_USER_INITIATED.
- treg_tex and tex_mtl_ skip re-creating or ghosting an unread retired GPU texture when a live alias already holds its (pool, off) range (alias_overlaps), and alias_take_over indexes g_by_serial by (pool, page) and marks retired g_treg slots over taken storage gone.
- pool_gpu's patch scratch arrays (ids, ser_list, vals) are static under g_rmu instead of taking 1.96 MB on the 1 MB dm_bigstack.
- Profile 0400486024DEC000: 16 GB mem_alias (0x400000000) for multi-dungeon virtual pool churn, v0 build entry, and updated README note.

Checked: test_dmsh_meshstage 28, t_cpu_tex --metal 68, t_upgrade_alias 14, t_feedback 194, t_lookahead_bindless 22, t_pool_notes 81, dm/host/tests, test_docs, test_env_switches, test_game_profile, test_dmsh_pool_arrays, all 0 failed.
@ksolenk38ze

Copy link
Copy Markdown
Contributor Author

Opened #1590 as a clean follow-up rebased on main (b2d46b86), carrying the remaining renderer fixes from this branch along with the new fixes from playing through the three child dungeons, the adult timeline transition, and the Forest Temple (Poe Sisters and Phantom Ganon). Future updates will be pushed to #1590.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation game: 0400486024DEC000 A game host The Horizon host: SVCs, services, threads, memory (dm/host) new game Adds a game profile that main does not have yet nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests) packing Building an IPA or a Mac app: the NSP script, extraction, the shader split, the packers shader chain The shader translation chain (DMSH_CHAIN): a change rebuilds every game's shaders tools Tools and scripts (dm/tools, scripts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants