NVIDIA Optimus is a technology that allows an Intel integrated
GPU (iGPU) and
discrete NVIDIA GPU (dGPU) to be built into and accessed by a laptop. It
is also often called "hybrid graphics", and its main feature is
that the iGPU controls all aspects of displaying the video output, while
the dGPU is mainly used for computing 3D-intensive sceneries but is not able to perform output on its own.
For many years the only way to get these to work is by using only
open source driver. You can choose to use only the iGPU using either
"i915" or "modesetting" driver, or you can using both using DRI PRIME,
but only if the NVIDIA dGPU is driven by the open source nouveau
driver. The nouveau driver however has left a lot of things to be
desired, the main problem being its lack of features, lack of
performance, and its on-going multi-threading bugs.
NVIDIA proprietary driver would offer a much better performance and
experience, however, setting it up was extremely complicated and hacky.
Two of the most prominent methods is "Bumblebee" and "vga switcheroo".
All this has changed since 2016. NVIDIA finally found a way
to integrate their proprietary driver with the same PRIME method that
is used by the open source driver. (It was never a technical problem to
do that, the problem was legal: how to do it in a way that satisfy both
NVIDIA proprietariness and Linux kernel GPL license). However, back then
it was still too early because it required a version of Xorg server
which wasn't released yet.
Time has passed and things are a lot more stable now. This
documentation will show you how to use proprietary NVIDIA driver with
PRIME so you can get maximum performance from you NVIDIA card in an
Optimus-equipped laptop.
Before we begin, it is important that with this method, the NVIDIA
GPU will be active at all times. It is not possible at this time to
dynamically switch the dGPU on or off. This may cause some concern for
battery life, so it you do, then you'd better stick with the usual
iGPU-only method (or the older and more complicated method like
Bumblebee).
This note is meant for Fatdog64 801 onwards. It is possible to do
this with Fatdog64 800 but the steps needs to be changed because
Fatdog64 800 graphic subsystem does not have the necessary hook to make
it work, but you can do that yourself.
Basically there are two steps that you need to do.
First, you need to create an Xorg configuration that will configure NVIDIA with PRIME support.
Then, on the second step, you need to add the scripts that will activate
this configuration just before the graphic subsystem starts.
The very first thing you have to check is to confirm that your laptop
supports Optimus. Older laptops with dual graphics may not support this
(they use a configuration where both iGPU and dGPU are capable of
displaying the output, and they use a "mux" instead). The method listed
here can only work on true Optimus-based laptops, not the older
mux-based technologies. Laptops from 2015 onwards usually comes with
Optimus instead of mux.
The next thing, is obviously you need to obtain a copy of the NVIDIA driver, either as an installable package, or as an SFS package. The final version of Fatdog64 usually ships with suitable NVIDIA driver, however there are so many variants of NVIDIA graphics card that NVIDIA itself has decided to publish different drivers for each card. You need to review NVIDIA website to verify that your card is indeed supported by the version of the driver that you have on hand. If your card is not supported, then you need to obtain the version that does, or you need to make it yourself (or ask someone else in the forum to make it for you).
If you are adventurous enough, here is one way of doing it.
Traditionally the Xorg configuration is created in /etc/X11/xorg.conf.d/20-gpudriver.conf
You will need to create this file yourself, because xorgwizard does not support it. If you have an existing 20-gpudrive.conf file, you may want to back it up before proceeding.
First, you need to know the Bus ID of your NVIDIA card. You can do this by opening a terminal and then running the command:
lspci | egrep "NVIDIA"
Then notice the output you see. For example, in my system it will show:
04:00.0 3D controller: NVIDIA Corporation GK208M [GeForce GT 740M] (rev a1)
The Bus ID is the number 04:00.0. This needs to be translated into 4:0:0, which is what Xorg wants.
Once done, create the file /etc/X11/xorg.conf.d/20-gpudriver.conf with the following contents:
Section "Module" Load "modesetting" EndSection
Section "Device" Identifier "nvidia" Driver "nvidia" BusID "PCI:4:0:0" Option "AllowEmptyInitialConfiguration" EndSection
Obviously replace the BusID parameter with your own Bus ID that you found previously.
Congratulations, this step is done!
Update Jan 2020: An alternate /etc/X11/xorg.conf.d/20-gpudriver.conf which does not
require you to find BusID is the following.
Please use this, or the
above - but not both!
Section "OutputClass" Identifier "intel" MatchDriver "i915" Driver "modesetting" EndSection Section "OutputClass" Identifier "nvidia" MatchDriver "nvidia-drm" Driver "nvidia" Option "AllowEmptyInitialConfiguration" Option "PrimaryGPU" "yes" EndSection
You will now need to create two files, /etc/X11/xsetup and /etc/X11/xsetup-slim.
The contents of these two files are going to be identical, so if you
know enough about symlinks, you can even create one file only and
symlink the other one to it. But in case you don't know what a symlink
is, just create two files with the same content.
You need to put the following contents to both files:
#!/bin/dash xrandr --setprovideroutputsource modesetting NVIDIA-0 xrandr --auto
After you make these two files, make sure that both of them are executable, by running chmod +x /etc/X11/xsetup-slim /etc/X11/xsetup
.
Fatdog64 800 does not support /etc/X11/xsetup so you will need to edit /etc/X11/xinitrc directly and add this to it.
That's it!
Apparently it is now possible to use PRIME offload with the proprietary
NVIDIA driver if you have the driver from version 435 onwards.
"modesetting" driver is always supported as the integrated GPU driver,
"amdgpu" is supported since 450.57, and "intel" is supported since
455.38
Unfortunately, my hardware only supports drivers up to 418, so I am not able to test and confirm this this.
That being said, the process to do this one is quite simple:
basically the same as when setting up PRIME configuration for nouveau
driver (or any other open-source Xorg drivers).
Step 1:
Create the following /etc/X11/xorg.conf.d/20-gpudriver.conf snippet:
Section "Device" Identifier "iGPU" Driver "modesetting" #BusID "PCI:0:2:0" # maybe necessary EndSection Section "Screen" Identifier "iGPU" Device "iGPU" EndSection Section "Device" Identifier "dGPU" Driver "nvidia" #BusID "PCI:4:0:0" # maybe necessary Options "AllowEmptyInitialConfiguration" EndSection
Step 2:
Run the command
xrandr --setprovideroffloadsink nvidia Intel
Step 3:
Then, for program that you want to use the NVIDIA GPU, export DRI_PRIME=1 before lauching it, like the following:
DRI_PRIME=1 glxinfo | grep "OpenGL renderer"
References:
1. NVIDIA PRIME and PRIME synchronization
2. Arch Linux wiki entry for NVIDIA Optimus