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