Bumblebee and Vulkan: getting my games back
If you like gaming and Linux, you will understand how I got pretty excited learning Dota Underlords has a native Linux port just like its big brother Dota 2. As my brother recommended I gave Underlords a try and I was also quickly disappointed. The game requires Vulkan to run and I was convinced my ASUS laptop running on Ubuntu 16.04 would not support such an “advanced” technology, let alone in combination with Bumblebee. However, after an afternoon spent on the Internet, I was super happy to find out that my laptop and Bumblebee do in fact support Vulkan. And setting it up was really straightforward. Read on to learn how you can get it running yourself. Maybe, like me, you will be happy to learn to you do not need to revert to an older version of The Talos Principle and get more oomph out of Guild Wars 2 through Lutris.
Vulkan and Bumblebee
RockPaperShotgun described Vulkan as “the new big exciting Thing That Might Make Your Games Run Faster Without You Having To Buy A New Graphics Card Or Anything”. Specifically, Vulkan is the technology succeeding OpenGL and put forward as a (better) alternative to OpenGL and through proper integration with your graphics card, claims your games will run faster. It has cross platform support (including Nintendo support) which makes it more attractive to developers than DirectX.
Vulkan is supported by every more games, such as Mad Max, Star Citizen, Wolfenstein II, Quake Champions, … A recent update of The Talos Principle surprised a lot of users as it would no longer run without Vulkan being present on the system, unless they revert to a previous version. I was one of those users. Not too happy that I would have to re-download several gigabytes to continue playing a game I have enjoyed a lot for the past months.
Maybe as important for Linux gamers, Vulkan has allowed developers to create a fast alternative translation layer for Microsoft’s DirectX on Linux, through a library called dxvk.
Bumblebee on the other hand, is software that allows Linux users to enjoy the benefits of Nvidia’s Optimus technology. For systems, such as laptops, that have a power-efficient integrated graphics card as well as a powerful (but energy consuming) discrete graphics card, this technology smartly determines if a program needs a lot of power, or can just run on the integrated chip. This saves your laptop battery and keeps it nice and cool. Windows users can enjoy this feature out of the box, but Nvidia has only provided a partial implementation in its Linux drivers. Bumblebee helps you run software on the discrete card when you want and runs on the integrated graphics as a default, without having to restart your session.
Bumblebee has two methods of achieving this. Optirun, the oldest option based on VirtualGL, and primusrun which interacts directly with the card. Because primusrun does not use as many layers as its counterpart, it results in better performance and is generally my preferred method of running games. Once Bumblebee is installed, primusrun integrates nicely with steam games by either starting it through
$ primusrun steam
from the command line, which will run steam and all of its child processes on your discrete card, or by editing the launch options (Right click ‘Properties’ > ‘General’ > ‘Set Launch Options’) of your steam game by changing this to
primusrun %command%
If you see your frame rate limited to your screen’s refresh rate, you may try using
vblank_mode=0 primusrun %command%
to get the most out of primusrun. However, even when installing the necessary Vulkan libraries through apt
, the package manager, running a game through this method will fail. In the best case it will report that it was not able to find a Vulkan enabled graphics card. Luckily, Primus-vk solves that problem.
The solution: Primus-vk
Although my initial searches indicated that Bumblebee will never support Vulkan, digging a bit deeper led to the Primus-vk github page. It uses the pipeline of optirun
to intercept Vulkan API calls and then resolves those with the Vulkan libraries. It is a smart move, and compatible with Vulkan design to have Vulkan available through Bumblebee.
While the installation instructions on the page are quite straightforward, I did encounter some bumps in the road and would like to explain what I did to solve them.
Card compatibility
First check if your graphics card is compatible with Vulkan. In my case, opening nvidia-settings
quickly showed my graphics card and currently installed Nvidia driver version. Since we run the X session on the integrated graphics card, the settings will not detect an Nvidia card unless we start with
$ optirun -b none /usr/bin/nvidia-settings -c :8
Where :8 is the number of the terminal. If nvidia-settings
is not installed, it can easily be installed by running
$ sudo apt install nvidia-settings
Check your card against a compatibility list (or alternatively here) and if your card is compatible, it is time to install the necessary drivers.
Installing drivers
The Primus-vk github page lists a number of Debian packages that they required to install. In my case, the Nvidia graphics driver was present (as bumblebee was installed), but I did not have the mesa Vulkan drivers installed. Most of the compilation of Primus-vk went fine, but when running the tool later on, I got complaints. To prevent this, make sure you have the package installed:
$ sudo apt install mesa-vulkan-drivers
Compiling the Primus-vk source
Since I do not run Arch, I cannot download the precompiled packages but installing from source proved easy. I started with downloading the latest sources from Github (click the ‘Clone or Download’ button) and extracting them into their own folder, following along with the instructions in the readme file.
Before starting the compilation I needed to install the necessary development files.
$ sudo apt install libvulkan-dev
Then tell the source file where your libGL.so.1 file is located. So first I looked for its path
$ locate libGL.so.1
Which turns out to be /usr/lib/nvidia-396/libGL.so.1
and then I edited the file nv_vulkan_wrapper.cpp
in the directory where the sources were unzipped to point to the correct path (you can use vim, nano, or your favorite text editor):
$ nano nv_vulkan_wrapper.cpp
Look for the lines looking like the below, and update your own path of libGL:
#ifndef NV_DRIVER_PATH
#define NV_DRIVER_PATH "/usr/lib/nvidia-396/libGL.so.1"
#endif
Save your changes, now you are ready to compile. I changed the Makefile
to install to /usr
instead of/usr/local
but this is probably not needed.
$ make
$ sudo make install
This will install the libraries and a handy shortcut called pvkrun
. I see no reason make install
would not work, but when installing this way, I got some errors (and segfaults) even though my Nvidia card is correctly detected. Removing the following json files helped me, but may not be necessary for you to work.
$ sudo rm /usr/local/share/vulkan/icd.d/nv_vulkan_wrapper.json
$ sudo rm /usr/local/share/vulkan/implicit_layer.d/primus_vk.json
If you changed the install directory to to /usr
instead of/usr/local
, you will need to update the above to
$ sudo rm /usr/share/vulkan/icd.d/nv_vulkan_wrapper.json
$ sudo rm /usr/share/vulkan/implicit_layer.d/primus_vk.json
Now back to what the readme is telling us. Copy primus_vk.json
to ~/.local/share/vulkan/implicit_layer.d
$ cp primus_vk.json ~/.local/share/vulkan/implicit_layer.d
Then back up and edit the Nvidia icd to refer to the wrapper rather than the Nvidia library.
$ sudo cp /usr/share/vulkan/icd.d/nvidia_icd.json vi /usr/share/vulkan/icd.d/nvidia_icd.json.bak
$ sudo nano /usr/share/vulkan/icd.d/nvidia_icd.json
Which should look similar to this when done editing:
{
"file_format_version" : "1.0.0",
"ICD": {
"library_path": "libnv_vulkan_wrapper.so",
"api_version" : "1.1.70"
}
}
If your intel driver is configured correctly, this should be enough to start using Primus-vk. So we will take a look at that first. However, if your system is complaining about DRI3 not begin enabled, be sure to read on.
Using Bumblebee with Primus-vk
Usage and testing is straightforward. If you have a game installed that uses Vulkan, it is as simple as running
$ pvkrun [game-executable]
For example, to run The Talos Principle:
$ cd ~/.local/share/Steam/steamapps/common/The Talos Principle/Bin/x64
$ pvkrun ./Talos
However, there may be other issues stopping the game from running, so alternatively you can use vulkan-utils for testing:
$ sudo apt install vulkan-utils
$ pvkrun vulkan-smoketest
$ pvkrun vulkaninfo | less
vulkan-smoketest
should open an animated window, which will tell you Primus-vk and Bumblebee are working. For more information, you can use vulkaninfo
. Amidst a lot of information, you will see something like the below, indicating the discrete graphics card has been found.
PrimusVK: CreateInstance
PrimusVK: Getting devices
PrimusVK: Searching for display GPU:
PrimusVK: 0x17bfcd0:
PrimusVK: 0x17bfcd0:
PrimusVK: Got integrated gpu!
PrimusVK: Device: Intel(R) Haswell Mobile
PrimusVK: Type: 1
PrimusVK: Searching for render GPU:
PrimusVK: 0x17bfcd0:
PrimusVK: Got discrete gpu!
PrimusVK: Device: GeForce GTX 950M
PrimusVK: Type: 2
Using pvkrun
in Steam is as straightforward as using primusrun
, in your application specific settings just change %command%
to pvkrun %command%
. Again, prepending vblank_mode=0
may help improve your frame rate.
If you are like me however, games will still not run.
Enabling DRI3
When starting either a test program or a game, Vulkan tells me this:
vulkan: No DRI3 support detected - required for presentation
Note: DRI2 support detected, you can probably enable DRI3 in /etc/X11/xorg.conf
and basically tells us the solution. We should enable DRI3 (for our intel card) in its relevant xorg.conf file. Either edit or create a file called /usr/share/X11/xorg.conf.d/20-intel.conf
. You may have a similar file already, or it may be in /etc/X11/xorg/conf.d/
. In my case, I had a file loading the intel driver with the TearFree
option enabled, but not DRI3. When you are done editing the file, it should look similar to this:
Section "Device"
Identifier "Intel Graphics"
Driver "intel"
Option "TearFree" "true"
Option "AccelMethod" "sna"
Option "DRI" "3"
EndSection
Running Windows games
This worked amazingly well. Dota Underlords and The Talos Principle both run great, straight from Steam as native Linux games. However, there is a further advantage. Having Vulkan running, means we can use the dxvk layer to optimize games running through Wine. I enjoyed playing Guild Wars 2 when my laptop was still running on Windows, but had problems with sound stuttering, and low frame rates playing it on Linux.
However, when visiting the Lutris page for Guild Wars 2 the option of using dxvk become ever more appealing. Having installed Lutris from Ubuntu’s repositories
$ sudo apt install lutris
I only have to click on the install script for dxvk on the Lutris web page, and the installation starts running. After downloading the required files, it is now possible to log in. Lutris has built in support for Bumblebee and dxvk. The only thing required to do is select the primus_vk launcher in the Optimus Launcher field and the game works like a charm:
Guild Wars 2 is a DirectX version 9 game, but dxvk will also work for newer versions. If you like statistics, you can enable the Heads Up Display by changing DXVK_HUD to 1.
Enjoy! And if you have any tips on how you got your system running even easier, be sure to let me know!