feat(host): a widescreen picture up to 5120x2160's pixels, native for 21:9 at the 4K output #2120

Merged
pmwork-personal merged 2 commits from feat/wide-past-4k into main 2026-11-11 20:37:39 +00:00
pmwork-personal commented 2026-11-11 03:45:39 +00:00 (Migrated from github.com)

On a 5120x2160 (21:9) monitor, the 3840x2160 output with Ultrawide on made a 4416x1864 picture, which the window copy then stretched to the screen: the monitor never got a native frame, and the Output resolution row showed 4416x1864. The cap behind it, 3840x2160's pixels, came from issue 1031, where a 32:9 screen's 7680x2160 picture ran its render targets' pool out. A 21:9 screen's native picture needs a third more pixels than 4K, not twice as many, and the pool already grows with the picture.

What changed

  • host/hos_wide_size.h: a picture wider or narrower than 16:9 takes at most 5120x2160's pixels (was 3840x2160's). At the 4K output a 21:9 screen gets its native 5120x2160, and the Output resolution row says "5120x2160 (native)". A 32:9 screen at the 4K output is still capped, now at 6256x1760 (was 5400x1520), its shape kept.
  • No pool change: host/nn_applet.c already scales the render-target pool with the picture's pixels, to 915 MB at 5120x2160 (test_rt_pool_minimum.py now checks that case).
  • HOS_WIDE_MAX_PX=<pixels> sets another cap without a rebuild (8294400 is the old 3840x2160's), in case a GPU needs the smaller picture. Listed in docs/development.md; the readme gives the new cap.

Relation to #2052
Merged with current main; #2052's code is kept as merged (the output limits, hos_wide_clamp up to 48:9, the 24-row alignment at 48:9). With the new cap:

  • The 7680x1440 output renders at full size, since it has exactly 5120x2160's pixels, instead of 6528x1224. Its pool stays 900 MB, set by the output's own size as before; the 5120x2880 output already plays in that pool with more pixels.
  • 48:9 at the 4K output is kept to 7680x1440, exactly 48:9, with a 915 MB pool: the same pixels and pool as 21:9's 5120x2160.
  • test_widescreen_shapes.py keeps #2052's 6528x1224 cases (the 24-row alignment and the four-decimal 5.3333) under HOS_WIDE_MAX_PX=8294400, the old cap, and adds the full-size 7680x1440 and 48:9 at 2160. test_output_resolution.py's 7680x1440 output is full size; test_rt_pool_minimum.py adds 48:9 at the 4K output.

Tested

  • In game on Windows 11, RTX 5090 (driver 621.14), 5120x2160 (21:9) monitor, 4K output, picture at the monitor's shape: picture 5120x2160, pool 915 MB, DLAA at 5120x2160. Kokiri Forest and Castle Town, where issue 1031's pool ran out, load. About 57 fps at native DLAA (GPU about 12 ms a frame). That run was before the merge with #2052.
  • tests/run_all.py on Windows (llvm-mingw) after the merge: 339 passed, 30 skipped, 4 failed. The 4 also fail on untouched main on this PC: test_recorder_sync (its exit case), test_precompile_compute_guard, test_bake_portability, and nx2/test_nup_read_name (no zstandard here). test_widescreen_shapes.py, test_output_resolution.py, test_rt_pool_minimum.py and gpu/vk/tests/present_rect_test.cpp pass.

Not tested

  • 48:9 and 32:9 in game at the new sizes (the full-size 7680x1440 output, 48:9 and 32:9 at the 4K output).
  • GPUs with less memory than the 5090 at these sizes, and Linux.

This and the Aspect ratio PR (#2119) edit the same readme paragraph, so whichever merges second needs a one-line merge.

🤖 Generated with Claude Code

On a 5120x2160 (21:9) monitor, the 3840x2160 output with Ultrawide on made a 4416x1864 picture, which the window copy then stretched to the screen: the monitor never got a native frame, and the Output resolution row showed 4416x1864. The cap behind it, 3840x2160's pixels, came from issue 1031, where a 32:9 screen's 7680x2160 picture ran its render targets' pool out. A 21:9 screen's native picture needs a third more pixels than 4K, not twice as many, and the pool already grows with the picture. **What changed** - `host/hos_wide_size.h`: a picture wider or narrower than 16:9 takes at most 5120x2160's pixels (was 3840x2160's). At the 4K output a 21:9 screen gets its native 5120x2160, and the Output resolution row says "5120x2160 (native)". A 32:9 screen at the 4K output is still capped, now at 6256x1760 (was 5400x1520), its shape kept. - No pool change: `host/nn_applet.c` already scales the render-target pool with the picture's pixels, to 915 MB at 5120x2160 (`test_rt_pool_minimum.py` now checks that case). - `HOS_WIDE_MAX_PX=<pixels>` sets another cap without a rebuild (8294400 is the old 3840x2160's), in case a GPU needs the smaller picture. Listed in `docs/development.md`; the readme gives the new cap. **Relation to #2052** Merged with current main; #2052's code is kept as merged (the output limits, `hos_wide_clamp` up to 48:9, the 24-row alignment at 48:9). With the new cap: - The 7680x1440 output renders at full size, since it has exactly 5120x2160's pixels, instead of 6528x1224. Its pool stays 900 MB, set by the output's own size as before; the 5120x2880 output already plays in that pool with more pixels. - 48:9 at the 4K output is kept to 7680x1440, exactly 48:9, with a 915 MB pool: the same pixels and pool as 21:9's 5120x2160. - `test_widescreen_shapes.py` keeps #2052's 6528x1224 cases (the 24-row alignment and the four-decimal `5.3333`) under `HOS_WIDE_MAX_PX=8294400`, the old cap, and adds the full-size 7680x1440 and 48:9 at 2160. `test_output_resolution.py`'s 7680x1440 output is full size; `test_rt_pool_minimum.py` adds 48:9 at the 4K output. **Tested** - In game on Windows 11, RTX 5090 (driver 621.14), 5120x2160 (21:9) monitor, 4K output, picture at the monitor's shape: picture 5120x2160, pool 915 MB, DLAA at 5120x2160. Kokiri Forest and Castle Town, where issue 1031's pool ran out, load. About 57 fps at native DLAA (GPU about 12 ms a frame). That run was before the merge with #2052. - `tests/run_all.py` on Windows (llvm-mingw) after the merge: 339 passed, 30 skipped, 4 failed. The 4 also fail on untouched main on this PC: `test_recorder_sync` (its exit case), `test_precompile_compute_guard`, `test_bake_portability`, and `nx2/test_nup_read_name` (no zstandard here). `test_widescreen_shapes.py`, `test_output_resolution.py`, `test_rt_pool_minimum.py` and `gpu/vk/tests/present_rect_test.cpp` pass. **Not tested** - 48:9 and 32:9 in game at the new sizes (the full-size 7680x1440 output, 48:9 and 32:9 at the 4K output). - GPUs with less memory than the 5090 at these sizes, and Linux. This and the Aspect ratio PR (#2119) edit the same readme paragraph, so whichever merges second needs a one-line merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Joey-Magnus (Migrated from github.com) approved these changes 2026-11-11 20:06:40 +00:00
Joey-Magnus (Migrated from github.com) left a comment

This looks right to me. I checked the render-target pool for each new size against hos_rt_pool_size (host/nn_applet.c:180):

  • 21:9 at the 4K output (5120x2160) gets 305 × 11.06 / 3.69 ≈ 915 MB. The output itself isn't above 4K's pixels, so the 900 MB cap doesn't apply.
  • 32:9 at the 4K output (6256x1760) gets about 911 MB, scaled with the picture as #1031 needed.
  • The 7680x1440 output now renders a full 7680x1440 picture. That output is above 4K's pixels, so the pool stays capped at 900 MB, and as you say, the 5120x2880 output already plays in 900 MB with more pixels (14.7M against 11.06M).

The test changes move expectations to the new sizes and keep #2052's 24-row and 5.3333 cases under HOS_WIDE_MAX_PX=8294400 instead of dropping them, which is what I'd want. Stripping HOS_WIDE_MAX_PX from the fixture's environment keeps a developer's own setting from leaking in. The new switch is documented in docs/development.md, the readme sentence is updated, and the host and menu agree because both call the same hos_wide_max_px() (the menu already reads HOS_OUTPUT_RES the same way). It merges cleanly with current main, and CI is green.

A few small things, none blocking:

  • minor host/hos_wide_size.h:35-39: HOS_WIDE_MAX_PX has a floor but no ceiling. The documented use is lowering the cap, but a value above the default at the 4K output brings back exactly #1031. 7680x2160 asks for a 1373 MB pool, and the description of #1031 says a pool that size failed the game's reservation at boot. Clamping it (v > 5120.0 * 2160.0 ? 5120.0 * 2160.0 : v), or saying in the development.md row that it's for lowering only, would stop someone "raising" it into a crash.
  • question: The default now gives 21:9 players at the 4K output 34% more pixels than before (5120x2160 against 4416x1864), and in-game testing so far is on a 5090. On an 8 GB card at that output, is there a VRAM risk worth a line in the readme pointing at HOS_WIDE_MAX_PX=8294400? As it stands, the only way back is an undocumented-for-players environment variable. Not a blocker; just asking whether you looked at memory use on a smaller card.
  • minor: As you note, this and #2119 touch the same readme paragraph. Whichever lands second needs the one-line merge.
This looks right to me. I checked the render-target pool for each new size against `hos_rt_pool_size` (`host/nn_applet.c:180`): - 21:9 at the 4K output (5120x2160) gets 305 × 11.06 / 3.69 ≈ 915 MB. The output itself isn't above 4K's pixels, so the 900 MB cap doesn't apply. - 32:9 at the 4K output (6256x1760) gets about 911 MB, scaled with the picture as #1031 needed. - The 7680x1440 output now renders a full 7680x1440 picture. That output is above 4K's pixels, so the pool stays capped at 900 MB, and as you say, the 5120x2880 output already plays in 900 MB with more pixels (14.7M against 11.06M). The test changes move expectations to the new sizes and keep #2052's 24-row and `5.3333` cases under `HOS_WIDE_MAX_PX=8294400` instead of dropping them, which is what I'd want. Stripping `HOS_WIDE_MAX_PX` from the fixture's environment keeps a developer's own setting from leaking in. The new switch is documented in `docs/development.md`, the readme sentence is updated, and the host and menu agree because both call the same `hos_wide_max_px()` (the menu already reads `HOS_OUTPUT_RES` the same way). It merges cleanly with current main, and CI is green. A few small things, none blocking: - **minor** `host/hos_wide_size.h:35-39`: `HOS_WIDE_MAX_PX` has a floor but no ceiling. The documented use is lowering the cap, but a value above the default at the 4K output brings back exactly #1031. 7680x2160 asks for a 1373 MB pool, and the description of #1031 says a pool that size failed the game's reservation at boot. Clamping it (`v > 5120.0 * 2160.0 ? 5120.0 * 2160.0 : v`), or saying in the development.md row that it's for lowering only, would stop someone "raising" it into a crash. - **question**: The default now gives 21:9 players at the 4K output 34% more pixels than before (5120x2160 against 4416x1864), and in-game testing so far is on a 5090. On an 8 GB card at that output, is there a VRAM risk worth a line in the readme pointing at `HOS_WIDE_MAX_PX=8294400`? As it stands, the only way back is an undocumented-for-players environment variable. Not a blocker; just asking whether you looked at memory use on a smaller card. - **minor**: As you note, this and #2119 touch the same readme paragraph. Whichever lands second needs the one-line merge.
Commenting is not possible because the repository is archived.
No description provided.