Repository navigation
shim: a late start keeps its slot's timeline (FPS limiter ignored at 120 Hz) - #49
Conversation
…ant release after a late start Reported on app master with payload 20261103.6 (shim 762e559): the FPS limiter set to 20 under gamescope on a 120 Hz panel left MGS V: The Phantom Pain at 40-50 fps; at 60 Hz the cap held. Reproduced on the Retroid Pocket 6 at 120 Hz with DTD at 1920x1080, cap 20, env mailbox: census `declared=mailbox requested=immediate source=env cap=20 gate=vsync`, `gate_holds` frozen at 188 for the rest of the session while `gate_late` grew by one per frame, frame spacing 17.2-20 ms (DTD's own ~53 fps). The cap reached the shim; the gate stopped holding. Cause: #47 (1cc98e1) added, next to the fix for the cap-rate FIFO cell (gate off under that declaration, kept here), a rule that the release after a late start is never more than one grid instant after it. A cap below the display's rate holds the guest for a whole slot (six vblanks at 20 on 120 Hz); after that rule fired once the next release was one vblank after the late start, a guest whose frame outlasts one period plus ON_TIME_NS (0.5 ms) was late for that release too, and so for every release after: the gate never held again. At 120 Hz (8.3 ms period) that is every game; at 60 Hz a guest faster than ~58 fps recovers, which is why the 60 Hz panel hid it. - icd_shim/src/vsync_gate.rs: Schedule::book: a start late by less than a period is booked to its release point as before; a start late by a period or more but still inside its slot (before `ideal + interval`) is booked to the grid instant it is in and keeps the slot's ideal timeline, so the release after it is where the cap puts it, at most the rest of the slot away; a start past the whole slot restarts the timeline from the instant it is in, so a stall carries no debt. The cap-rate cell is unchanged (slot == period). Tests: the late-frame-on-a-divisor-cap test now expects the slot's release (two vblanks at 30 on 60) and covers late by a whole vblank and past the slot; a new test runs a guest with 18 ms frames, 1 ms late wake-ups and one 80 ms hitch under cap 20 on 120 Hz (and 22 ms frames under 20 on 60 Hz) and requires the 6- (3-) vblank cadence everywhere but the three releases after the hitch, which catch the slot's timeline up, and never more releases than the cap over the run. The existing 16 ms guest on a 59.97 Hz grid under cap 60 still gets every vblank. - docs/15: the gate paragraph states the rule and why the next-grid-instant release is gone.
983bed0 to
5d1e0ae
Compare
|
Device verification, Retroid Pocket 6 at 120 Hz, DTD 1920x1080, env mailbox, shim from this branch (sha256 0339ed44…), Utkarsh switching the Quick Menu limiter live:
Each switch settled within the same second (40 → 20: 26.8 fps for the partial second, 20.0 from the next; 20 → 40: 24.8 then 40.6). Before this change the same device, scene and cap 20 read The 3-4 s stretches with almost no acquires in the log are the Quick Menu being open (the session is stopped while it is up); the HUD's 2 s frame window then takes a couple of seconds to show the new rate after the menu closes. That is the app's HUD, unchanged here. Unit tests (the whole |
|
Unit tests at 5d1e0ae on the RP6: 90 passed, 0 failed. Independent 100 s gameplay run with the branch shim (DTD boat overworld, 120 Hz, cap 20): 2010 commits in 100.4 s = 20.02 fps, gate_holds +2010, gate_late +16, log in gn-testlogs/mailbox-vsync-gate-20261102/runs/capgate-1/. |
…panel rate again (#2336) Ships GameNative/gamenative-drm#49: the shim's vsync-grid gate no longer releases the frame after a late start at the next grid instant, a rule from GameNative/gamenative-drm#47 that made every cap below the panel's rate stop holding once a frame outlasted one vblank (MGS V at cap 20 on a 120 Hz panel ran at 40-50 fps; DTD at 53). Only GamescopePayload.VERSION changes. Co-authored-by: Utkarsh Dalal <utkarsh.dalal@toptal.com>
Report
App master with payload 20261103.6 (shim 762e559): the FPS limiter set to 20 under gamescope on a 120 Hz panel left MGS V: The Phantom Pain at 40-50 fps. At 60 Hz the cap held.
Reproduced
Retroid Pocket 6 at 120 Hz, DTD 1920x1080, cap 20, container env mailbox:
The cap reached the shim. The gate held 188 frames, then never held another one:
gate_lategrows by one per frame and the game runs at its own ~53 fps.Cause
#47 (1cc98e1) carried two changes. The fix for JT's 40 fps capture, the gate off under the cap-rate FIFO declaration, stays. The second, "the release after a late start is never more than one grid instant after it", is the bug: a cap below the display's rate holds the guest for a whole slot (six vblanks at 20 on 120 Hz), and after that rule fired once the next release was one vblank after the late start. A guest whose frame outlasts one period plus
ON_TIME_NS(0.5 ms) is late for that release too, and for every one after it, so the gate never holds again. At 120 Hz (8.3 ms) that is every game; at 60 Hz a guest faster than ~58 fps recovers, which is why a 60 Hz panel hides it.Change
Schedule::book(icd_shim/src/vsync_gate.rs): a start late by less than a period is booked to its release point, as before. A start late by a period or more but still inside its slot is booked to the grid instant it is in and keeps the slot's ideal timeline, so the release after it is where the cap puts it, at most the rest of the slot away. A start past the whole slot restarts the timeline from the instant it is in, so a stall carries no debt. The cap-rate cell is unchanged (slot == period), so the #47 capture stays fixed.Trade: a late frame's successor can be held for the rest of its slot instead of coming out one vblank later; that is what a limiter does on a hitch, and the cap holds on average.
Tests: the late-frame-on-a-divisor-cap test now expects the slot's release (two vblanks at 30 on 60) and covers late by a whole vblank and past the slot; a new test runs a guest with 18 ms frames, 1 ms late wake-ups and one 80 ms hitch under cap 20 on 120 Hz (and 22 ms frames under 20 on 60 Hz) and requires the 6- (3-) vblank cadence apart from the frame after the hitch. The 16 ms guest under cap 60 on 59.97 Hz still gets every vblank.
docs/15 states the rule and why the next-grid-instant release is gone.
Verification
adrenotools_gamescopelib suite) on the RP6 through an adb cargo runner.Delivery: payload
gamescope-gamenative-20261103.7.tzst(sha2561b2dc730…4f55, shimb10cb509…9122from 5d1e0ae) is on both CDN hosts; app PR utkarshdalal/GameNative#2336 bumpsGamescopePayload.VERSIONand depends on this PR.EOF
)