vulkano-rs / vulkano

Safe and rich Rust wrapper around the Vulkan API
Apache License 2.0
4.41k stars 434 forks source link

Example makes windows dragging very slow #252

Closed killkrt closed 7 years ago

killkrt commented 7 years ago

Hi,

I've found a strange behavior running the teapot and triangle examples.

One of my CPUs goes always at 100% (taken from the running example) and dragging windows (any windows on the screen) it's quite hard, since the mouse seems to be stucked as you try to drag a window, while it is fluid when just moving around. It's not even possible to close the example window, the only way is pressing CTRL+C.

This issue doesn't happen with image example.

Just for info in both cases the output of the example is: Using device: GTX 970 (type: DiscreteGpu)

System info: OS: Arch Linux (Kernel 4.7.2 64bit) Video Card: nVidia GTX 970Ti (driver 370.23-4) Desktop environment: Budgie Dekstop Wayland: no

tomaka commented 7 years ago

If the problem is that the CPU goes to 100%, then it can be fixed by forcing the Fifo present mode (instead of the first mode available, like the examples do).

Using Fifo means that you won't be able to call acquire_next_image more than once every 16.7ms, which means that the thread will sleep a little bit.

nphyx commented 7 years ago

I solved this by building a frame limiter around the main loop (https://gist.github.com/nphyx/e5970f20c1ce761a0a03276810bcefc4). Does Fifo present mode do this automatically?

tomaka commented 7 years ago

@nphyx Yes, but if the framerate goes below 60fps it will also reduce the speed of your simulation. This is not always what you want.

nphyx commented 7 years ago

You could run the render loop in a separate thread from the simulation though, right? Unless you need it synced to the FPS for some reason (I guess some things would make more sense that way). Are there any other disadvantages to the Fifo approach or is it generally the "right" way to manage framerates? And if so, is there a way to set a different framerate?

tomaka commented 7 years ago

You could run the render loop in a separate thread from the simulation though, right? Unless you need it synced to the FPS for some reason

Usually the simulation writes to some state which is then read by the rendering system. If you put the two on two separate threads, there are two possibilities:

The "correct" approach, I think, is to maintain a count of the number of times the logic should have been run based on a timer, and a count of the number of times it has been run. Thanks to this you can run the simulation multiple times per frame if the framerate is too low.

Are there any other disadvantages to the Fifo approach or is it generally the "right" way to manage framerates?

Except Immediate, which will show tearing, there's no "wrong way". Mailbox will make the framerate be as fast as possible and without tearing. Fifo will block at the nearest divider of 60 (so it will block either at 60fps, 30fps, 20fps, 15fps, etc.). Relaxed will block at 60fps, but if it goes below it will not round down (ie. it can run at 55fps for example).

It may seem that Relaxed is always better than Fifo, but it also means that the framerate is less stable. With Fifo, the whole range from 30 to 59 will be rounded down to 30. In first person shooter, I think it's usually better to have a stable framerate more than a high framerate.

tomaka commented 7 years ago

Triage. Eventually the examples should be changed to use Fifo by default, as it is supposed to guaranteed to be supported by the implementation. Older versions of Mesa didn't support it though, so fixing this problem may break the examples on these old versions.