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

Linux + Nvidia + Vulkan + X11: Judder / lag spikes with PresentMode::Fifo #6251

Open
valadaptive opened this issue Sep 10, 2024 · 1 comment
Labels
api: vulkan Issues with Vulkan platform: x11 Issues with integration with linux/x11 type: bug Something isn't working

Comments

@valadaptive
Copy link

Description

I'm running Linux with X11 on an Nvidia GPU, and the demos have periodic "hitches" in the frame pacing that seem to be a result of PresentMode::Fifo. Once every second or so (the timing is not perfectly consistent), a frame takes a long time to render (around 100ms) and previously submitted work all completes at once. New frames are then rendered rapidly until the queue is full again. Here's an example from the bunnymark demo, where I've modified the framework to give each frame a number and track pacing:

[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 36
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 32
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 16.67ms (60.0 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 37
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 33
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 16.69ms (59.9 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 38
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 34
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 16.74ms (59.7 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 39
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 35
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 100.52ms (9.9 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 40
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 36
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 37
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 38
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 39
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 0.90ms (1113.5 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 41
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 40
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 0.46ms (2195.4 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 42
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 41
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 0.43ms (2340.8 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 43
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 0.36ms (2816.5 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 44
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 0.37ms (2704.2 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 45
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 13.69ms (73.1 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 46
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 42
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 16.67ms (60.0 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 47
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 43
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 16.75ms (59.7 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 48
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 44
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 16.64ms (60.1 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 49
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 45
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] Frame time 16.67ms (60.0 FPS)
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted 50
[2024-09-10T19:05:43Z INFO  wgpu_examples::framework] submitted work done 46

Adding a context.device.poll(Maintain::wait()); after each frame to limit the length of the queue to 1 frame seems to help but does not eliminate the stutter, instead only reducing it to 1 frame as well:

[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] Frame time 16.70ms (59.9 FPS)
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted 186
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted work done 186
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] Frame time 16.65ms (60.0 FPS)
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted 187
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted work done 187
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] Frame time 33.44ms (29.9 FPS)
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted 188
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted work done 188
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] Frame time 0.57ms (1751.2 FPS)
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted 189
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted work done 189
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] Frame time 16.09ms (62.2 FPS)
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted 190
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted work done 190
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] Frame time 16.63ms (60.1 FPS)
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted 191
[2024-09-10T19:14:47Z INFO  wgpu_examples::framework] submitted work done 191

Setting desired_maximum_frame_latency to 1 in combination with context.device.poll(Maintain::wait()); does seem to completely eliminate the judder.

Repro steps

Here are the changes I made to the framework to report frame/present pacing

Expected vs observed behavior

Frame pacing should be smooth. In general, frame pacing should get smoother as the amount of buffering increases, whereas the opposite seems to be true here.

Extra materials

Not sure if this is a driver bug or a consequence of PresentMode not actually controlling frame pacing. This Reddit post describes a very similar issue but seems to indicate it's specific to Nvidia on Linux.

The vkcube demo seems to work properly with no frame pacing issues on my machine, which seems to indicate that there's at least some way to fix this on the API consumer's side. See this commit to vkcube which uses fences to limit outstanding presentations, and this commit which changes the throttling logic and states "It is currently impossible to reliably throttle presentation per the Vulkan spec."

Platform
Fedora 40, latest wgpu trunk (9b36a3e), Nvidia driver 560.35.03 on X11

@valadaptive
Copy link
Author

A lot of these types of issues seem to get redirected to #2869, but I think this is a significant usability bug beyond any sort of API for finer-grained frame pacing control.

@Wumpf Wumpf added api: vulkan Issues with Vulkan platform: x11 Issues with integration with linux/x11 type: bug Something isn't working labels Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: vulkan Issues with Vulkan platform: x11 Issues with integration with linux/x11 type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants