Repository navigation
Conversation
This was referenced Nov 9, 2026
… own The Mac replays a game's graphics queue and encodes it to Metal on the submit thread, which waits for each pass's encoding; iOS encodes on a thread of its own for every game. With enc_thread on, Ocarina of Time's GPU starves less at segment boundaries: on a MacBook Air M4 (10-core GPU, 16 GB) at 1920x1080 docked, the Hyrule Field view, A/B phases in one process (DM_NVN_ENC_THREAD=0 / 1): frame p50 24.48 -> 23.46 ms (40.2 -> 41.6 fps), GPU span 22.09 -> 21.39 ms. t_feedback tests the segment timestamp heap, which exists only without the encode thread (ts_on(): seg_ts() && !rec_on()), and rec_on() defaults to the profile's enc_thread; under GAME=0400486024DEC000 three of its checks failed (segment mode has a timestamp heap; a boundary, no commit; its timestamp slot). check_t_feedback now sets the mode it tests, as t_present_crop and t_perf_order set theirs. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
FeReuss
force-pushed
the
pr/oot-enc-thread
branch
from
November 9, 2026 16:44
c890f78 to
858fe11
Compare
Fasen24-AI
added a commit
to Fasen24-AI/swordboiMacNative
that referenced
this pull request
Nov 10, 2026
…ctions compiled out, DMSH_BORDER_FC), seedds#1930 (native float atomic add), seedds#1920 (GPU-written sliver does not own a texture: terrain tiles), seedds#1917 (depth attachment sampled by a depth-writing draw reads a copy), seedds#1928 (enc_thread on), seedds#1942 (idle-GPU late frames do not step the hold up), seedds#1940 (prewarm lines after the first frame), seedds#1936 (resolution families uncompressed) Hand-resolved: image_texture keeps the virtual pools we admit; fb_prepare keeps our pass split and local dread flag after the depth snapshot; the compute key keeps the NDVE direct draw before the border constant. 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#1774 by uncraftablexd (closed): Compute threads that exit before a barrier keep arriving at it, and every shader loop has a cap (GPU hang defences), chain change - seedds#1917 by FifteenPen (closed): A draw that writes depth and samples its own depth attachment reads a copy of it: Ocarina of Time's light-blue dashes over the rock at Death Mountain Trail's cave entrance are gone - seedds#1920 by nawangwe (closed): A GPU-written span's sliver inside a texture does not make it the GPU's: Ocarina of Time's terrain tiles no longer vanish or show another tile's surface (seedds#1566) - seedds#1928 by FeReuss (open): Ocarina of Time: enc_thread on, the replay encodes on a thread of its own - seedds#1929 by FeReuss (open): Unused border corrections are compiled out of pipelines that bind no sampler with a twin (function constant DMSH_BORDER_FC) - seedds#1930 by FeReuss (open): A float add to storage memory with no result read is one native atomic add instead of a compare-and-swap loop - seedds#1936 by TheGoldfish11 (closed): Write resolution-family image textures uncompressed - seedds#1940 by uncraftablexd (open): A prewarm list's lines after its #@after_first_frame line are built after the first frame, in the background, instead of in the prepare step (issue seedds#1747) - seedds#1942 by uncraftablexd (open): Frame step: late frames with the GPU idle do not step up, and a longer hold the GPU does not explain is probed
Fasen24-AI
added a commit
to Fasen24-AI/swordboiMacNative
that referenced
this pull request
Nov 10, 2026
seedds#1901 seedds#1459 seedds#1928 seedds#1942 seedds#1940 seedds#1952 seedds#1611 seedds#2065 seedds#2083 seedds#2008 seedds#2079 seedds#2022 seedds#2075 seedds#2077 seedds#2020 seedds#2021 onto main 04811a6 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#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#1611 by Esteban-V (open): An argument block whose only change is a uniform buffer is patched instead of encoded again - seedds#1774 by uncraftablexd (closed): Compute threads that exit before a barrier keep arriving at it, and every shader loop has a cap (GPU hang defences), chain change - seedds#1824 by cocoman93 (open): Clamp texel fetches past a sampled 2D texture's edge: no hard edge in Ocarina of Time's mist - 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#1928 by FeReuss (open): Ocarina of Time: enc_thread on, the replay encodes on a thread of its own - seedds#1929 by FeReuss (open): Unused border corrections are compiled out of pipelines that bind no sampler with a twin (function constant DMSH_BORDER_FC) - seedds#1930 by FeReuss (open): A float add to storage memory with no result read is one native atomic add instead of a compare-and-swap loop - seedds#1940 by uncraftablexd (open): A prewarm list's lines after its #@after_first_frame line are built after the first frame, in the background, instead of in the prepare step (issue seedds#1747) - seedds#1942 by uncraftablexd (open): Frame step: late frames with the GPU idle do not step up, and a longer hold the GPU does not explain is probed - seedds#1952 by AdyaGMD (open): Compute moves ahead of scene passes past occlusion queries and conditional rendering; clears wait across dispatches - seedds#2008 by bquilty25 (open): nvn: reactive memory watchdog, 16-way view cache, and texture upload batching - 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#2022 by sleepyeyedjoe (closed): Ocarina of Time: large models no longer go black for one frame twice, 4–5 frames apart, when the game streams new textures into them (a texture ID a shader has read keeps its read mark when it gets another texture) - seedds#2030 by humanperzeus (open): A NaN colour at alpha 0 is returned as 0, as NVIDIA's blender takes a zero factor: Ocarina of Time's white clouds over the ferns are gone - seedds#2035 by Know-It-All-Brother (open): The shader build runs as worker processes, and no shader waits for a batch (Ocarina of Time's cold Mac map: 3,002 s to 1,298 s) - seedds#2065 by Raymon82777 (closed): A vertex library with layer entry points of its own gets bases for its main0 pairs: Ocarina of Time's 230 ms camera-turn hitch in Hyrule Field goes to 39 ms - 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) - seedds#2077 by roandegraaf (closed): Ocarina of Time: fix the "plaid" terrain / missing texture tiles (GPU-drawn textures now reach the storage the game copies) - seedds#2079 by uncraftablexd (open): Render pipelines that share a vertex function are taken from the archive or compiled one at a time: the AGX driver crashes in createVertexProgramVariant's completion block - seedds#2083 by FifteenPen (closed): Ocarina of Time's prewarm list gets 41 more task / mesh pipelines from later play
1 task done
Contributor
|
#2260 adds the same One update: the |
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
Ocarina of Time (0400486024DEC000, v131072) is profiled with
enc_thread on: the Mac replays the game's graphics queue and encodes it to Metal on a thread of its own, as iOS does for every game, instead of the submit thread stalling on each pass's encoding. With it the GPU of a MacBook Air M4 starves less at segment boundaries.The one test it breaks is fixed in the same PR:
t_feedbackexercises the segment timestamp heap, which exists only without the encode thread (ts_on():seg_ts() && !rec_on()), andrec_on()defaults to the profile'senc_thread. UnderGAME=0400486024DEC000, three of its checks failed (segment mode has a timestamp heap,with work running: a boundary, no commit,and its timestamp slot).check_t_feedbacknow setsDM_NVN_ENC_THREAD=0, the mode it tests, ast_present_cropandt_perf_orderset theirs.Profile key only; no host code, no chain change. The game note's Frame rate section has the measurement.
Checked
python3 -m unittest test_docs test_game_profile test_launcher_settings test_architecture(dm/tools/tests, 39 tests OK);make -C dm/gfx/tests GAME=0400486024DEC000 check_t_feedback: 203 checks, 0 failed (3 failed without the Makefile line, on this profile). The wholemake -C dm/gfx/tests GAME=0400486024DEC000 runon the tree with every PR of the series, which has this profile: 150 suites, 72,812 checks, 0 failed; 525 read-back cases, 0 failed.still_shotsroute, the heaviest), 120 s runs, window, docked, 1920x1080, 60 fps cap,enc_threadoff against on, the same host and shaders, one run each (not an in-process A/B: the switch is read once): frame p50 24.48 -> 23.46 ms (40.2 -> 41.6 fps), GPU p50 22.09 -> 21.39 ms. Measured on a tree of 2026-11-08 (main7f502220plus the series); this branch is rebased on7a7acfeeand built and unit-tested, not re-measured in the game.scripts/regress.py check: not run; a profile key of one game, and only Ocarina of Time is built on this Mac.Front ends
None.
Docs
docs/referenceneeds none: the key is documented (dm/games/README.md).Series: what these PRs add up to
This PR is one of a set from one effort to make Ocarina of Time (0400486024DEC000 v131072) hold its frame rate on a MacBook Air M4. The set, and how its parts combine into the last measured result:
The result (the Hyrule Field view, the heaviest of the game: 1920x1080 docked, 60 fps cap, window, 120 s runs, M4 with 10 GPU cores, 16 GB, macOS 27.2):
7f502220+ #1304,fps_holdat its defaultfps_hold off(#1927)cut_draws 128below, and the PRs listed as "also in the tree"enc_thread on(#1928)(The step from 33.7 to 40.2 changes the shader chain, so it has no in-process A/B; #1833 is most of it. Kokiri Forest, walking, is at 60 fps on build 4; the Hyrule view is the worst case.)
Each part switched in one process on build 4 (
DM_AB, 210 s, 600-frame phases, frame p50 with the part active against without; the noise between phases is about 0.3 ms): border-FC (#1929) 22.61 vs 23.98 ms; the barrier set (FRAG_ORDER,PASS_OVERLAPandHEAP_RELAXalternating together) 22.41 vs 22.58 ms;CUT_IDLE22.74 vs 22.85 ms;DISPATCH_CHAIN22.32 vs 22.48 ms.Which PRs make that tree:
fps_hold offenc_thread onshader_raw_direct(without it every raw store is dropped on an M4 and the foliage is not drawn: the 48-50 fps of a build without it are false)FeReuss:pr1833-m4-window, one commit on #1833's head (not yet offered on #1833 itself)gpu_ts_hz), #1833 (shader_raw_direct), #1720, #1377, #1840-fwrapv, nowe4e5ff64), #1368 / #1708 (native mesh prewarm and mesh without task: main's own versions), #1707 (withdrawn)FRAG_ORDER+PASS_OVERLAP+HEAP_RELAX),CUT_IDLEpr/pass-overlapandpr/cut-idleinFeReuss/nxnative-ootcut_draws 128(64 and 128 tie on this tree)All of it was measured on main
7f502220plus the above; these PRs are rebased on main8d5d4f1b; the tool and docs tests that touch them were run again there (test_env_switches,test_docs,test_nsp_chain, and each PR's own), while the host build and the graphics suite are those of7a7acfee, and none of it has been run in the game on the newer main (a shader rebuild of the new chain takes about an hour and 10 GB of disk). This PR is #1928.🤖 Generated with Claude Code