Changes to the NVIDIA driver packages

The same set of changes described here have also been applied in the NVIDIA driver packages published by NVIDIA as part of the CUDA repositories. The changes will land in the 620 branch releases.

The same set of changes will land at the same time in the official driver installation guide.

DNF 5 reboot suggestion

The kernel module and the user space libraries must always be the same version, so after a driver update you really want to reboot. With DNF 4 on RHEL/EL 8 to 10, the packages have been adding themselves to the needs-restarting DNF plugin configuration for a while. DNF 5 did not have an equivalent until recently, but luckily my merge request to DNF 5 got merged without issues so we now have a configurable list of packages that can trigger the notification.

The snippets reside in /usr/share/dnf5/suggest-reboot.d/ and are available in Fedora (and eventually RHEL 11); after an update to the driver, “dnf5 needs-restarting” and the reboot hint at the end of the transaction tell you that a reboot is needed, like for a kernel update. This is also available in the 580 branch driver packages, the LTS driver that still supports older GPUs.

NVIDIA drivers on a system without an NVIDIA GPU

The NVIDIA driver packages can now be installed on any system, whether or not it has an NVIDIA GPU. That includes OS images that end up on very different hardware, and machines that only get an NVIDIA GPU later in their life, for example a laptop that gets plugged into a Thunderbolt dock or eGPU enclosure with an NVIDIA card inside.

Until now the packages assumed that if you installed them, you had the hardware. On a system without an NVIDIA GPU you would get services that fail at every boot, an autostart entry that complains at every login, and so on. None of it was harmful, but it made the driver a bad fit for generic images. Everything that needs the GPU now stays “dormant” and waits for the GPU to appear in the system.

Most of the changes are variations on the work done for Anatase (https://anatase.org/). Thanks to Antheas Kapenekakis for figuring it all out.

Kernel modules

The kernel modules are built as usual, through akmods (akmod-nvidia) or DKMS (dkms-nvidia), whether or not a GPU is present. They are not included in the initrd, and they are only loaded when the kernel finds a matching PCI device through its modalias. On a system without an NVIDIA GPU they just sit on disk. When a GPU appears, even after boot, udev loads the driver.

On top of the open kernel modules, nvidia-kmod and dkms-nvidia now carry two extra patches from Anatase:

  • Tunneled PCIe link speed. A GPU attached over Thunderbolt or USB4 sits behind a tunneled PCIe link, and the link often does not train to the best speed the tunnel supports. With this patch, whenever such a GPU is in use (at startup, and every time it wakes up from runtime power management), the driver stops the hardware from changing the link speed on its own at both ends of the link. It then asks the kernel’s PCI core to train the link once at the maximum speed available, and gives control back to the hardware when the GPU goes idle again. It is only enabled for Thunderbolt-attached GPUs and on kernels that export pcie_set_target_speed(), so internal GPUs are not affected. This is what makes the “plug in a dock with an NVIDIA GPU” case perform properly and not just work.
  • CEC over DisplayPort to HDMI adapters. This one is not about GPU detection, but it is a nice addition: it exposes the DisplayPort AUX channel to the kernel’s DRM helpers, so HDMI-CEC works through DP-to-HDMI adapters that support it. For example, you can control the Steam interface with a remote or turn on the TV once your HTPC set powers on.

I’m trying to push both patches internally in NVIDIA, let’s see if we can get them in.

Auotostart of programs

Previously the packages shipped systemd presets that enabled nvidia-persistenced and nvidia-powerd. An enabled service starts at every boot, GPU or not. The presets are gone. Both packages now ship a udev rule that pulls in the service when an NVIDIA display controller (VGA or 3D class) is added to the system:

ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000|0x030200", TAG+="systemd", ENV{SYSTEMD_WANTS}+="nvidia-persistenced.service"

On a system without an NVIDIA GPU the services never start. On a system with one they start at boot as before. When a GPU is hot-plugged, they start the moment it appears. There is nothing to enable or disable by hand.

nvidia-settings installs an autostart entry that restores the saved settings at login with “nvidia-settings --load-config-only“. Without an NVIDIA GPU this just fails at every login. The entry now checks for the device first:

Exec=sh -c "[ -e /dev/nvidia0 ] && exec /usr/bin/nvidia-settings --load-config-only"

No GPU means no device node, so that covers nvidia-settings as well.

CUDA in unprivileged containers

CUDA also needs the /dev/nvidia-uvm and /dev/nvidia-uvm-tools device nodes. They are normally created on demand: the NVIDIA libraries call nvidia-modprobe, a setuid helper that loads the nvidia-uvm module and creates the nodes.

Unprivileged containers (rootless Podman, Toolbx, Distrobox) can not call setuid programs on the system, so CUDA fails even if the rest of the GPU is passed through correctly. This is the standard mechanism for most of the non open source libraries that are part of the driver to make sure the correct device nodes are created upon execution.

nvidia-kmod-common now does this in advance with a udev rule. When an NVIDIA GPU is added, it runs “nvidia-modprobe -u -c 0“, which loads nvidia-uvm and creates both nodes. The nodes are then already there to pass into containers.

New 595 NVIDIA driver and Proton guide

New 595.45.04 driver

There’s a new 595.45.04 driver in the repositories, with a few interesting updates:

  • Sets egl-wayland2 as the default in place of egl-wayland, and this enables all the extra Wayland protocols that are part of it.
  • Finally enables the VK_EXT_hdr_metadata which is the missing extension to enable HDR, making this useless: https://copr.fedorainfracloud.org/coprs/bazzite-org/vk_hdr_layer/. It’s already obsoleted in Mesa and now also in nvidia-driver-libs; so it the layer package will be uninstalled the moment you upgrade.
  • Enables VK_KHR_swapchain_timeline_semaphore and VK_KHR_surface_timeline_semaphore, which are useful for VR headsets.
  • Implements VK_EXT_descriptor_heap which is the all new descriptor management in Vulkan, it’s now part of the Vulkan 1.4.340 spec and hopefully will increase peformance on DirectX 12 games on Proton (the vkd3d-proton part is still pending: https://github.com/HansKristian-Work/vkd3d-proton/pull/2805)
  • Enables nvidia-drm.modeset=1 by default, so it’s no longer needed in the configuration file.
  • Enables VK_EXT_present_timing, which should give some good performance as well.
  • Kernel suspend notifiers can be enabled for the open modules (NVreg_UseKernelSuspendNotifiers=1), which allows the removal of all the systemd units and scripts related to suspend and hibernate. Considering I’m shipping only open modules, this is for a nice simplification.

NVIDIA gaming technologies in Proton

Configuring all the NVIDIA specific gaming technologies in Proton definitely has a steep learning curve, so as part of the ongoing work for driver 595; I’ve added a Proton / DLSS / Reflex / Smooth Motion section to the NVIDIA Driver Installation Guide for Linux.

This guide has been written hand to hand with the DXVK-NVAPI folks, which have provided information on titles supporting the various technologies and helped out proof reading everything. It has also been reviewed internally in NVIDIA by the team responsible for the DLSS/NGX online updates.

The guide is not meant to replace completely the massive DXVK-NVAPI wiki, but should you give you the most useful information for getting started; along with some practical examples.

Steam Proton helpers

As part of the testing of games and technologies in the Proton / DLSS / Reflex / Smooth Motion section of the guide, I’ve also created Steam helper scripts and wrappers that I found very useful while using NVIDIA GPUs with Steam.

It contains three things:

Proton automatic configuration: A Python module that automatically configures DLSS, Reflex and Smooth Motion (if the title does not support native DLSS) for all titles you install with Proton. For example; you set Proton Experimental as the default compatibility tool, and then with the Python module every game you run with Proton will get all the NVIDIA features that can be enabled. It checks automatically for DLSS, Smooth Motion, etc.

Game wrapper (Proton and native): A wrapper for all games, that achieves the same thing as the Python module; with the main difference being that it works for both Proton and Linux native titles. Again it checks if the game supports DLSS otherwise enables Smooth Motion, etc. This is useful for the handful of native games where you want to update the DLSS libraries (ex. Baldur’s Gate 3) or enable Smooth Motion.

Automatic The drawback is of course that you need to add this to the Launch Options line of every game to use the wrapper.

Launch Options mass updater: Since the above wrapper needs to be set for all Launch Options of all games you have installed, and Steam does not offer easily this functionality, I’ve created a wrapper that parses the Steam VDF files and adjusts/reset all the Launch Options of every title installed at once.

You need to run this parser every time you install a new title via Steam.

The game wrapper and the mass updater is what I’m currently using on my system. The other option is to force Proton as the compatibility tool also for native titles and then you can just enable the Python module once and forget it all.

Let me know if you would like to see these scripts packaged in the repositories.

NVIDIA driver 580 LTS repository

Soon we will get a release of drivers in the 590 branch. So branch 580 will be the last driver branch to support Maxwell, Pascal, and Volta based GPUs.

There is now a long term support for the 580 branch of NVIDIA drivers along with the main one. This repository contains only the 580 driver set in both DKMS and akmod format for supported Enterprise Linux (EPEL) and Fedora releases.

My plan is to maintain this repository until branch is End of Life, which should be around June 2028.

Until then, I’ll try to keep it in sync with the latest changes and updates going into the main repository.

To install this repository on Fedora:

# cd /etc/yum.repos.d
# wget https://negativo17.org/repos/fedora-nvidia-580.repo

On Red Hat Enterprise Linux and derivatives:

# cd /etc/yum.repos.d
# wget https://negativo17.org/repos/epel-nvidia-580.repo

As usual, the EPEL repository is required for Red Hat Enterprise Linux 8 and above.

The open source kernel modules have been removed, as they are not supported on Maxwell, Pascal and Volta GPUs. This makes the kernel module packages smaller and just with the modules supporting this hardware.

Starting with branch 590 the only use case for closed source modules on GPUs that are also supported by open modules is the vGPU case, which anyway as a matrix of supported driver versions and distributions. So starting from 590 I’ll remove the closed source modules and just stick with the open ones from then on.

If you plan to use the Multimedia repository as well, which contains 590 drivers, you can increase the priority of the NVIDIA 580 driver packages on Fedora (DNF5) with:

# dnf config-manager setopt fedora-nvidia-580.priority=90

or on EPEL (DNF4) with:

# dnf config-manager --save --setopt=epel-multimedia.priority=90

Source code stuff is available on Github as usual.

Wayland only system using Nvidia drivers

My recent experience with Nvidia proprietary drivers and Wayland has been great. With the latest updates of EGL Wayland (1.1.16+), the performance of the Wayland session it’s on par with the X session and it’s free from visual artifacts and strange behaviours. Games running on Proton on Xwayland run smoothly and I can’t tell the difference between running them this way or under an X session.

As part of the Fedora 41 features, the workstation media will not install the X components by default, resorting to Wayland only. Of course the X components will still be available for install for corner cases (accessibility?), but they will not be installed by default.

To accomodate this, with the latest update of the Nvidia driver from the Nvidia/Multimedia repository it’s now possible to remove the X components and just leave the Wayland part without the need to remove the Nvidia driver as a whole.

There is a new subpackage called xorg-x11-nvidia which contains the X11 DDX driver, the GLX extension and the default X.org configuration file. This package can be removed along all X.org components and Gnome X session:

$ sudo dnf remove xorg-x11-server-Xorg
Dependencies resolved.
===================================================================================================================
 Package                            Architecture   Version                              Repository            Size
===================================================================================================================
Removing:
 xorg-x11-server-Xorg               x86_64         1.20.14-35.fc40                      @updates             3.6 M
Removing dependent packages:
 gnome-session-xsession             x86_64         46.0-1.fc40                          @fedora               16 k
 xorg-x11-drv-amdgpu                x86_64         23.0.0-3.fc40                        @fedora              186 k
 xorg-x11-drv-ati                   x86_64         19.1.0-11.fc40                       @fedora              477 k
 xorg-x11-drv-evdev                 x86_64         2.10.6-15.fc40                       @fedora               74 k
 xorg-x11-drv-fbdev                 x86_64         0.5.0-15.fc40                        @fedora               34 k
 xorg-x11-drv-intel                 x86_64         2.99.917-57.20210115.fc40            @fedora              2.0 M
 xorg-x11-drv-libinput              x86_64         1.4.0-2.fc40                         @fedora               98 k
 xorg-x11-drv-nouveau               x86_64         1:1.0.17-7.fc40                      @fedora              210 k
 xorg-x11-drv-openchrome            x86_64         0.6.400-7.20210215git5dbad06.fc40    @fedora              290 k
 xorg-x11-drv-qxl                   x86_64         0.1.6-3.fc40                         @fedora              166 k
 xorg-x11-drv-vesa                  x86_64         2.5.0-7.fc40                         @fedora               34 k
 xorg-x11-drv-vmware                x86_64         13.4.0-4.fc40                        @fedora              173 k
 xorg-x11-drv-wacom                 x86_64         1.2.2-1.fc40                         @updates             1.2 M
Removing unused dependencies:
 libXvMC                            x86_64         1.0.13-5.fc40                        @fedora               45 k
 mesa-libxatracker                  x86_64         1:24.1.6-1.fc40                      @fedora-multimedia    11 M
 nvidia-xconfig                     x86_64         3:560.35.03-2.fc40                   @fedora-multimedia    92 k
 xorg-x11-drv-wacom-serial-support  x86_64         1.2.2-1.fc40                         @updates              40 k
 xorg-x11-nvidia                    x86_64         3:560.35.03-2.fc40                   @fedora-multimedia    19 M
 xorg-x11-server-common             x86_64         1.20.14-35.fc40                      @updates             127 k

Transaction Summary
===================================================================================================================
Remove  20 Packages

Freed space: 38 M
Is this ok [y/N]:

The package xorg-x11-nvidia itself has reverse dependencies (Supplements) on the main Nvidia driver and X.org server packages, so in case of an install/reinstall of X.org with the Nvidia driver installed, the package gets added to the DNF transaction, making sure you have a working X session at the next login:

$ sudo dnf install xorg-x11-server-Xorg gnome-session-xsession
Last metadata expiration check: 0:36:46 ago on Sun 01 Sep 2024 09:11:59 PM CEST.
Dependencies resolved.
========================================================================================
 Package                   Arch      Version                 Repository            Size
========================================================================================
Installing:
 gnome-session-xsession    x86_64    46.0-1.fc40             fedora                13 k
 xorg-x11-server-Xorg      x86_64    1.20.14-35.fc40         updates              1.5 M
Installing dependencies:
 xorg-x11-drv-libinput     x86_64    1.4.0-2.fc40            fedora                50 k
 xorg-x11-server-common    x86_64    1.20.14-35.fc40         updates               36 k
Installing weak dependencies:
 xorg-x11-nvidia           x86_64    3:560.35.03-2.fc40      fedora-multimedia    2.3 M

Transaction Summary
========================================================================================
Install  5 Packages

Total download size: 3.9 M
Installed size: 23 M
Is this ok [y/N]:

All of this can be already performed on a Fedora 40 system. Just login using the standard “GNOME Session” (Wayland) and then remove the xorg-x11-server-Xorg package.

Prime / Optimus laptops and multi GPU systems

I’ve seen around tons of confusion about Optimus laptops, Prime and systems with multiple GPUs (like a desktop with an Nvidia dedicated GPU and an embedded AMD GPU) and how to configure them. People get mad with variables, scripts and extra tools.

The truth is, there’s not much to configure and since a few years, for most common cases, everything works out of the box.

Let’s take into consideration a very common case, a laptop with Intel + Nvidia GPU (Dell Precision 5680, Nvidia Optimus):

$ lspci | grep -i vga
00:02.0 VGA compatible controller: Intel Corporation Raptor Lake-P [Iris Xe Graphics] (rev 04)
01:00.0 VGA compatible controller: NVIDIA Corporation AD104GLM [RTX 3500 Ada Generation Laptop GPU] (rev a1)

And then let’s take the two most common cases into consideration to drive the GPUs.

  • Intel + Nouveau open source driver (DRI/DRI)
  • Intel open source driver + Nvidia proprietary driver (DRI/NVIDIA)

Power management

The system boots with the graphical output driven by the integrated Intel GPU (00:02.0) and the Nvidia GPU (01:00.0) is off.

$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
suspended

A simple command that touches the PCI card like lspci or nvidia-settings is enough to wake up the Nvidia GPU for probing:

$ lspci > /dev/null 
$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
active

A few seconds after, the GPU is again in suspended:

$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
suspended

The transition is always fast if no program is using the GPU, it usually takes just 4 or 5 seconds for the GPU to turn off. For example after exiting a game, you hear immediately the fan shutting down when the GPU goes off.

This is the simplest way to check power state of the GPU both when using the open source Nouveau driver and the Nvidia proprietary driver.

VGA Switcheroo (DRM drivers only)

If you are using the open source driver, there are a few added benefits in terms of control. The VGA Switcheroo files appear as soon as two GPU drivers and one handler have registered with vga_switcheroo.  since multiple GPUs are using a common framework, vga_switcheroo is enabled and we we can manipulate the state of the devices:

$ sudo cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS-Audio: :DynOff:0000:01:00.1
2:DIS: :DynOff:0000:01:00.0

After firing up the GPU for a workload, we can see the state reflected into the virtual file:

$ sudo cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS-Audio: :DynOff:0000:01:00.1
2:DIS: :DynPwr:0000:01:00.0

The DIS-Audio device is the actual HDA sound card on the GPU that is used to send output to an external output (ex. HDMI). That is also controlled by the dynamic control of the devices.

The configuration is flexible, so for example you could have two or more discrete GPUs and one extra audio controller for an eventual HDMI port.

You can also do some really lowlevel stuff, like this one to switch the display output to the discrete GPU if you have an old system with disconnected GPUs that uses a MUX to switch the display output:

$ sudo echo MDIS > /sys/kernel/debug/vgaswitcheroo/switch

Selecting the GPU to use when running a program from the desktop

If running on Gnome or KDE, any application can be selected to run on the discrete GPU directly from the desktop by right clicking on the icon:

This is supported both in the case of multiple DRI/DRM devices and or a combination with Nvidia proprietary drivers. There is no visible difference between the two.

Both Gnome and KDE feature an extra setting that can be added to desktop menus to prefer the integrated GPU. For example Steam provides this by default:

$ cat /usr/share/applications/steam.desktop | grep -i GPU
PrefersNonDefaultGPU=true
X-KDE-RunOnDiscreteGpu=true

Applications bearing those entries receive the opposite treatment, they run by default on the discrete GPU and by right clicking we can select the internal GPU:

Selecting the GPU to use with switcherooctl

The system comes with a userspace utility to manipulate the GPUs and that also prints the variables you can use to address a specific GPU. Prime / VGA Swicheroo case:

$ switcherooctl list
Device: 0
  Name:        Intel Corporation Raptor Lake-P [Iris Xe Graphics]
  Default:     yes
  Environment: DRI_PRIME=pci-0000_00_02_0

Device: 1
  Name:        NVIDIA Corporation AD104GLM [RTX 3500 Ada Generation Laptop GPU]
  Default:     no
  Environment: DRI_PRIME=pci-0000_01_00_0

The DRI_PRIME variable is never set by default and it’s assumed to be at 0 (so main integrated GPU in most cases) if nothing else sets it.

In the case of Nvidia proprietary drivers, the tool is smart enough to set the appropriate Nvidia variables to achieve the same result:

$ switcherooctl list
Device: 0
  Name:        Intel Corporation Raptor Lake-P [Iris Xe Graphics]
  Default:     yes
  Environment: DRI_PRIME=pci-0000_00_02_0

Device: 1
  Name:        NVIDIA Corporation AD104GLM [RTX 3500 Ada Generation Laptop GPU]
  Default:     no
  Environment: __GLX_VENDOR_LIBRARY_NAME=nvidia __NV_PRIME_RENDER_OFFLOAD=1 __VK_LAYER_NV_optimus=NVIDIA_only

Think of switcherooctl as a replacement for setting up variables. For example, if your system has 4 GPUs and you want to target the 4th GPU, these commands are equivalent:

$ switcherooctl launch -g 3 <command>
$ DRI_PRIME=3 <command>
$ DRI_PRIME=pci-0000_03_00_0 <command>

Selecting the GPU to use with environment variables

OpenGL context

OpenGL came in before this multiple GPU – multiple GPU vendor thing existed, so by default, the first used GPU is the one used to run OpenGL applications in the main display and leave the second GPU off:

$ glxinfo -B | grep string
OpenGL vendor string: Intel
OpenGL renderer string: Mesa Intel(R) Graphics (RPL-P)
OpenGL core profile version string: 4.6 (Core Profile) Mesa 24.0.8
OpenGL core profile shading language version string: 4.60
OpenGL version string: 4.6 (Compatibility Profile) Mesa 24.0.8
OpenGL shading language version string: 4.60
OpenGL ES profile version string: OpenGL ES 3.2 Mesa 24.0.8
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
suspended

In the case of the Intel + Nvidia proprietary drivers, we can use the Nvidia variables consumed by the proprietary driver to select the GPU and let the system power on the extra GPU:

$ __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo -B | grep string
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA RTX 3500 Ada Generation Laptop GPU/PCIe/SSE2
OpenGL core profile version string: 4.6.0 NVIDIA 555.42.02
OpenGL core profile shading language version string: 4.60 NVIDIA
OpenGL version string: 4.6.0 NVIDIA 555.42.02
OpenGL shading language version string: 4.60 NVIDIA
OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 555.42.02
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
active

If we are using open source drivers for both Intel + Nvidia (Nouveau), we can use the Mesa DRI variables to select the GPU:

$ DRI_PRIME=1 glxinfo -B | grep string
OpenGL vendor string: Mesa
OpenGL renderer string: NV194
OpenGL core profile version string: 4.3 (Core Profile) Mesa 24.0.8
OpenGL core profile shading language version string: 4.30
OpenGL version string: 4.3 (Compatibility Profile) Mesa 24.0.8
OpenGL shading language version string: 4.30
OpenGL ES profile version string: OpenGL ES 3.2 Mesa 24.0.8
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20

We can now use both ways of checking the power state of the GPUs via the PCI devices or with VGA Switcheroo:

$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
active
$ sudo cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS-Audio: :DynOff:0000:01:00.1
2:DIS: :DynPwr:0000:01:00.0

VA-API (Video Acceleration API) context

$ vainfo | grep version
libva info: VA-API version 1.21.0
libva info: Trying to open /usr/lib64/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_21
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.21 (libva 2.21.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 24.2.3 (Full Feature Build)
$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
suspended

VA-API has its own set of variables for selecting which driver to use in the case of Intel + Nvidia proprietary drivers:

$ LIBVA_DRIVER_NAME=nvidia vainfo | grep version
libva info: VA-API version 1.21.0
libva info: User environment variable requested driver 'nvidia'
libva info: Trying to open /usr/lib64/dri/nvidia_drv_video.so
libva info: Found init function __vaDriverInit_1_0
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.21 (libva 2.21.0)
vainfo: Driver version: VA-API NVDEC driver [direct backend]
$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
active

Again, with the open source stack, also the DRI variable or switcherooctl are required:

$ DRI_PRIME=1 LIBVA_DRIVER_NAME=nouveau vainfo | grep version
libva info: VA-API version 1.21.0
libva info: User environment variable requested driver 'nouveau'
libva info: Trying to open /usr/lib64/dri/nouveau_drv_video.so
libva info: Found init function __vaDriverInit_1_21
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.21 (libva 2.21.0)
vainfo: Driver version: Mesa Gallium driver 24.0.8 for NV194
$ cat /sys/bus/pci/devices/0000:{00:02.0,01:00.0}/power/runtime_status
active
active

VDPAU context

VDPAU is pretty much dead, there is no support for Optimus/Prime laptops and no support for Wayland.

Vulkan or EGL context

Vulkan and EGL were thought with this use case in mind and the selection of the GPU to use ties into the extensions, so usually the correct one is already considered by the program using the appropriate API. The program can query a particular extension to get an ordered list of GPUs or with some other mechanism. This is usually performed by the program itself, so there is not really a way to “force” one specific GPU.

For example, vkcube allows us to select the GPU:

$ vkcube --gpu_number 0 --c 20
Selected GPU 0: Intel(R) Graphics (RPL-P), type: IntegratedGpu
$ vkcube --gpu_number 1 --c 20
Selected GPU 1: NVIDIA RTX 3500 Ada Generation Laptop GPU, type: DiscreteGpu

Contrary to the OpenGL context, you can check with the following commands that there is always a list of GPUs to use and never a single GPU information:

$ eglinfo -B
$ __NV_PRIME_RENDER_OFFLOAD=1 eglinfo -B
$ vulkaninfo --summary

There are some variables or programs that can be used to influence the extensions used for querying the GPUs, but it’s not really a supported path. The application decides based on the information provided by the drivers and some predefined criteria.

Forcing the usage of X on a specific GPU in a Wayland context

Everything described so far is applied as well to Wayland. On top of that, Xwayland is started whenever an application that does not support Wayland yet is started in a Wayland desktop.

If you want to force the use of Xwayland for a program that supports both Wayland and X, then you just need to set an additional variable.

For example, depending on the context (DRI, Nvidia, etc), these are all equivalent:

$ XDG_SESSION_TYPE=X11 __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia glxgears
$ XDG_SESSION_TYPE=X11 DRI_PRIME=1 glxgears
$ XDG_SESSION_TYPE=X11 switcherooctl launch -g 1 glxgears

CUDA with unsupported GCC versions

When running the CUDA stack on a recent Fedora distribution, you’re very likely to hit the compatibility issue with the current GCC release not being yet supported by NVCC. This is quite easy to address, but not many people seem to know it.

At the moment of writing, CUDA 12.4 has GCC 13.x support, while Fedora 40 ships with GCC 14.

Since a few years I’ve been shipping a cuda-gcc package which appears as a drop in replacement for NVCC. It can be installed along with CUDA and the drivers from the Nvidia or multimedia repository or from a Fedora COPR if you are running the upstream CUDA packages provided by Nvidia.

This GCC version is hidden from the main path and is explicitly used by NVCC when compiling something. Installing the cuda-gcc-c++ package creates profile entries in /etc/profile.d that just do this:

# dnf -y install cuda-gcc-c++
$ cat /etc/profile.d/cuda-gcc.sh 
export NVCC_PREPEND_FLAGS='-ccbin /usr/bin/cuda'

Logout/login or reload your profile and you’re good to go.

This way, every time you invoke NVCC you are not using the system compiler but the one provided by the cuda-gcc package.

On a Red Hat Enterprise Linux based distribution you can achieve the same result by installting the development toolset of your choice and activating the environment for it. This is usually not an issue as NVCC is officially supported on those distributions.

Nvidia proprietary and open source kernel modules

With the latest bunch of updates to the Nvidia and Multimedia repositories, I’ve added the ability to switch to the two implementations of the kernel modules currently available in the Nvidia driver for Linux.

Since almost a year, the Nvidia driver ships with two different implementations of the kernel modules, one proprietary and one open source. The open source one as of drivers 545.x is now considered beta quality also for the workstations, so it seems a good moment to start shipping it.

The open source one is supposed to be the only one that will be kept in the future, but at the moment both are available and both differ in terms of functionality. You can read about the main differences in terms of functionality and what chips they support in the official documentation.

I did not want to introduce another variation of the kernel modules beside akmods, kABI and DKMS, this would have created even more confusion and lots of dependencies in the SPEC files for the variations. The new akmod and DKMS packages ship both sources (MIT/GPL and proprietary kernel modules) and allow you to switch between one or the other through a configuration file.

Considering that in the long run only the open source variant will remain, I wanted to make this as transparent as possible for the users. Basically, if you don’t care and just want something that works, nothing has changed for you.

The two sources get referenced as they are referenced inside the Nvidia run file, namely “kernel” for the original proprietary kernel modules and “kernel-open” for the new open source variation.

The following instructions show you how to switch between one implementation or the other.

DKMS

Check which version you have installed:

# modinfo -l nvidia
NVIDIA

Change the type of modules you want to use and trigger a rebuild and a reinstall:

# sed -i -e 's/kernel$/kernel-open/g' /etc/nvidia/kernel.conf
# dkms build -m nvidia/545.29.02 --force
# dkms install -m nvidia/545.29.02 --force

Now check again the license and you should see that it has changed to MIT/GPL:

# modinfo -l nvidia
Dual MIT/GPL
# reboot

To switch back, change the configuration again and then trigger the same process for rebuilding installing:

# sed -i -e 's/kernel-open$/kernel/g' /etc/nvidia/kernel.conf
# dkms build -m nvidia/545.29.02 --force
# dkms install -m nvidia/545.29.02 --force
# reboot

akmods

Check which version you have installed:

# modinfo -l nvidia
NVIDIA

Change the type of modules you want to use and trigger a rebuild and a reinstall:

# sed -i -e 's/kernel$/kernel-open/g' /etc/nvidia/kernel.conf
# akmods --rebuild

Now check again the license and you should see that it has changed to MIT/GPL:

# modinfo -l nvidia
Dual MIT/GPL
# reboot

To switch back, change the configuration again and then trigger the same process for rebuilding installing:

# sed -i -e 's/kernel-open$/kernel/g' /etc/nvidia/kernel.conf
# akmods --rebuild
# reboot

Wayland/modesetting on Nvidia

With the latest Nvidia drivers it seems that modesetting and Wayland work fine for Gnome and GDM.

Console text is still a normal console, but upon boot you get the native screen resolution in Plymouth and then you can login under both X.org and Wayland sessions.

Screenshot-from-2020-07-11-08-06-56

How to test? Make sure that you have the following line enabled for the nvidia-drm module:

# cat /usr/lib/modprobe.d/nvidia.conf | grep drm
options nvidia-drm modeset=1

And then make sure to comment out the following line in the udev rules supplied by GDM:

# cat /usr/lib/udev/rules.d/61-gdm.rules | grep -i nvidia
# disable Wayland when using the proprietary nvidia driver
#DRIVER=="nvidia", RUN+="/usr/libexec/gdm-disable-wayland"

Then reboot, and you will login with a Wayland session by default:

# cat /sys/module/nvidia_drm/parameters/modeset 
Y
# cat /sys/module/nvidia_drm/version 
450.57
$ lsmod | grep nvidia
nvidia_drm             57344  4
nvidia_modeset       1187840  3 nvidia_drm
nvidia_uvm           1130496  0
nvidia              19726336  208 nvidia_uvm,nvidia_modeset
drm_kms_helper        249856  1 nvidia_drm
drm                   618496  7 drm_kms_helper,nvidia_drm
$ env | grep XDG_SESSION_TYPE
XDG_SESSION_TYPE=wayland
$ lspci | grep -i vga
01:00.0 VGA compatible controller: NVIDIA Corporation GP106 [GeForce GTX 1060 6GB] (rev a1)

HandBrake with NVENC support

After switching from libav to FFmpeg, the HandBrake developers quickly added NVENC encoder support to HandBrake. You can now select both NVENC for H.264/H.265 encoders in the drop down menu or with the command line interface:

$ HandBrakeCLI --help | grep -A12 "Select video encoder"
   -e, --encoder   Select video encoder:
                               x264
                               x264_10bit
                               nvenc_h264
                               x265
                               x265_10bit
                               x265_12bit
                               nvenc_h265
                               mpeg4
                               mpeg2
                               VP8
                               VP9
                               theora

With most GPUs I tried, even setting the slowest and costly preset results in the video engine not being fully utilized. Encoding times are cut to ~25%.

Awesome! No more ffmpeg command line black magic. You can now comfortably create your preset in the HandBrake gui and then use HandBrakeCLI through SSH on your awesome Plex Media Server. The build is available for both CentOS/RHEL 7 and Fedora.

HandBrake FFmpeg, no more Nvidia 32 bit drivers

HandBrake has been updated again to track the master branch, as it now uses FFMpeg 4 and no longer libAV 12. This could probably lead to other improvements, like NVENC/CUDA support, more formats, etc.

Starting with the Nvidia drivers version 396.24 there will be no more 32 bit support, the driver will be 64 bit only. The 32 bit libraries are still included, so Steam and other applications will keep on being supported.

In a few days, the updated drivers will be pushed in the Fedora repositories, and at the same time I will also remove the i386 folder from the repositories. Some i386 packages will still be provided in the x86_64 folder, as it is now for Fedora 28 and CentOS/RHEL 7. The packages that will be kept, are mostly multilib library packages.

The same will happen to CentOS/EPEL 6 at the moment a new 64 bit only driver series will be nominated as “Long Lived”.

Also the Spotify repository has already no more i386 support, upstream stopped providing updated clients. Judging from the web server logs, there seems to be almost no one using an i686 Fedora in conjunction with the repositories hosted here.