Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat) Improve frame pacing, and only go framepaceless if the GPU is loaded #2642

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

shinyquagsire23
Copy link
Contributor

So, there's two modes of frame pacing: Framepaceless and framepaced.

Framepaceless was changed so that it will only omit sleeps if:

  • The game latency is over the display interval
  • The compositor is taking more than 2ms (ie, the GPU is actually loaded)
  • Server FPS (present-to-present latency) is under display interval.

Seems to be more stable in high-FPS games (and the overlay).

Framepaced was changed so that it will subtract the compositing latency from the vsync sleep. Sometimes if the GPU is starting to get fully loaded, the compositing latency will go up to ~5ms or so. This means that for example (assuming a 100Hz HMD):

  • If a game is taking 7ms to render and the compositing takes 3-4ms, the vsync round-up will start constantly thrashing.
  • If a game is taking 10ms to render and the compositing takes 5ms, the vsync will round up like it should.
  • If a game is taking 15ms to render and the compositing takes 5ms, the vsync will round up twice, when arguably it shouldn't have.

For whatever reason, subtracting the compositing latency from the vsync sleep seems to agree more with SteamVR's frame pacing, and in nearing-display-frametime situations, seems to result in a less-thrashy graph. I think what happens is that if a game is taking 7ms to render and compositing takes 3-4ms, the client-side frame queue has an easier time absorbing the impact of 1-2ms variance on the next frame as opposed to the 10ms/0ms thrashing if it starts rounding. For even lower FPS games, SteamVR's frame pacing seems to take the wheel and the graphs get really flat.

I also think that the framepaced change basically makes the framepaceless change almost useless.

@shinyquagsire23 shinyquagsire23 requested a review from zmerp January 18, 2025 02:23
Comment on lines +510 to +540
pub fn last_game_time_latency(&self) -> Option<Duration> {
self.connection_context
.statistics_manager
.read()
.as_ref()
.map(|stats| stats.last_game_time_latency())
}

pub fn last_compose_latency(&self) -> Option<Duration> {
self.connection_context
.statistics_manager
.read()
.as_ref()
.map(|stats| stats.last_compose_latency())
}

pub fn last_frame_present_interval(&self) -> Option<Duration> {
self.connection_context
.statistics_manager
.read()
.as_ref()
.map(|stats| stats.last_frame_present_interval())
}

pub fn display_interval(&self) -> Option<Duration> {
self.connection_context
.statistics_manager
.read()
.as_ref()
.map(|stats| stats.display_interval())
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the API surface seems pretty big, maybe the timing logic should be moved inside the StatisticsManager?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants