Repository navigation
Conversation
…held a second vsync With fps_target 60 the pacer raises the hold above the cap's vsyncs after three late frames in a row, so a game that can almost keep 60 fps is held at 30. On a MacBook Air M4 (10-core GPU, 16 GB) at 1920x1080 docked, in the Hyrule Field view, DM_FPS_HOLD at its default against off: 30.1 -> 33.7 fps (frame p50 33.31 -> 29.38 ms); on the Kokiri bridge, about 52 fps against a steady 30. fps_hold is already off for two other profiles; the launcher's Hold frames when late turns it back on. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
813f4c2 to
a4d50d8
Compare
|
Independent data point for this PR on an M4 Pro (20-core GPU, 24 GB, macOS 27.0.1, AC power), main 04811a6, chain 39eb2f781d07, docked, Kokiri Forest route from a fixed save with scripted inputs, 190 s per run, frame stats from 60–120 s. With the default hold (
The log of run 9 shows the pattern: In an earlier series with the default hold, the two main runs did recover to 60 fps, but spent 62 and 213 frames at hold 2 during the walk, and one of them left the scripted route (the hold changes the game's time step, so frame-indexed inputs cover a different distance). With |
What and why
Ocarina of Time (0400486024DEC000, v131072) is profiled with
fps_hold off. Withfps_target 60the pacer raises the hold above the cap's vsyncs after three late frames in a row, so a game that can almost keep 60 fps is held at 30. With the hold off a late frame is shown late; the game still steps by the vsyncs that passed, so its speed stays right. The launcher's Hold frames when late turns it back on. Two other profiles already have the key off.Profile key only; no host code, no chain change.
Checked
python3 -m unittest test_docs test_game_profile test_launcher_settings test_fps_target(dm/tools/tests, 41 tests OK).DM_FPS_HOLD=off, the same host and shaders: 30.1 -> 33.7 fps (frame p50 33.31 -> 29.38 ms, GPU p50 27.56 -> 27.28 ms): the GPU time does not move, the hold was quantizing the frames. On the Kokiri bridge, about 52 fps against a steady 30. Measured on a tree of 2026-11-08 (main7f502220plus The graphics scale is tier 0 in both modes: Star Fox's docked 3D was 768x432, smaller than handheld #1304); this branch is rebased on7a7acfeeand 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
fps_holdis documented indm/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 #1927.🤖 Generated with Claude Code