Skip to content

Upload staging shrinks back when it sits idle on iOS: the three slots no longer keep 192 MB of private GPU memory through steady play - #1491

Open
aksmith-git wants to merge 1 commit into
seedds:mainfrom
aksmith-git:pr/upload-staging-idle
Open

aksmith-git wants to merge 1 commit into
seedds:mainfrom
aksmith-git:pr/upload-staging-idle

Conversation

@aksmith-git

Copy link
Copy Markdown
Contributor

What and why

Each of the three upload slots keeps a primary and an overflow staging block for reuse, sized by the slot's largest batch since the start. That is usually a scene load, so up to 192 MB of private GPU memory stays allocated for the rest of the run. Ocarina of Time's GPU out-of-memory report on an iPad Pro (M5, Metal's working set 8,192 MB) lists them as private buffers 8, 224 MB.

up_idle_release (nvn_mtl.m) runs at each submission's start on the submit thread, which owns the slots. Per slot:

  • no batch used the slot for DM_NVN_UPLOAD_IDLE_MS: both blocks go, and the next batch makes them again;
  • the overflow block went unused that long: the overflow goes;
  • every such window: a primary block larger than the window's largest batch needed goes (rounded up to a power of two, at least 4 MB). The slot's demand drops to that batch, so the next batch makes the smaller block.

A slot whose batch is still running is left alone, and defer_obj_release keeps a block until the GPU is done with it. The default is 2000 ms on iOS and 0 (never) on the Mac, so the Mac is unchanged. A line every 30 s says what the slots hold.

#1391's guard also lets go of the slots' staging, from 80% of the working set. This change is time-based instead and applies on iOS whatever the level. The two do not depend on each other.

Reference entry: docs/reference/memory.md, "Upload staging keeps its largest blocks for the whole run", with its line in the symptom index and Ocarina of Time's note; DM_NVN_UPLOAD_IDLE_MS in docs/env_switches.tsv.

Checked

  • Tests: check_t_upload_idle (new: three idle slots give their 32 MB blocks back at the next submission; slots that keep running small batches shrink their primary to 4 MB; every upload lands; Metal validation on), check_t_upload_slots (also with DM_NVN_UPLOAD_IDLE_MS=2000), check_t_upload_budget, test_docs.py, test_env_switches.py.
  • make -C dm/host GAME=0400486024DEC000 dmhost builds on main 0f510fd; dm/ios/tools/compile_check.py (261 files, 0 failed).
  • Games run: Ocarina of Time (0400486024DEC000 v131072), 5 minutes from a Kokiri Forest save in handheld mode on an M4 Pro Mac, on our stack (main 6121fd7 with other changes):
DM_NVN_UPLOAD_IDLE_MS slots hold at the 30-s lines in play releases staging blocks made GPU p50
0 192 MB at every line 0 19 21-23 ms
2000 0 MB at every line 36 (400 MB) 46 21-23 ms

Submit and present time in the last minute was 15-16 ms with 2000 against 10 ms with 0. A run with neither change also reached 13-15 ms there, so I can't tell a cost from the noise. Watch it on a device.

  • Not run on an iPad yet, where it is on by default.
  • regress.py not run: the Mac default is unchanged.

Docs

  • The finding is in docs/reference/memory.md, and python3 dm/tools/docs_symptoms.py was run
  • No game files, keys or data extracted from a game in the change

… no longer keep 192 MB of private GPU memory through steady play

Each upload slot kept its primary and overflow staging blocks for reuse, sized
by its largest batch since the start (a scene load), so up to 192 MB stayed
allocated for the rest of the run; the iPad's GPU out-of-memory report for
Ocarina of Time listed them as private buffers, 224 MB. up_idle_release, at
each submission's start: a slot no batch used for DM_NVN_UPLOAD_IDLE_MS gives
both blocks back, an overflow block unused that long goes, and a primary block
larger than the window's largest batch goes, so the next batch makes the
smaller one. Default 2000 ms on iOS, 0 (never) on the Mac. A line every 30 s
says what the slots hold.

Ocarina of Time on an M4 Pro Mac, 5 minutes: 192 MB held at every 30-s line
with 0, 0 MB in play with 2000 (36 releases, 46 blocks made against 19), GPU
time the same. t_upload_idle checks both cases; t_upload_slots and
t_upload_budget pass.
@github-actions github-actions Bot added nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests) docs Documentation game: 0400486024DEC000 A game labels Nov 6, 2026
john62036203-ops added a commit to john62036203-ops/NXNativeWindows that referenced this pull request Nov 6, 2026
ivan-leschinsky pushed a commit to ivan-leschinsky/nxnative that referenced this pull request Nov 9, 2026
… no longer keep 192 MB of private GPU memory through steady play

Ported from seedds#1491 (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
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 nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant