Repository navigation
Insert menu: Frame rate limit (30, 40, 45, 50 fps) - #895
Closed
HenriqueSBueno wants to merge 1 commit into
Closed
HenriqueSBueno wants to merge 1 commit into
HenriqueSBueno wants to merge 1 commit into
Conversation
A PC whose replay makes 35-45 fps swung between those rates, and frame generation passed the swing on to the screen. The new Graphics row (and HOS_FPS_LIMIT=<fps>, 15-59, over it) paces the game's frames to at most that rate in host/nn_vi.c: the present period becomes 1/limit, and the acquire waits one period after the last present instead of letting the display queue run two limited frames ahead. Game time keeps following the clock (realtime_step). Off by default: the pacing is unchanged then. tests/test_fps_limit.py compiles fps_limit() and frame_period() out of nn_vi.c and checks the menu row, labels, table and option 18.
Contributor
Author
|
Follow-up on the same PC, fullscreen at 3840x2160 / 60 Hz, Frame generation 2x + Frame pacing, Output resolution 3840x2160 with Resolution 67% (#849 on top), interleaved runs:
In fullscreen the presents already hold the shown rate at 60 (#755), and there the limit makes the shown intervals less even, not more. The windowed gain above still holds, but this is not the improvement I described for fullscreen, so I'm moving this to draft until the pacer and the limit agree (the display thread's interval estimate divided by the multiplier, against a game held at exactly 33.3 ms). |
HenriqueSBueno
marked this pull request as draft
November 9, 2026 02:06
Owner
|
Closing to keep the queue clear — please rebase on current main and reopen; thanks! |
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.
Problem
On a CPU where the replay is the limit, the game's own rate swings with the view. On an i5-10400F + RTX 3080 (driver 591.x, Windows 11, v2.0.5), standing at the same spot in Kokiri Forest, the native rate goes between ~31 and ~46 fps as the camera turns (1800 to 2900 draws a frame; the replay thread's submit is 13-25 ms, the GPU 10-15 ms). Frame generation passes that swing on to the screen: the shown intervals spread over the 7-25 ms buckets, and with fullscreen on a 60 Hz screen the game is held to 60 ÷ the multiplier anyway (#755), so a frame that misses 33 ms waits for the next vsync.
There is no way to ask for a steady lower rate:
HOS_FPS_TARGETonly raises the game's own limiter (MKW), andHOS_GAME_INTERVALfollows OoT's controller, which snaps to 33/50/67 ms.Change
A Frame rate limit row in the Insert menu's Graphics tab: Off (default), 30, 40, 45, 50 fps, saved as
frame_rate_limitinhookshot_options.ini.HOS_FPS_LIMIT=<fps>(15-59) wins over the menu.host/nn_vi.c:frame_period()is the longer of the display interval and 1/limit; the presents are paced by it. With a limit, the acquire waits one period after the last present instead of letting the display queue run two frames ahead (two limited frames of extra input delay otherwise).realtime_stepmeasures the real frame time), so Real time speed is unchanged.gpu/vk: the row, its labels,menu_fps_limit()and host option 18.fps_limit()is 0, the period and the acquire are exactly as before.With Frame generation 2x and Frame pacing, a 30 fps limit is an even 60 on a 60 Hz screen on a PC that keeps 30 but not 60 (see the results below for a spot where this one does not).
Testing
tests/test_fps_limit.py(new, inrun_all.pywith--cc gcc): compilesfps_limit()andframe_period()out ofnn_vi.cwith stand-ins forgetenvandrx_optionand checks off, 30, 45, the env over the menu, a longer game interval kept, 60 and <15 as off; reads the menu row, labels, table and option 18 from the sources.python -I -B tests/run_all.py fps_limit report_words text_speed: pass (Windows, llvm-mingw).Heavy Kokiri view (~2440 draws), Frame generation 2x + Frame pacing, windowed, 60 s each:
RX_VK_FLASH, every frame captured) walking with the limit at 30: 0 flash events, 0 white blowouts, 0 black frames over ~1800 frames.fps_limit()is 0).Related
nn_vi.c's pacing, this one only below 60.