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).
- 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.
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.
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.
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_*).
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
- 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).
- 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).