Gamescope Compatibility - Pahheb/lsfg-vk GitHub Wiki
Gamescope is the compositor used on the Steam Deck. Many Linux users use Gamescope outside of Steam as well, as it provides a nice canvas for a game to run in that doesn't need to fight with the compositor to work properly. It also has some neat upscaling features.
For these exact reasons is Gamescope support one of the most anticipated things of this project. I do unfortunately have to announce, that after some research, Gamescope support will be impossible.
Please do read the rest of this document so you actually understand what this means, because the impact will be much less than you think.
Understanding how Gamescope works
Gamescope can run in one of three modes (technically four, if we count VR):
- SDL
- Wayland
- DRM
Let's understand what this means:
- SDL is a library used for creating a window, handling keyboard and mouse input, etc. and Gamescope can use SDL to create a window to draw the game to. The upsides to this approach are, that SDL supports a bunch of compositors. It can run on any Wayland compositor, it runs on X11 and it even runs on Windows.
- The Wayland backend as the name suggests talks to Wayland directly. The downsides are obvious, this will not run on Windows and it will not run on X11. The upsides are amazing however: Images are fed directly to the Wayland compositor and synchronization does not rely on a queue anymore, meaning latency is significantly lower (on most compositors it's identical to SDL though). Also, while it sounds like a "Wayland" backend would work on all Wayland compositors, the compositor needs to implement something extremely specific. Due to this, the Wayland backend doesn't even work on Hyprland or GNOME.
- DRM is the interface provided by Linux itself. You talk directly to the monitors and directly to the GPU. Naturally this only works if you do not have Wayland or X11 running (e.g. you're on a white terminal or just have a blackscreen). Synchronization is implemented with a direct shot to the monitor, so V-Sync actually means V-Sync for once.
As you may have already guessed by now, the Steam Deck itself runs in DRM mode Gamescope (at least as far as I know, I don't have any sources or did any testing myself). When you are in docked mode, the entire Steam UI and every game you play runs on this one instance of Gamescope.
Once you switch into Desktop mode, Gamescope is stopped and a Wayland compositor (KDE) starts up.
Understanding how lsfg-vk does frame pacing
The way lsfg-vk works, is by putting a layer inbetween Vulkan and your game. It listens for one specific method to be called (vkQueuePresentKHR
) and inserts generated frames inbetween by calling the method a few more times (depending on the multiplier, of course).
This system relies on a swapchain. Let's not get lost in the details, but you can think of a swapchain as a list of images. If the game (or the frame generation) finishes rendering one image, it puts it on the swapchain. The compositor can then look at the list, grab the image and put it on the actual screen.
Let's assume the game renders one frame and lsfg-vk renders an additional 3 frames (4x frame generation). If lsfg-vk puts all 4 images onto the swapchain at the same time, what will the compositor do? The answer is, this depends on the present mode. A present mode can either be "immediate", which means "Once a frame is on the swapchain, put it onto the screen IMMEDIATELY". Or a present mode can be "FIFO", which means "When the monitor finished displaying the previous frame, grab the next frame in order of submission and put it on the screen". This second approach is more commonly called "vsync", and when you change that option in the game settings, you are actually changing the present mode.
This brings me to how lsfg-vk does frame pacing. The answer is, it doesn't. It forces vsync/FIFO onto the swapchain and simply puts the pictures onto the swapchain when they're ready, letting the compositor do the pacing by itself. This approach has some upsides and some downsides, but they are out of the scope of this document. The key takeaway here is: We need a swapchain.
The problem with Gamescope
As we've established before, the Steam Deck runs Gamescope via DRM and most desktop users run Gamescope via Wayland or SDL backend. We've also established that lsfg-vk relies on a swapchain to function.
The problem is, the Wayland and DRM backends, simply do not have a swapchain.
When you try to use lsfg-vk on those backends you are greeted with this, now hopefully familiar, error message:
lsfg-vk(layer): Failed to get device function pointer for vkCreateSwapchainKHR
lsfg-vk(layer): Failed to get device function pointer for vkQueuePresentKHR
lsfg-vk(layer): Failed to get device function pointer for vkDestroySwapchainKHR
lsfg-vk(layer): Failed to get device function pointer for vkGetSwapchainImagesKHR
lsfg-vk(layer): Failed to get device function pointer for vkAcquireNextImageKHR
This is lsfg-vk screaming about not finding the methods responsible for swapchains, simply because they do not exist.
What does this mean for me? Can I still use Gamescope?
Yes, you can absolutely still use Gamescope, but it requires extra caution. Let me explain.
lsfg-vk can be enabled in two places when using Gamescope:
# enable lsfg-vk on gamescope
$ ENABLE_LSFG=1 LSFG_MULTIPLIER=2 gamescope -- env DISABLE_LSFG=1 (...)
# enable lsfg-vk on the game
$ gamescope -- env ENABLE_LSFG=1 LSFG_MULTIPLIER=2 (...)
# !! NEVER forget the DISABLE_LSFG=1, you will load lsfg-vk TWICE !!
$ ENABLE_LSFG=1 LSFG_MULTIPLIER=2 gamescope -- (...) # bad!
As you've just learned, the first option here will not work for non-SDL backends.
Can I use the SDL backend?
Unfortunately you cannot use the SDL backend either in most cases.
Gamescope updates at a fixed refresh rate. It's the value you specify with -r
or is inherited from your monitor. Gamescope does not care about when it receives a new frame from the game, it simply refreshes at a fixed rate. If your game has microstutters, or renders at a framerate that doesn't quite match up with Gamescope (fluctuating between 60 and 70 for example), you will get a very rough experience and extremely weird frame pacing. The only usecase for lsfg-vk on Gamescope itself would be if you're on some old, potentially 32-bit game that gets a dead-stable 30 fps and you wish to up that framerate. Other than that, do not use it.
Summary
I want to make this abundantly clear:
- You can keep using Gamescope with your games
- You CANNOT add lsfg-vk to Gamescope, but you CAN add lsfg-vk to the game inside of Gamescope
Here's how you properly enable lsfg-vk on the game inside of Gamescope:
# DO NOT PUT ENABLE_LSFG=1 BEFORE "-- env"
$ gamescope (arguments) -- env ENABLE_LSFG=1 LSFG_MULTIPLIER=4 (game)
If there's any Valve developer reading, or anyone who knows how the Steam Deck and Gamescope works in more detail than me, I would appreciate a round of fact checking. <3