PRIME
PRIME 是一种用于管理最新一些台式机和笔记本电脑上的混合图形的技术(NVIDIA 的 Optimus,Radeon 的 AMD 动态可切换图形)。 PRIME GPU 分载(offloading)和反向 PRIME(reverse PRIME)是在 Linux 内核中支持无复用混合显示的尝试。
安装[编辑 | 编辑源代码]
开源驱动程序[编辑 | 编辑源代码]
安装开源图形驱动程序需要先删除所有闭源图形驱动程序并将其替换为等效的开源图形驱动程序:
然后重新启动并检查系统加载的图形驱动程序列表:
$ xrandr --listproviders
Providers: number : 2 Provider 0: id: 0x7d cap: 0xb, Source Output, Sink Output, Sink Offload crtcs: 3 outputs: 4 associated providers: 1 name:Intel Provider 1: id: 0x56 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 6 outputs: 1 associated providers: 1 name:radeon
我们可以看到有两块显卡:Intel的集成显卡(id 0x7d)和 Radeon 的独立卡(id 0x56),后者应该被用于 GPU 密集型应用。
默认情况下系统会始终使用 Intel 卡:
$ glxinfo | grep "OpenGL renderer"
OpenGL renderer string: Mesa DRI Intel(R) Ivybridge Mobile
为了使用独立显卡(此处以radeon为例),需要先将集成显卡定义为offload provider,因为当前连接到显示器的是集成显卡:
$ xrandr --setprovideroffloadsink 0x56 0x7d
现在你可以在对显卡要求高的程序(如游戏,3D建模工具等等)中使用独立显卡了:
$ DRI_PRIME=1 glxinfo | grep "OpenGL renderer"
OpenGL renderer string: Gallium 0.4 on AMD TURKS
"HAINAN @ pci:0000:03:00.0"
,而不是 radeon
. 在这种情况下在接下来的命令中应该使用 "HAINAN @ pci:0000:03:00.0"
作为显示提供程序。闭源驱动程序[编辑 | 编辑源代码]
要让 PRIME 在专有驱动程序上运行,过程几乎一样。按照下列文章安装驱动程序:
- AMD 显卡参考 AMDGPU PRO 来安装驱动程序.
- 英伟达显卡参考 NVIDIA 来安装驱动程序.
安装驱动程序后,请不要重启系统或 Xorg。在重新配置之前,由于系统配置不一样,可能会导致 Xorg 无法运行。
按照指定用例部分的说明进行操作。理论上不需要卸载开源驱动程序即可正常运行,但也有可能需要卸载,以防止混乱和未来潜在的问题。
其他程序仍然会使用更节能的集成显卡。每次X11重启都必须再运行一次 xrandr --setprovideroffloadsink 0x56 0x7d
; 你可以写一个脚本并且在启动桌面环境时自动运行(或者将脚本放在 /etc/X11/xinit/xinitrc.d/
目录下).
PRIME GPU 分载[编辑 | 编辑源代码]
有时候用户想在更强大的卡上呈现应用程序并将结果发送到连接了显示器的卡。
命令 xrandr --setprovideroffloadsink provider sink
可用于让做渲染工作的分载提供程序(offload provider)将其输出发送到接收端(sink)提供程序(也就是连接了显示器的提供程序)。 提供程序和接收端标识符可以是数字(0x7d、0x56)或区分大小写的名称(Intel、radeon)。
- 当使用来自官方存储库的大多数默认 Xorg DDX(
xf86-video-*
或内置模式设置驱动程序时,不再需要此设置,因为它们默认启用 DRI3,因此会自动的这样安排配置。不过,再次显式设置它们一次也不会有什么害处。 - 闭源驱动程序不支持 GPU 分载(不过在 NVIDIA 驱动程序上,情况有所变化,有关详细信息,请参见下面的 #PRIME 渲染分载)。
样例:
$ xrandr --setprovideroffloadsink radeon Intel
命令中的提供程序也可以用序号代替名字:
$ xrandr --setprovideroffloadsink 1 0
对于开源程序 - PRIME[编辑 | 编辑源代码]
要将独立显卡用于最需要它的应用程序(例如游戏、3D 建模器...),要在程序的启动命令前面加上环境变量 DRI_PRIME=1
:
$ DRI_PRIME=1 glxinfo | grep "OpenGL renderer"
OpenGL renderer string: Gallium 0.4 on AMD TURKS
其他应用程序仍将使用功耗较低的集成显卡。一旦 X 服务器重新启动,这些设置就会丢失,可能需要制作一个脚本并在桌面环境启动时自动运行(或者,将其放在 /etc/X11/xinit/xinitrc.d/
目录下面). 不过,这样可能会缩短电池寿命并增加热量。
更多信息可以参考 Gentoo:AMDGPU#Test, if a discrete graphics card is in use。
PRIME 渲染分载[编辑 | 编辑源代码]
NVIDIA 驱动程序从版本 435.17 开始支持这个方法。iGPU 驱动程序 xf86-video-amdgpu包 (450.57) 和 xf86-video-intel包 (455.38) 官方支持模式设置(modesetting)。
要在 NVIDIA 显卡上运行程序,您可以使用 nvidia-prime包 软件包提供的 prime-run
脚本:
$ prime-run glxinfo | grep "OpenGL renderer" $ prime-run vulkaninfo
PCI-Express Runtime D3 (RTD3) 电源管理[编辑 | 编辑源代码]
开源驱动程序[编辑 | 编辑源代码]
在不和 PRIME 分载或反向 PRIME 一起使用的时候,内核 PCI 电源管理就会关闭 GPU。
内核级显示模式设置、xf86-video-amdgpu包、xf86-video-intel包、xf86-video-nouveau包 驱动程序都支持这个功能。
以下命令可用于检查每个 GPU 的当前电源状态:
$ cat /sys/class/drm/card*/device/power_state
NVIDIA[编辑 | 编辑源代码]
对于在 Intel Coffee Lake 或更高版本 CPU 以及某些 Ryzen CPU(如 5800H)平台上运行的图灵显卡,可以在不使用的时候完全关闭 GPU。
需要以下 udev 规则:
/etc/udev/rules.d/80-nvidia-pm.rules
# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto" ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto" # Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on" ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"
同时设置以下内核参数#设置内核模块选项:
/etc/modprobe.d/nvidia-pm.conf
options nvidia "NVreg_DynamicPowerManagement=0x02"
我们还需要启用nvidia-persistenced.service
服务以避免内核在 NVIDIA 设备资源不再使用时清空设备状态。
配置应用程序使用 GPU 渲染[编辑 | 编辑源代码]
即使没有启用动态电源管理,应用程序的渲染分载也要启用[1]。
要在运行应用程序时渲染分载到 NVIDIA GPU 并启用动态电源管理,要添加以下内容。[2]
__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia command
在 Steam 游戏上使用时, 启动命令行选项可以设置为:
__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia %command%
GNOME 集成[编辑 | 编辑源代码]
使用 GNOME 集成需要安装 switcheroo-controlAUR和启用 switcheroo-control.service
。
GNOME将尊重桌面项中的PrefersNonDefaultGPU
属性。或者也可以通过右键单击图标并选择Launch using Discrete Graphics Card
来使用GPU 启动应用程序。
故障排除[编辑 | 编辑源代码]
如果安装了bumblebee包,则需要将其删除,因为它将 nvida_drm
列入黑名单,该驱动程序由 X 服务器加载 NVIDIA 驱动程序来实现渲染分载。
PRIME 同步[编辑 | 编辑源代码]
当使用PRIME时,主GPU渲染屏幕内容/应用程序,并将其传递给备用GPU进行显示。参考an NVIDIA thread,"传统的 vsync 可以将应用程序的呈现与系统内存中的副本同步,但需要一种额外的机制来将系统内存中的副本与 iGPU 的显示引擎同步。与传统的垂直同步不同,这种机制必须涉及到 dGPU 和 iGPU 驱动之间的通信。"
这种同步是使用 PRIME 同步实现的。要检查显示系统是否启用了 PRIME 同步,可以查看xrandr --prop
的输出。
使用下面的命令启用(PRIME 同步):
$ xrandr --output <output-name> --set "PRIME Synchronization" 1
- 在 NVIDIA 驱动程序上使用 PRIME 同步的先决条件是启用 NVIDIA#DRM内核级显示模式设置。
- PRIME 同步无法在 AMDGPU DDX 驱动上使用(xf86-video-amdgpu包)。
特定于 Wayland 的配置[编辑 | 编辑源代码]
Wayland需要的配置比Xorg少。KDE 的 KWin 和 GNOME 的 Mutter (Issue 17 和 Merge request 1562) 似乎也实现了 GPU 热插拔的初步支持。
通过设置DRI_PRIME=
环境变量来使用独立显卡。下面的示例假设一个系统使用 Intel 集成卡、NVIDIA 内部 GPU 和 AMD 外部 GPU。
使用集成英特尔芯片不需要修改,因为它已经是默认的:
glxinfo | grep 'OpenGL renderer'
OpenGL renderer string: Mesa Intel(R) Xe Graphics (TGL GT2)
使用开源驱动程序的 AMD 显卡:
DRI_PRIME=pci-0000_06_00_0 glxinfo | grep 'OpenGL renderer'
OpenGL renderer string: AMD Radeon RX 5700 XT (navi10, LLVM 14.0.6, DRM 3.46, 5.18.17-hardened1-1-hardened)
使用专有驱动的 NVIDIA 显卡:
DRI_PRIME=pci-0000_01_00_0 __VK_LAYER_NV_optimus=NVIDIA_only __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo | grep 'OpenGL renderer string'
OpenGL renderer string: NVIDIA GeForce RTX 3050 Ti Laptop GPU/PCIe/SSE2
Wayland 可以在同一台机器上同时使用多个GPU。
参见 mesa3d 的 PRIME 文档: https://docs.mesa3d.org/envvars.html
反向 PRIME[编辑 | 编辑源代码]
- 470 beta 之前的 NVIDIA 驱动程序上的 AMDGPU + NVIDIA 不支持反向 PRIME。更多详细信息,请参考 [3]。旧版本的替代方法是使用 NVIDIA 作为主卡,如#Discrete card as primary GPU小节所述。
- 当前仅启用外部显示器时,将只能获得 1 FPS。 更多信息参考[4]。
如果第二个 GPU 的输出无法被主 GPU 访问,可以使用反向 PRIME来使用它们。这将涉及使用主 GPU 渲染图像,然后将它们传递给第二个 GPU。
它可能开箱即用,但如果不能,则需要按照以下步骤进行配置。
配置[编辑 | 编辑源代码]
首先, 识别集成 GPU 的总线 ID(BusID)
lspci | grep VGA
00:02.0 VGA compatible controller: Intel Corporation UHD Graphics 630 (Mobile) 01:00.0 VGA compatible controller: NVIDIA Corporation TU117M [GeForce GTX 1650 Mobile / Max-Q] (rev a1)
在上面的示例中,Intel 卡的总线id是 00:02.0 ,翻译到 pci 总线上为 PCI:0:2:0。
如下设置您的 xorg.conf
并调整 BusID。
/etc/X11/xorg.conf
Section "ServerLayout" Identifier "layout" Screen 0 "intel" Inactive "nvidia" Option "AllowNVIDIAGPUScreens" EndSection Section "Device" Identifier "nvidia" Driver "nvidia" EndSection Section "Screen" Identifier "nvidia" Device "nvidia" EndSection Section "Device" Identifier "intel" Driver "modesetting" BusID "PCI:0:2:0" EndSection Section "Screen" Identifier "intel" Device "intel" EndSection
命令 xrandr --setprovideroutputsource provider source
将提供程序设置为源的输出。 例如:
$ xrandr --setprovideroutputsource radeon Intel
完成后,独立显卡的输出应该在 xrandr 中可用,可以执行以下操作:
$ xrandr --output HDMI-1 --auto --above LVDS1
来配置内部和外部显示器。
问题[编辑 | 编辑源代码]
如果重启后你只有一个提供程序,可能是因为当 Xorg 启动时nvidia
模块还没加载。您需要启用早期模块加载。 有关详细信息,请参阅内核级显示模式设置#KMS 早启动。
用户场景[编辑 | 编辑源代码]
将独立显卡作为主 GPU[编辑 | 编辑源代码]
想象一下以下场景:LVDS1(内部笔记本电脑屏幕)和 VGA 输出都只能通过集成的英特尔 GPU 访问。 HDMI 和 DisplayPort 输出连接到独立的 NVIDIA 卡。 如上所述,可以通过使用 #反向 PRIME 技术来使用所有四个输出。 然而,性能可能会很差,因为所有输出的所有渲染都是由集成的英特尔卡完成的。 为了改善这种情况,可以通过独立的 NVIDIA 卡进行渲染,然后将 LVDS1 和 VGA 输出的帧缓冲区复制到英特尔卡。
创建以下 Xorg 配置:
/etc/X11/xorg.conf.d/10-gpu.conf
Section "ServerLayout" Identifier "layout" Screen 0 "nouveau" Inactive "intel" EndSection Section "Device" Identifier "nouveau" Driver "nouveau" BusID "PCI:x:x:x" # Sample: "PCI:1:0:0" EndSection Section "Screen" Identifier "nouveau" Device "nouveau" EndSection Section "Device" Identifier "intel" Driver "intel" BusID "PCI:x:x:x" # Sample: "PCI:0:2:0" EndSection Section "Screen" Identifier "intel" Device "intel" EndSection
重启 Xorg。现在应该使用的是NVIDIA 独立显卡。 HDMI 和 Display Port 输出是主要输出。 LVDS1 和 VGA 输出关闭。 要启用它们,可以运行:
$ xrandr --setprovideroutputsource Intel nouveau
集成显卡的输出现在应该在 xrandr 中可用。
故障排查[编辑 | 编辑源代码]
XRandR 只识别出一个显卡[编辑 | 编辑源代码]
删除或者移走 /etc/X11/xorg.conf 以及 /etc/X11/xorg.conf.d/ 目录下任何与GPU有关的文件
当程序使用独立显卡渲染时,程序黑屏[编辑 | 编辑源代码]
某些情况下PRIME的正常工作需要一个混合窗口管理器。如果你使用的窗口管理器不进行混合渲染,你可以在其基础上使用xcompmgr。
在基于 GL 的渲染合成器下黑屏[编辑 | 编辑源代码]
目前基于 GL 的渲染合成器和 PRIME 分载渲染还有一些问题。当基于 Xrender 的渲染合成器(xcompmgr,xfwm,compton的默认后端,cairo-compmgr和一些其他的合成器)可以正常工作,基于 GL 的渲染合成器(Mutter/muffin, Compiz, 使用 GLX 后端的 compton , Kwin 的 OpenGL 后端,等)一开始会显示黑屏,就好像没有运行渲染合成器一样。虽然也可以通过调整使用渲染分载的程序窗口大小来强制显示图像,但这并不是一个实用的解决方案,因为它不适用于全屏的 Wine 应用程序。这意味着像 GNOME3 和 Cinnamon 这样的桌面环境在使用 PRIME 分载时存在问题。
此外,如果使用的是英特尔 IGP,也许可以通过把 IGP 当作 UXA 而不是 SNA 运行来修复 GL合成问题,然而这可能会导致渲染分载进程出现问题(例如,xrandr --listproviders
可能不会打印独立 GPU)。