Commit Graph
9 Commits
Author SHA1 Message Date
seedds 79d82f7b64 Remove the D2R code and the legacy frame step
D2R (Diablo II Resurrected) has no profile and its code could not run here: the
host-call svcs its cuts emitted only died, the touch-run-v4 rule set needed a
missing dm/PRODUCT, and the host files its hooks called were never in this
repository. Removed with it:
- rewriter: D2R cuts, observation gates and parameter slots, the touch-run-v4
  rule set and private gates, the boot list, the cut scope column and the
  KRES / KASPECT key slots (fixups.tsv keeps the four thread slots; no
  params.tsv any more); dm/tools/product.sh
- host: D2R save edits, add-on content, render-scale controller, time()
  takeover and Terror Zone clock, crash decoding at D2R offsets, host-call
  registry and stubs, i18n, UI-screen, shell-app loader, zero-stripped
  archives, boot profiling hooks with no implementation; D2R headers, tests
  and scripts; dm/ios/Sources/dm_touch_controls; dm/third_party/libdeflate
- graphics: runtime extrapolation, world freeze, iPad UI shift, shop drag
  image, brightness LUT, visual ruler, bloom / FXAA shader hashes, DM_GFXUSE,
  the eco-fps setting, the loading-screen gate; shader_map.py,
  nometal_run.py, nvn_slots.py, nvn_slots.tsv and the PC-texture samples

The legacy frame step (frame_step legacy, DM_FRAME_STEP) is retired: the
Breath of the Wild and Tears of the Kingdom stubs lose their mode test.
Breath of the Wild's interval-controller cuts stay: the framework keeps the
controller's interval while the game's VFR override holds.

patch_nso.py output is byte-identical for all 15 games on this machine except
the two frame-step stubs; all 18 profiles build; the host tests pass (their
Makefile now builds the general tests only).
2026-10-21 02:09:49 +08:00
seedds b3f25a09bb Shader chain: translator fixes for 39 shaders; compiled shaders cached by their Metal source
- Ryujinx (vendored, Instructions.cs GenerateTextureSample): texel offsets read from a
  register are built with OpCompositeConstruct + Offset, and a four-offset gather becomes
  four one-offset gathers. Upstream wrote an OpConstantComposite, invalid SPIR-V that
  SPIRV-Cross refused (2 shaders each in Wonder, Link's Awakening, TOTK, Age of Calamity).
- dmsh_xlate: a shader whose SPIR-V declares a 64-bit float is translated again with
  Ryujinx's DoubleToFloat pass (30 TOTK main-material vertex shaders); TOTK's
  visibility-counter vertex shader gets MacNativeGames' subgroup lowering (MIT).
  Every other shader's SPIR-V is byte-identical.
- New dm/gfx/tools/dmsh_mtlcache.py: dmsh_build.py compiles each MSL through a cache keyed
  by the source, the compile flags and the compiler (<cache>/cas/metallib/). Before a build
  it is filled from the earlier b-*/ folders beside the output and IOSOUT, and from
  DMSH_PREFILL, once a fresh compile of a few of a folder's shaders reproduces their
  libraries byte for byte. A chain change that leaves a shader's MSL unchanged no longer
  recompiles it.
- dmsh_build.py clones files with the clonefile call instead of one cp per file: each fork
  of the build process cost about 6 ms and serialized the finishing phase.
- TOTK's rebuild after the translator fix: 49 min -> 9 min, libraries byte-identical to
  the previous build apart from the 39 fixed shaders. All 12 chain versions are new;
  Dread, 13 Sentinels, Three Houses, TOTK and Wonder are rebuilt (Mac + iOS + c1_full.tsv),
  the other six follow.
2026-10-18 23:55:19 +08:00
seedds 840171d448 TOTK's 3D scene renders; BotW issue #9 memory and 30 fps fixes; in-pass clears; GLSLC capture in the NSP script
Tears of the Kingdom (two profile keys, off for every other game):
- render_cond: NVN conditional rendering is evaluated at replay from the
  timestamp reports' counter 0; before, every conditional clear ran and the
  lighting passes drew nothing.
- tex_dirty_upload: textures the game fills from the CPU without an NVN flush
  (its 121-layer ASTC terrain arrays) are found through write-protected pages
  and uploaded; before, they stayed empty (magenta in ASTC).

Breath of the Wild, issue #9 (iPhone 16 Pro Max killed for memory in the first
shrine; an 8 GB iPhone gives the app 3,375 MB):
- Finalized textures' serials no longer stay in the serial table for good:
  live serials are marked at nvnTextureInitialize, dead ones resolve through a
  512-entry table (about 10 a frame in BotW before, 276k after 25k frames).
- The memory-pool tracking table grows past 4,096 entries (BotW reached 4,006).
- Most of the growth was the defer_drain leak fixed in 0fc0ce4: the shrine now
  stays at 2.8-2.9 GB resident on the Mac, about 500 MB under the limit.
- Falls back to 30 fps at the right speed when the GPU can't hold 60: two cuts
  make the frame-interval controller always use its GPU-time path, and the
  profile key gpu_timestamps segment gives each timestamp report its
  segment's GPU start / end (the default, submission, is unchanged). Under
  load, interval 2 held at 0.93-0.98 of real time (0.78-0.95 before). The
  check that it still holds 60 on a quiet machine is pending.

NVN: clears inside a pass, with a partial channel mask or a partial scissor
are drawn as a triangle in the open pass instead of dropped, and 8-bit indices
written by the GPU earlier in the submission are widened on the GPU (TOTK red
lines 6 / 7 / 48). Adapted from MacNativeGames (MIT, dm/third_party/macnativegames).

NVN vertex fetch: 8 / 16-bit integer attributes fed to an input of the other
sign are widened by their own sign (CPU conversion, red 96 once); before, the
signedness swap widened them the other way and Three Houses' terrain heights
below 0 left the screen (no ground under close-up cameras). The pass dump's d
line shows polygon offset and depth clamp.

NSP script: a GLSLC capture stage for profiles with shader_glslc_capture
(Three Houses' 9 run-time shaders), so only the NSPs and prod.keys are needed.

AGENTS.md: only the coordinating session runs the multi-game smoke test.

Each part was checked on its own game on the Mac. The multi-game smoke test
runs after this push (Wonder and Engage already passed on the same changes
minus the vertex-fetch fix). The translator fix and its chain rebuild are not
in this commit.
2026-10-18 22:30:11 +08:00
seedds 14fbcf9c37 Only GPUs with BC textures are supported: no-BC decompression paths removed
Only the latest iPhones are supported now: A17 Pro and later, i.e. iPhone 15 Pro and newer, and M1 or
later iPads. All of them read BC textures natively. On older GPUs the decompressed textures didn't fit in
memory anyway: Breath of the Wild needs 3.9 GB instead of 2.8 GB.

- nvn_mtl.m: BC textures are always created and uploaded as BC. Removed: no_bc(), the GPU bcd kernel for
  BC1-5, CPU decompression of BC6H/BC7 at upload and in buffer-to-texture copies, and the ASTC to
  decompressed-format copy. The rule that a BC texture is never a render target or viewed raw stays
  (GitHub issue #4).
- dm/gfx/tex/nvn_bcdec.c/h, dm/third_party/bcdec and DM_TEST_NO_BC are gone. The docs are updated.
2026-10-18 10:29:30 +08:00
seedds 787f9a178e Hades runs on the Mac through a new Vulkan-on-Metal layer
Hades (0100535012974000, update 1.0.38233, SDK 9) renders with Vulkan through The Forge, not NVN.
The host now implements its 100 vk* imports on Metal in dm/gfx/vk/hle_vk.m, and the Vulkan loader
(subsdk0) and NVIDIA's driver (subsdk1) are not loaded. The title menu, the intro and Tartarus gameplay
run at 60 fps on the Mac, and a Metal validation run is clean. The iPhone build is untested.

- dm/gfx/vk/hle_vk.m: one Tegra X1-shaped device. Memory is a lazily made shared MTLBuffer; images are
  private MTLTextures. Command buffers are recorded on the host and replayed at vkQueueSubmit on the
  layer's own queue, which signals an MTLSharedEvent. Descriptor sets, update templates, render passes
  and pipelines are supported. The swapchain presents through the NVN layer's present path.
  vkGet*ProcAddr look names up in the HLE table, also trying a name without its KHR suffix.
- dm/gfx/tools/vk_shaders.py: SPIR-V to one metallib plus a slot table. It renumbers bindings per kind,
  flips vertex y, and lists only the resources the Metal entry point takes.
- nvn_mtl.m/h: mtl_device, mtl_ext_tex and mtl_present_ext for external producers. Their present
  waits on the producer's event.
- hle_nvn.c: dm_gfx_enter/leave and dm_vk_drain, so the background suspend also covers Vulkan submits.
- hle_oe.c: GetNotificationMessageEvent returns a host-owned auto-clear SystemEvent. The SDK's version
  returned an event the no-op oe::Initialize never created.
- patch_nso.py: the byte-table jump search looks 16 instructions back, not 8 (Hades main+0x1135d0).
  The output for every other module is byte-identical.
- Profile key `graphics vulkan`: build_ipa.sh ships $MSL_IOS/vk instead of the NVN chain libraries.
- dm/third_party/vulkan-headers: Vulkan-Headers 1.4.363, unmodified.
- dm/.gitignore: per-game host binaries (dm/host/dmhost_*).
2026-10-18 10:29:06 +08:00
seedds e734ced7d9 Zelda Link's Awakening runs on the Mac (profile 01006BB00C6F0000, 1.1.0, SDK 8); BotW HUD prompt boxes fixed
BotW: the button-prompt shadow samples an R8 blur whose swizzle (R,0,0,1)
made alpha 1, so every prompt got a solid box. New profile key
alpha_from_red takes alpha from red for the named shader.

Link's Awakening:
- NVN lower-left window origin (negative viewport height, winding flip,
  flipped present and raw screenshots)
- texture copies with format change, scaling, mirroring and depth
  (copy_t2t_draw); SetCopyImageStride; nvnWindowGetPresentInterval
- oe::PopNotificationMessage, vi SetLayerCrop / DestroyLayer /
  CloseDisplay / Finalize, audren P_SIZE 0x40 for SDK 8, hid style-set
  update event signalled once on bind
- Vorbis movie audio through stb_vorbis (dm/third_party/stb_vorbis)
- patch_nso jump tables: other index registers, mov copies, masked copies
2026-10-17 08:28:44 +08:00
seedds b68ac089a3 SM3DW magenta blocks fixed (same-pass feedback snapshot); English default language; English-only comments, bilingual README
- Magenta 16x16 blocks in Super Mario 3D World 1-1 (iPhone only): the composite shader 66a71a3081b91b9a
  renders into the RGB10A2 image while sampling it in the same pass. That is undefined in Metal: the
  M4 Pro reads the old content, the A20 Pro sometimes returns whole 16x16 blocks as (1,0,1). Found with
  the new device self-check DM_NVN_MAGSCAN (blocks first appear on that attachment, and still appear
  with the suspected particle dropped). fb_prepare ends the pass, copies the attachment level into a
  snapshot and binds the snapshot for that draw, only for shaders in the new profile key feedback_snap
  (doing it for every shader cost BotW 16.6 -> 36.6 ms). DM_NVN_FB_SNAP=0 / all / <keys> overrides.
- The game language now defaults to English (nn::oe::GetDesiredLanguage returns en-US; DM_LANG=zh-Hans
  in Documents/env.txt for Chinese).
- Code comments, docstrings and docs are English only; the zh-CN doc twins are removed. README.md has the
  English text followed by the same text in Chinese. Files the shader chain version hashes keep their
  bilingual comments (editing them changes every game's chain version).
2026-10-17 00:41:10 +08:00
seedds 18515e6797 Movies: VP9 decoding with libvpx
- dm/third_party/libvpx: the VP9 decoder of libvpx v1.17.0 (upstream
  6df3ec3, BSD 3-Clause), unmodified: the 71 sources a VP9-decoder-only
  arm64 build compiles, their headers, and the generated configuration
  in config/ (one config for Mac and iOS, NEON, no run-time CPU
  detection). README.md records the configure line.
- dm/host/Makefile builds it file by file into gen/vpx/libvpx.a, so host
  changes do not recompile it. gen_build.py now collects sources and
  header paths from every clang line of make -n (host link line first),
  so the iOS project compiles the same files.
- hle_movie.c decodes VP9 packets with libvpx instead of emitting black
  frames. Each decoder has its own host thread (guest threads run on
  SDK stacks, too small for libvpx); the guest thread that sends a packet
  or returns an output index waits for the decode and signals the
  events itself. Packets are decoded in arrival order from one queue;
  I420 is converted to NV12 with NEON. The destructor logs decode times.
- Engage's 94 s opening movie decodes completely (2,816 of 2,816 frames,
  about 2 ms per frame on the Mac). The iOS project compiles and links
  with the decoder (not yet run on a device).
2026-10-14 23:15:44 +08:00
seedds d1b17080ed smbw-mobile: Mac host boots Mario Wonder v0 into its frame loop
Generic host, gfx and tools taken from d2r-mobile (MIT), with the D2R
gameplay, diagnostics and Blizzard/Granny/movie layers removed.

- hle_hid.c: generic standard-controller layer (all Npad styles)
- hle_sdk16.c: newer-SDK oe/time/pl/vsync/diag hooks
- hle_offline.c: offline stubs for prepo/ldn/socket/ssl/nifm/nsd/friends/ngc/err
- hle_fs.c, hle_account.c: SDK 16 overloads
- loader.c: unreferenced forced hooks only logged (DM_FORCE_STRICT=1 aborts)
- NVN: API 55.15, 13 newer names, ~45 state-only functions, tex_t packed
  to 0x80 (Mario allocates NVNtexture as 0x80; 0x88 corrupted the heap)

Frontier: null read at main+0x64763c inside the frame loop.
2026-10-12 22:04:20 +08:00