Skip to content

Ocarina of Time draws its 3D above its Switch 2 resolution: Render scale 1.333 gives native 2560x1440 docked, where the console draws 1920x1080 and upscales - #2532

Open
Know-It-All-Brother wants to merge 1 commit into
seedds:mainfrom
Know-It-All-Brother:oot-render-scale

Conversation

@Know-It-All-Brother

@Know-It-All-Brother Know-It-All-Brother commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

What and why

This lets Ocarina draw its 3D at a higher resolution than it does on a Switch 2. Docked, the game never draws its 3D views above 1920x1080: that's level 0, the top of its dynamic resolution, at 0.75 of its 2560x1440 output, and its upscaler fills the rest. With the launcher's Render scale at 1.333 they're drawn at the full 2560x1440, so the picture is native 1440p with nothing upscaled.

On main the Render scale setting doesn't reach this game at all, because the dynamic-resolution stub never reads DM_RENDER_SCALE and the profile doesn't declare RENDER_SCALE.

With this change, when Dynamic resolution is off, the stub's level 0 also writes level 0's scale as the game's own scale times the render scale, capped at 1.0 of the output. Setting 1.333 draws the 3D views at the native 2560x1440. 1.0, the default, writes the game's own scale back, so nothing changes unless you raise the setting. The stub declares RENDER_SCALE 2, so the launcher offers the slider. Above 1.333 the views stay at the output's size.

The game only reads the scale when it sets its view sizes, at start and on a level change. So the setting takes effect at start, which is how the launcher sets it. Writing it into a running game through DM_CTL does nothing until the level changes. #1903 found the same thing for the view-size store.

Checked

On an M5 Max (40-core GPU, 64 GB), docked, in a window, on main at c9d57d2 plus this change:

  • Pass dumps in play show the main passes at 1920x1080 with 1.0 and at 2560x1440 with 1.333.
  • bench.py on kokiri-deck from the deck save, three alternating runs of each setting, medians:
Render scale 3D views fps GPU p50 GPU p95
1.0 (as main) 1920x1080 56.2 13.46 ms 14.41 ms
1.333 2560x1440 57.5 13.34 ms 14.13 ms

On this Mac the larger views cost no measurable GPU time, which matches the game note: the frame's cost on Apple GPUs hardly depends on resolution.

  • Checks that pass: docs_patches.py --check, test_docs, test_patches, test_settings and test_launcher_settings.

Not measured: a slower Mac, handheld, or the iPhone.

Screenshots

The same spot on the Kokiri Forest deck, render scale 1.0 on the left and 1.333 on the right (crops shown at 2x):
closeup_link
closeup_mushrooms
closeup_village
scale_1 0
scale_1 333

What about 3840x2160

We tried it, and it isn't in this PR. The game's output-size list does have a 3840x2160 entry, and raising the start size does make the frame buffer 3840x2160. But the window textures stay at 2560x1440, the 3D views came out at 1707x960, and the host flagged every present's crop as outside the window texture. The game's upscaler library (roulibr) only has variants up to 2560x1440 output. A 4K output would mean replacing or skipping that pass, not just changing a size. The game note's new Render scale section records the addresses.

Docs

  • The finding is in its game note (the new Render scale section), and python3 dm/tools/docs_symptoms.py was run (the symptom index, unchanged)
  • No game files, keys or data extracted from a game in the change or the attachments

Related

Both only lower the size. This PR raises level 0 up to the output's size and leaves the lower range to those PRs. If #1903 lands first, its stubs and this one would need one combined RENDER_SCALE.

…own size: 1.333 draws the 3D views at 2560x1440 instead of 1920x1080 docked

With Dynamic resolution off, the dynamic-resolution stub's level 0 now also writes level 0's scale (the first entry of the game's level list) as the game's own scale times DM_RENDER_SCALE (state +0x10), at most 1.0 of the output. The game's own scale is kept in the state page (+0x2a0) on the first call, so 1.0, the default, writes it back and nothing changes. The stub declares RENDER_SCALE 2, so the launcher offers the setting; above 1.333 the 3D views stay at the output's size.

The game reads the scale when it sets its views' sizes, at start and when the level changes, so the setting takes effect at start, as the launcher sets it.

Checked on an M5 Max (40-core GPU), docked, a window, kokiri-deck from the deck save: pass dumps in play show the main passes at 1920x1080 with 1.0 and 2560x1440 with 1.333; three alternating runs of each gave 56.2 fps / GPU p50 13.46 ms with 1.0 and 57.5 fps / 13.34 ms with 1.333. docs_patches.py --check, test_docs, test_patches, test_settings and test_launcher_settings pass.

The game note's new Render scale section also records why 3840x2160 is not done: the frame buffer can be raised to it, but the game's upscaler library has no variant above 2560x1440 and the window's textures stay that size.
@github-actions github-actions Bot added rewriter The NSO rewriter and per-build patches docs Documentation game: 0400486024DEC000 A game labels Nov 12, 2026
@Know-It-All-Brother Know-It-All-Brother changed the title Ocarina of Time takes the launcher's Render scale up to its output's own size: 1.333 draws the 3D views at 2560x1440 instead of 1920x1080 docked Ocarina of Time draws its 3D above its Switch 2 resolution: Render scale 1.333 gives native 2560x1440 docked, where the console draws 1920x1080 and upscales Nov 12, 2026
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 rewriter The NSO rewriter and per-build patches

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant