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 way to do this is to add the Vulkan driver package to
95[](#opt-hardware.graphics.extraPackages).
96This links the ICD file under `/run/opengl-driver`, where it will be
97visible to the ICD loader.
98
99The proper installation of Vulkan drivers can be verified through the
100`vulkaninfo` command of the vulkan-tools package. This command will
101report the hardware devices and drivers found, in this example output
102amdvlk and radv:
103
104```ShellSession
105$ vulkaninfo | grep GPU
106 GPU id : 0 (Unknown AMD GPU)
107 GPU id : 1 (AMD RADV NAVI10 (LLVM 9.0.1))
108 ...
109GPU0:
110 deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
111 deviceName = Unknown AMD GPU
112GPU1:
113 deviceType = PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
114```
115
116A simple graphical application that uses Vulkan is `vkcube` from the
117vulkan-tools package.
118
119### AMD {#sec-gpu-accel-vulkan-amd}
120
121Modern AMD [Graphics Core
122Next](https://en.wikipedia.org/wiki/Graphics_Core_Next) (GCN) GPUs are
123supported through the RADV driver, which is part of mesa.
124
125## VA-API {#sec-gpu-accel-va-api}
126
127[VA-API (Video Acceleration API)](https://www.intel.com/content/www/us/en/developer/articles/technical/linuxmedia-vaapi.html)
128is an open-source library and API specification, which provides access to
129graphics hardware acceleration capabilities for video processing.
130
131VA-API drivers are loaded by `libva`. The version in nixpkgs is built to search
132the opengl driver path, so drivers can be installed in
133[](#opt-hardware.graphics.extraPackages).
134
135VA-API can be tested using:
136
137```ShellSession
138$ nix-shell -p libva-utils --run vainfo
139```
140
141### Intel {#sec-gpu-accel-va-api-intel}
142
143Modern Intel GPUs use the iHD driver, which can be installed with:
144
145```nix
146{ hardware.graphics.extraPackages = [ intel-media-driver ]; }
147```
148
149Older Intel GPUs use the i965 driver, which can be installed with:
150
151```nix
152{ hardware.graphics.extraPackages = [ intel-vaapi-driver ]; }
153```
154
155## Common issues {#sec-gpu-accel-common-issues}
156
157### User permissions {#sec-gpu-accel-common-issues-permissions}
158
159Except where noted explicitly, it should not be necessary to adjust user
160permissions to use these acceleration APIs. In the default
161configuration, GPU devices have world-read/write permissions
162(`/dev/dri/renderD*`) or are tagged as `uaccess` (`/dev/dri/card*`). The
163access control lists of devices with the `uaccess` tag will be updated
164automatically when a user logs in through `systemd-logind`. For example,
165if the user *alice* is logged in, the access control list should look as
166follows:
167
168```ShellSession
169$ getfacl /dev/dri/card0
170# file: dev/dri/card0
171# owner: root
172# group: video
173user::rw-
174user:alice:rw-
175group::rw-
176mask::rw-
177other::---
178```
179
180If you disabled (this functionality of) `systemd-logind`, you may need
181to add the user to the `video` group and log in again.
182
183### Mixing different versions of nixpkgs {#sec-gpu-accel-common-issues-mixing-nixpkgs}
184
185The *Installable Client Driver* (ICD) mechanism used by OpenCL and
186Vulkan loads runtimes into its address space using `dlopen`. Mixing an
187ICD loader mechanism and runtimes from different version of nixpkgs may
188not work. For example, if the ICD loader uses an older version of glibc
189than the runtime, the runtime may not be loadable due to missing
190symbols. Unfortunately, the loader will generally be quiet about such
191issues.
192
193If you suspect that you are running into library version mismatches
194between an ICL loader and a runtime, you could run an application with
195the `LD_DEBUG` variable set to get more diagnostic information. For
196example, OpenCL can be tested with `LD_DEBUG=files clinfo`, which should
197report missing symbols.