Repository navigation
Ocarina of Time takes the launcher's Render scale: the 3D views at that fraction of the game's own size, the dynamic resolution held at its top level (Kokiri Forest docked at 0.75: GPU p50 15.77 → 14.31 ms, 60 fps held) - #1903
Open
FifteenPen wants to merge 1 commit into
Open
FifteenPen wants to merge 1 commit into
FifteenPen wants to merge 1 commit into
Conversation
1 task done
ivan-leschinsky
pushed a commit
to ivan-leschinsky/nxnative
that referenced
this pull request
Nov 9, 2026
…at fraction of the game's own size, the dynamic resolution held at its top level (Kokiri Forest docked at 0.75: GPU p50 15.77 → 14.31 ms, 60 fps held) Ported from seedds#1903 (open upstream) onto this branch: its own changes from its merge base with main, conflicts resolved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U35V38c6UYLbzyyPx6Up7P
…at fraction of the game's own size, the dynamic resolution held at its top level, as on Breath of the Wild and Tears of the Kingdom (Kokiri Forest docked at 0.75: GPU p50 15.77 -> 14.31 ms, 60 fps held) The 3D views' sizes come from the scale the engine stores in its view-size update (v131072 main+0x31d3200, now found by its fingerprint), but that store and the size loop after it run only in a frame where the dynamic-resolution update answers "new scale", which at a steady frame rate it never does. Two stubs in that function: at the update's answer, a host scale below 1.0 not yet applied makes the frame recompute the sizes once; at the store, the game's scale is multiplied by the host's. The dynamic-resolution level stub returns the top level under such a scale, so the size is fixed. 1.0, the loader's default, runs the game's own code. The rewriter marks the build RENDER_SCALE, so the launcher offers the setting. docs_patches.py's dry run puts a rule's other functions 8 MB apart from 0xa000000 instead of 16 MB apart from 0x10000000: a stub that returns into one of them (here the view-size update) needs a B within +-128 MB of the stub area. Measured with scripts/bench.py on a --platform mac build of main d8b2b64 with the module rewritten by this change, kokiri-deck, docked, Apple M4 Pro, two runs each: 1.0 1536x864, GPU p50 15.77 ms, 46 fps (the frame step holds 2 vsyncs for stretches); 0.75 1171x659, 14.31 ms, 59.6 fps; 0.5 781x439, 13.25 ms, 59.7 fps; the pictures clean at each.
FifteenPen
force-pushed
the
pr/render-scale
branch
from
November 9, 2026 18:33
66fc501 to
0e9a1a3
Compare
2 of 3 tasks
|
A build confirmation on current I applied this PR's code files on top of On and the packed app's Not tested yet: I have not played either build, so I have no frame-time numbers for the slider on this GPU. I'll add them after a session. (Written with an AI coding assistant; the builds and logs are from my own machine.) |
2 of 3 tasks
Fasen24-AI
added a commit
to Fasen24-AI/swordboiMacNative
that referenced
this pull request
Nov 10, 2026
…nds once to half), seedds#1909 (fragment uniform reads bound to the binding length), seedds#1901 (dispatch_overlap on for Ocarina), seedds#1459 (MetalFX takes agl_ndsr_vr, no-curve variants linear), seedds#1903 (render scale stubs for Ocarina; replaces the seedds#1497 ceiling we carried) Hand-resolved: the mesh draw keeps the task isolation of seedds#1842 and the copy paths our nvn_tex_level_range / DM_SHARPEN; seedds#1497's stub, test and BINDING entry go; the build-keyed rule names the render scale function (main+0x31d3200). Chain e906c7467690. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014eD437mxrMnW2UwLZhpwc7 Upstream pull requests applied in this commit (their authors' work, brought onto this tree with a three-way merge; the description is in each PR): - seedds#1459 by PromethOps (open): DM_UPSCALER=metalfx takes agl's agl_ndsr_vr.pck networks too, and a variant with no curve and no power is drawn as one colour space: Ocarina of Time's upscaler is MetalFX's - seedds#1497 by givethesourceplox (open): Add a render-scale ceiling for Ocarina v131072 - seedds#1842 by ycarogabriel-lgtm (open): Ocarina of Time: opt-in task isolation (DM_NVN_ISOLATE_TASK), the Hi-Z task a5288 in command buffers of its own, a workaround for its GPU hangs on an M1 - seedds#1897 by Know-It-All-Brother (closed): HMMA with an f16 accumulator rounds once per 8 products, as Ampere does (chain change) - seedds#1901 by FifteenPen (open): The game's compute dispatches with no game barrier between them run side by side (profile key dispatch_overlap, on for Ocarina of Time): Kokiri Forest GPU p50 15.63 → 14.76 ms - seedds#1902 by fxd0h (open): HFMA2 rounds once to half, as Ampere does (chain change) - seedds#1903 by FifteenPen (open): Ocarina of Time takes the launcher's Render scale: the 3D views at that fraction of the game's own size, the dynamic resolution held at its top level (Kokiri Forest docked at 0.75: GPU p50 15.77 → 14.31 ms, 60 fps held) - seedds#1909 by oz-rinkliff (open): Bound translated fragment uniform reads to the NVN binding length
Fasen24-AI
added a commit
to Fasen24-AI/swordboiMacNative
that referenced
this pull request
Nov 10, 2026
…a 23 was built from Ours kept where main has not taken the change: the pool test of image_texture (virtual pools), need_make with seedds#2075's stand-in, the copy absorb beside main's gsb_mark, DM_SHARPEN's copy_t2t_draw_x, the render scale (seedds#1903) and fixed resolution stubs beside seedds#2020's native output and seedds#2021's render size. Main's own taken for the depth rule (fb_depth_rule), the family textures and the movie network: the opt-in shortcut of PR seedds#1331 (DM_NVN_NDVE_MOVIE_DIRECT) is removed, main runs the network as host kernels. Generated files (chain header, lock, translator binaries, symptoms, game-patches) are main's here and rebuilt in the next commit. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014eD437mxrMnW2UwLZhpwc7 Upstream pull requests applied in this commit (their authors' work, brought onto this tree with a three-way merge; the description is in each PR): - seedds#1331 by givethesourceplox (closed): Scale decoded NDVE movies on Metal and skip matched reconstruction - seedds#1903 by FifteenPen (open): Ocarina of Time takes the launcher's Render scale: the 3D views at that fraction of the game's own size, the dynamic resolution held at its top level (Kokiri Forest docked at 0.75: GPU p50 15.77 → 14.31 ms, 60 fps held) - seedds#2020 by padsiwono (open): Ocarina of Time v131072: Output Native draws the full output size instead of the game's 80 % frame (`DM_OUTPUT`) - seedds#2021 by padsiwono (open): Ocarina of Time v131072 renders at the launcher's Resolution (`DM_RENDER_SIZE`), docked - seedds#2075 by sleepyeyedjoe (closed): Ocarina of Time: a patch of scenery no longer draws dark for one frame when the game gives it a sharper texture (a pool texture the walk does not make holds a stand-in of its own colours until its first read)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
The launcher's Render scale (
DM_RENDER_SCALE, 0.5 to 1.0) fixes a game's 3D views at a fraction of their size, for builds whose rewriter stubs read it. Breath of the Wild and Tears of the Kingdom have such stubs; The Legend of Zelda: Ocarina of Time (0400486024DEC000, v131072) had none, so the setting did not appear for it.The 3D views' sizes come from the scale the engine stores in its view-size update (v131072 main+0x31d3200;
str s0,[x20,#0xe5c]at +0xd48). That store, and the size loop after it, run only in a frame where the dynamic-resolution update answers status 0, a new scale. At a steady frame rate it never does, so a stub at the store alone changes nothing.This change adds two stubs in that function, placed by its fingerprint through the frame-step rule's
others:The existing dynamic-resolution level stub returns the top level under such a scale, so the size is fixed. 1.0, the loader's default, runs the game's own code. The rewriter declares
RENDER_SCALEfor the build, so the launcher offers the setting.No tool change is needed any more: main's dry run (
docs_patches.py) now starts its stub area at 0x6000000, within aB's reach of a rule's other functions, so this branch, rebased onto 04811a6, takes main's file as it is and only regeneratesdocs/agents/game-patches.md.Docs: the game note's "Dynamic resolution" section (Current: Render scale, with the numbers below), the new
BINDINGentry inpatches.py, and the loader's comment that lists the render-scale stubs.Checked
python3 -m unittest dm/tools/tests/test_patches.py dm/tools/tests/test_nso_match.py: 48 tests OK, among them the function-matched frame-step checks (sites inside their functions, nothing written without them).python3 dm/tools/docs_patches.py --check,dm/tools/tests/test_docs.py,python3 dm/tools/docs_symptoms.py --check.dm/tools/lint_python.py(ruff 0.17.2, pyright 1.1.414): 0 new findings.make -C dm/host GAME=0400486024DEC000builds.patches.py): the matcher finds the view-size update at 0x31d3200, all three sites are written (0x8065e0, 0x31d3ee4, 0x31d3f48), and the fixups carryRENDER_SCALE.s0is computed from the update's answer (fmov s0,w0at +0xd34), never reread from +0xe5c, so the factor does not compound.0400486024DEC000, v131072).Setup: a
--platform macbuild of main d8b2b64, with its host and shader library and the module rewritten by this change.scripts/bench.py, routekokiri-deck, docked, two runs each, the pipeline archive warm (0 bases built in every run). The main pass's size comes from a pass dump in each run.At the game's own size the GPU's p95 sits just over a vsync on this Mac, so the frame step holds 2 vsyncs for stretches of the route; at 0.75 it holds 60 fps.
The screenshots after the window are clean at each scale, through the game's own upscaler.
The main pass sizes include the engine's own normalization and rounding (×[x20+0xe58] / [x20+0xe50]), hence 1171x659 rather than exactly 1152x648.
regress.py impact: Breath of the Wild, Pokémon Scarlet, Tears of the Kingdom and Hades, throughloader.c. That change is a comment only. Nothing in another game's rewritten modules or host behaviour changes, soregress.py checkwas not run on other games.DM_DYNAMIC_RESOLUTION=1together with a render scale below 1.0 (the scale wins: the level stub returns the top level); the handheld output.Docs
docs/reference/<subsystem>.mdentry, andpython3 dm/tools/docs_symptoms.pywas run (the symptom index)