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