If you find any mistakes here or anywhere else on my website, email website@CoryHufford.com.
September 30, 2026
On a Linux system with multiple GPUs, which GPU is used for a particular
OpenGL or Vulkan process can be controlled with the DRI_PRIME
environment variable (with some exceptions and caveats), which is documented
here. Since
this is a Mesa feature, this works with all discrete and integrated AMD, Intel,
and NVIDIA GPUs as long as the open source Mesa drivers are being used.
The DRI_PRIME environment variable can take several types of
GPU identifiers; I find the most convenient to be the PCI vendor and device ID,
since that's the only type that's stable across machines and reboots. Note that
PCI device IDs can be ambiguous if there are multiple GPUs of the same model or
two closely related models in the same system; in that case, a different form of
identifier would have to be used for DRI_PRIME. The GPUs present on
a system can be listed with their PCI IDs with
lspci -nn | grep VGA. For example, my current desktop machine with
an AMD Ryzen 7950X (which has an integrated GPU) and an AMD RX 7900 XTX discrete
GPU lists:
03:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 31 [Radeon RX 7900 XT/7900 XTX/7900 GRE/7900M] [1002:744c] (rev c8)
18:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Raphael [1002:164e] (rev c1)
[1002:744c] is the vendor and device ID of the 7900 XTX and
[1002:164e] is the vendor and device ID for the 7950X's integrated
GPU. The PCI ID Repository is a useful
resource for finding or identifying PCI IDs. A selection of discrete and
integrated GPUs and their PCI IDs are shown in Table 1:
| Vendor | Vendor ID | Type | Device(s) | Device ID | Notes |
|---|---|---|---|---|---|
| AMD | 1002 |
Discrete | Navi 31:
|
744c |
- |
Navi 33:
|
7480 |
RX 7700S is the original Framework 16 discrete GPU. | |||
| Integrated |
|
164e |
- | ||
Radeon 780M:
|
15bf |
7840HS and 7940HS are the original Framework 16 CPUs. | |||
| NVIDIA | 10de |
Discrete | RTX 5090 | 2b85 |
- |
| RTX 5080 | 2c02 |
- |
Using vendor ID 1a2b and device ID 3c4d as an
example, the GPU can be specified with DRI_PRIME=1a2b:3c4d!. Note
the trailing exclamation mark - it's often required for Vulkan programs. The
OpenGL driver chooses the GPU on behalf of the program and always respects
DRI_PRIME with or without an exclamation mark. The Vulkan driver,
however, presents programs with a list of GPUs to choose from. Some Vulkan
programs choose the first GPU in the list, others choose based on their own
criteria. Without the exclamation mark, DRI_PRIME causes the
specified GPU to be moved to the beginning of the list, but the program is still
free to choose any GPU from the list. With the exclamation mark, all GPUs are
removed from the list except the specified one, forcing the program to use it.
This GPU sorting/filtering is implemented in a Vulkan layer outside of the
driver itself, so the layer has to be installed for DRI_PRIME to
have any effect on Vulkan programs. The layer is called
libVkLayer_MESA_device_select.so, and is often included with the
normal Mesa Vulkan drivers package (usually called
mesa-vulkan-drivers); Arch Linux is a notable exception, where
it's provided by the vulkan-mesa-implicit-layers package. The
concept of Vulkan layers is briefly described in the Vulkan Loader documentation
here.
To test that GPU selection is working, any graphics-intensive program can be
used to create a GPU load that can be seen in monitoring software like
btop. There are graphics test programs specifically for OpenGL and
Vulkan that can be used for this:
glxgears -fullscreen opens a window that renders a set of
spinning gears. -fullscreen produces a larger (more
noticeable) GPU load. glxgears is provided by the
mesa-utils package in Debian- and Arch-family distributions
and glx-utils in Fedora-family distributions.vkcube --present_mode 0 opens a window that renders a
spinning cube. --present_mode 0 disables frame
synchronization to let the program run at a higher frame rate, producing
a more noticeable GPU load. vkcube is provided by the
vulkan-tools package in most major distributions.