1# GPU acceleration {#sec-gpu-accel} 2 3NixOS provides various APIs that benefit from GPU hardware acceleration, 4such as VA-API and VDPAU for video playback; OpenGL and Vulkan for 3D 5graphics; and OpenCL for general-purpose computing. This chapter 6describes how to set up GPU hardware acceleration (as far as this is not 7done automatically) and how to verify that hardware acceleration is 8indeed used. 9 10Most of the aforementioned APIs are agnostic with regards to which 11display server is used. Consequently, these instructions should apply 12both to the X Window System and Wayland compositors. 13 14## OpenCL {#sec-gpu-accel-opencl} 15 16[OpenCL](https://en.wikipedia.org/wiki/OpenCL) is a general compute API. 17It is used by various applications such as Blender and Darktable to 18accelerate certain operations. 19 20OpenCL applications load drivers through the *Installable Client Driver* 21(ICD) mechanism. In this mechanism, an ICD file specifies the path to 22the OpenCL driver for a particular GPU family. In NixOS, there are two 23ways to make ICD files visible to the ICD loader. The first is through 24the `OCL_ICD_VENDORS` environment variable. This variable can contain a 25directory which is scanned by the ICL loader for ICD files. For example: 26 27```ShellSession 28$ export \ 29 OCL_ICD_VENDORS=`nix-build '<nixpkgs>' --no-out-link -A rocmPackages.clr.icd`/etc/OpenCL/vendors/ 30``` 31 32The second mechanism is to add the OpenCL driver package to 33[](#opt-hardware.graphics.extraPackages). 34This links the ICD file under `/run/opengl-driver`, where it will be visible 35to the ICD loader. 36 37The proper installation of OpenCL drivers can be verified through the 38`clinfo` command of the clinfo package. This command will report the 39number of hardware devices that is found and give detailed information 40for each device: 41 42```ShellSession 43$ clinfo | head -n3 44Number of platforms 1 45Platform Name AMD Accelerated Parallel Processing 46Platform Vendor Advanced Micro Devices, Inc. 47``` 48 49### AMD {#sec-gpu-accel-opencl-amd} 50 51Modern AMD [Graphics Core 52Next](https://en.wikipedia.org/wiki/Graphics_Core_Next) (GCN) GPUs are 53supported through the rocmPackages.clr.icd package. Adding this package to 54[](#opt-hardware.graphics.extraPackages) 55enables OpenCL support: 56 57```nix 58{ 59 hardware.graphics.extraPackages = [ 60 rocmPackages.clr.icd 61 ]; 62} 63``` 64 65### Intel {#sec-gpu-accel-opencl-intel} 66 67[Intel Gen12 and later GPUs](https://en.wikipedia.org/wiki/List_of_Intel_graphics_processing_units#Gen12) 68are supported by the Intel NEO OpenCL runtime that is provided by the `intel-compute-runtime` package. 69The previous generations (8,9 and 11), have been moved to the `intel-compute-runtime-legacy1` package. 70The proprietary Intel OpenCL runtime, in the `intel-ocl` package, is an alternative for Gen7 GPUs. 71 72Both `intel-compute-runtime` packages, as well as the `intel-ocl` package can be added to 73[](#opt-hardware.graphics.extraPackages) 74to enable OpenCL support. For example, for Gen12 and later GPUs, the following 75configuration can be used: 76 77```nix 78{ 79 hardware.graphics.extraPackages = [ 80 intel-compute-runtime 81 ]; 82} 83``` 84 85## Vulkan {#sec-gpu-accel-vulkan} 86 87[Vulkan](https://en.wikipedia.org/wiki/Vulkan_(API)) is a graphics and 88compute API for GPUs. It is used directly by games or indirectly though 89compatibility layers like 90[DXVK](https://github.com/doitsujin/dxvk/wiki). 91 92By default, if [](#opt-hardware.graphics.enable) 93is enabled, Mesa is installed and provides Vulkan for supported hardware. 94 95Similar to OpenCL, Vulkan drivers are loaded through the *Installable 96Client Driver* (ICD) mechanism. ICD files for Vulkan are JSON files that 97specify the path to the driver library and the supported Vulkan version. 98All successfully loaded drivers are exposed to the application as 99different GPUs. In NixOS, there are two ways to make ICD files visible 100to Vulkan applications: an environment variable and a module option. 101 102The first option is through the `VK_ICD_FILENAMES` environment variable. 103This variable can contain multiple JSON files, separated by `:`. For 104example: 105 106```ShellSession 107$ export \ 108 VK_ICD_FILENAMES=`nix-build '<nixpkgs>' --no-out-link -A amdvlk`/share/vulkan/icd.d/amd_icd64.json 109``` 110 111The second mechanism is to add the Vulkan driver package to 112[](#opt-hardware.graphics.extraPackages). 113This links the ICD file under `/run/opengl-driver`, where it will be 114visible to the ICD loader. 115 116The proper installation of Vulkan drivers can be verified through the 117`vulkaninfo` command of the vulkan-tools package. This command will 118report the hardware devices and drivers found, in this example output 119amdvlk and radv: 120 121```ShellSession 122$ vulkaninfo | grep GPU 123 GPU id : 0 (Unknown AMD GPU) 124 GPU id : 1 (AMD RADV NAVI10 (LLVM 9.0.1)) 125 ... 126GPU0: 127 deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU 128 deviceName = Unknown AMD GPU 129GPU1: 130 deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU 131``` 132 133A simple graphical application that uses Vulkan is `vkcube` from the 134vulkan-tools package. 135 136### AMD {#sec-gpu-accel-vulkan-amd} 137 138Modern AMD [Graphics Core 139Next](https://en.wikipedia.org/wiki/Graphics_Core_Next) (GCN) GPUs are 140supported through either radv, which is part of mesa, or the amdvlk 141package. Adding the amdvlk package to 142[](#opt-hardware.graphics.extraPackages) 143makes amdvlk the default driver and hides radv and lavapipe from the device list. 144A specific driver can be forced as follows: 145 146```nix 147{ 148 hardware.graphics.extraPackages = [ 149 pkgs.amdvlk 150 ]; 151 152 # To enable Vulkan support for 32-bit applications, also add: 153 hardware.graphics.extraPackages32 = [ 154 pkgs.driversi686Linux.amdvlk 155 ]; 156 157 # Force radv 158 environment.variables.AMD_VULKAN_ICD = "RADV"; 159 # Or 160 environment.variables.VK_ICD_FILENAMES = 161 "/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json"; 162} 163``` 164 165## VA-API {#sec-gpu-accel-va-api} 166 167[VA-API (Video Acceleration API)](https://www.intel.com/content/www/us/en/developer/articles/technical/linuxmedia-vaapi.html) 168is an open-source library and API specification, which provides access to 169graphics hardware acceleration capabilities for video processing. 170 171VA-API drivers are loaded by `libva`. The version in nixpkgs is built to search 172the opengl driver path, so drivers can be installed in 173[](#opt-hardware.graphics.extraPackages). 174 175VA-API can be tested using: 176 177```ShellSession 178$ nix-shell -p libva-utils --run vainfo 179``` 180 181### Intel {#sec-gpu-accel-va-api-intel} 182 183Modern Intel GPUs use the iHD driver, which can be installed with: 184 185```nix 186{ 187 hardware.graphics.extraPackages = [ 188 intel-media-driver 189 ]; 190} 191``` 192 193Older Intel GPUs use the i965 driver, which can be installed with: 194 195```nix 196{ 197 hardware.graphics.extraPackages = [ 198 intel-vaapi-driver 199 ]; 200} 201``` 202 203## Common issues {#sec-gpu-accel-common-issues} 204 205### User permissions {#sec-gpu-accel-common-issues-permissions} 206 207Except where noted explicitly, it should not be necessary to adjust user 208permissions to use these acceleration APIs. In the default 209configuration, GPU devices have world-read/write permissions 210(`/dev/dri/renderD*`) or are tagged as `uaccess` (`/dev/dri/card*`). The 211access control lists of devices with the `uaccess` tag will be updated 212automatically when a user logs in through `systemd-logind`. For example, 213if the user *alice* is logged in, the access control list should look as 214follows: 215 216```ShellSession 217$ getfacl /dev/dri/card0 218# file: dev/dri/card0 219# owner: root 220# group: video 221user::rw- 222user:alice:rw- 223group::rw- 224mask::rw- 225other::--- 226``` 227 228If you disabled (this functionality of) `systemd-logind`, you may need 229to add the user to the `video` group and log in again. 230 231### Mixing different versions of nixpkgs {#sec-gpu-accel-common-issues-mixing-nixpkgs} 232 233The *Installable Client Driver* (ICD) mechanism used by OpenCL and 234Vulkan loads runtimes into its address space using `dlopen`. Mixing an 235ICD loader mechanism and runtimes from different version of nixpkgs may 236not work. For example, if the ICD loader uses an older version of glibc 237than the runtime, the runtime may not be loadable due to missing 238symbols. Unfortunately, the loader will generally be quiet about such 239issues. 240 241If you suspect that you are running into library version mismatches 242between an ICL loader and a runtime, you could run an application with 243the `LD_DEBUG` variable set to get more diagnostic information. For 244example, OpenCL can be tested with `LD_DEBUG=files clinfo`, which should 245report missing symbols.