Using My Laptop's Nvidia GPU On Linux
UPDATE: Since I wrote this, some things have of course changed. Nowadays, the stock Nvidia driver ships with prime-run
and I just use that. It's nice and easy, but performance has some odd characteristics such as periodic stuttering. I'll leave the rest of the post in place for historic reasons, but be warned it's all outdated info.
As far as I know, official support for primus functionality on Linux is somewhat limited. I recall reading about some sort of official support from Nvidia themselves, but now that I look for evidence of this I'm unable to find it. As an alternative, I looked to using nvidia-xrun in order to more directly utilize the nvidia GPU inside my laptop. I've used primusrun, bumblebee, and friends before and they just aren't as easy to work with as this in my opinion - but most importantly, performance was lacking. 1 2 Read on as I discuss how I did this, with Void Linux package recipes.
→ Seamless Or Not
The main advantage to using a setup like bumblebee (or, presumably the officially supported method that I've not used) is that you can run an arbitrary program and have it use the Nvidua GPU - on top of any desktop session that might be running off of the integrated GPU. It's a bit more convenient, but can have performance issues due to various bottlenecks. It is impressive nonetheless.
I actually ran this setup for quite some time and it worked well enough but the performance issues (stuttering that was likely caused by the integrated GPU) and maintenance cost (after some time of not using it, I wasn't really able to get bumblebee and friends working again and didn't care to put too much time into it) made it not worthwhile to keep up with.
→ Into Xrun
I don't really recall why I started looking at nvidia-xrun, or where I might have first seen it, but eventually I dusted off my altered nvidia package for void and gave it a spin.
→ An Altered Driver Package
I couldn't simply use the nvidia driver package provided by my distribution's package manager, because it would overwrite things like the system libGL.so
and others, and that would break the integrated GPU (which I still wanted to use as the main driver).
I decided to fork the provided package template and make some small changes that would allow installing it alongside the Mesa-provided libraries. The result is viewable on my fork of the void-packages repository, but by and large it is the same thing as the actual nvidia package with the exception that it doesn't make itself the system provider of various libraries as described above. 3 4
→ The Xrun Package
The nvidia-xrun program itself is a bit of an oddball in that it's simply a shell script, but it calls sudo. I don't think it's common for a package-provided program to implicitly call sudo like that, at least I'd find it a bit jarring, so this isn't something I'd expect the Void maintainers to merge without some modifications on that front. Anyways, that template is also viewable on my fork of the void-packages repository. 5
→ Building And Installing Packages
There's nothing special about building these, but if you don't use Void or never built a package it might not be clear just how easy it is:
# Clone my fork of void-packages, the nvidia-primus branch has the goods:
git clone -b nvidia-primus https://github.com/hristoast/void-packages
cd void-packages
# Bootstrap or update as needed
./xbps-src binary-bootstrap # OR: ./xbps-src bootstrap-update
# 64-bit driver package:
./xbps-src pkg nvidia-primus
# 32-bit driver package:
./xbps-src -a i686 pkg nvidia-primus
# Now, nvidia-xrun:
./xbps-src pkg nvidia-xrun
# Finally, install them:
sudo xbps-install --repository=./hostdir/binpkgs/nvidia-primus/nonfree nvidia-primus
sudo xbps-install --repository=./hostdir/binpkgs/nvidia-primus/multilib/nonfree nvidia-primus-libs-32-bit
sudo xbps-install --repository=./hostdir/binpkgs/nvidia-primus nvidia-xrun
If you don't use Void Linux, you can still of course install these things on your own.
→ Setup
So now you can run all kinds of things on your GPU right? Well no, not yet. There is of course some configuration that needs to be done first. The required files are listed in the nvidia-xrun README, and the repo ships with some example configurations. 6 Below I describe specifically which files are needed.
→ nvidia-xorg.conf
Copy this to /etc/X11/nvidia-xorg.conf
and you're all set. Before moving on, it's worth checking that you have the right bus ID configured in /etc/X11/nvidia-xorg.conf
. Please see the nvidia-xrun README as a reference on how to do that. 7
→ nvidia-xinitrc
No changes are made to this file, just create the directory /etc/X11/xinit
if it doesn't exist and copy the file from the repo to /etc/X11/xinit/nvidia-xinitrc
.
→ config/nvidia-xrun
Last but not least, this needs to be copied to /etc/default/nvidia-xrun
. I didn't change anything here, but feel free to make any changes you think are appropriate for your setup.
→ Other Considerations
While researching this post, I came across other resources for setting this kind of thing up. A thread from reddit's /r/linux_gaming covers a lot of details nicely, but it claims bumblebee is needed when in fact it is not. 8 This post also confirms my observations: that nvidia-xrun yields noticeably better performance than alternative methods.
→ X-running Stuff
Now it's time to finally run something on the Nvidia GPU. First thing's first, switch to an unused TTY with a keypress such as Ctrl-Alt F5. Log in, and invoke the nvidia-xrun
command like this:
# I use Openbox, feel free to run any DE you like.
nvidia-xrun openbox-session
You will be prompted for a sudo password as various system-level changes are made to enable running the Nvidia GPU. 9 From here I'm given a desktop session running on the Nvidia GPU; anything I launch from here will also be on the Nvidia GPU. You can run sudo nvidia-smi
to verify that you're using the Nvidia GPU.
A beautiful part of this is, my old X session that's using the integrated GPU is still chugging away. I can press Ctrl-Alt F7 to go back to it whenever I want, and of course the Nvidia session stays available until I exit with openbox --exit
or some other method.
Of course, you don't have to run a desktop environment with nvidia-xrun
; it's perfectly fine to directly launch a game, or steam, or anything else that requires an X display. Feel free to try anything that suits your fancy.
→ Conclusion
It's not a seamless experience, but it is still a decent one at the end of the day. I can run things on the Nvidia GPU and it doen't interfere with my normal desktop too much. And the Void packages I've fashioned make staying up to date relatively simple. If you've got a setup like mine, with a secondary Nividia GPU, this is definitely worth trying.
→ Footnotes And References
1https://github.com/Witko/nvidia-xrun
2https://www.bumblebee-project.org/
3srcpkgs/nvidia-primus/template
7README.md#setting-the-right-bus-id
8The Ultimate Guide to Setting Up Nvidia Optimus on Linux; I suspect that Bumblebee was listed as needed because it may have provided a special driver package, similar to what I build above. Any Arch user: feel free to inform me!