PRIME

提供: ArchWiki
2023年4月17日 (月) 21:39時点におけるAshMyzk (トーク | 投稿記録)による版 (ユーザのシナリオ を追加)
ナビゲーションに移動 検索に移動

関連記事

PRIME は最近のデスクトップやノートパソコンで使われているハイブリッドグラフィック (NVIDIA の Optimus や Radeon の AMD Dynamic Switchable Graphics) を管理するためのテクノロジーです。Linux カーネルでマルチプレクサを必要としないハイブリッドグラフィックを実現するものとして PRIME GPU オフロードReverse PRIME が存在します。

目次

インストール

オープンソースドライバ

クローズドソースのグラフィックドライバを削除して、オープンソースのドライバで置き換えてください:

再起動して、使われているグラフィックドライバのリストを確認:

$ 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

2つのグラフィックカードが存在することを確認できます: 内蔵カードの Intel (id 0x7d) とディスクリートカードの Radeon (id 0x56) です。GPU を激しく消費するアプリケーションは後者を使うべきとなります。

デフォルトでは、Intel のカードが常時使用されます:

$ glxinfo | grep "OpenGL renderer"
OpenGL renderer string: Mesa DRI Intel(R) Ivybridge Mobile
ノート: 時々、表示されているプロバイダが radeon ではなく "HAINAN @ pci:0000:03:00.0" になることがあります。この場合、次のコマンドで "HAINAN @ pci:0000:03:00.0" をプロバイダとして使用する必要があります。

クローズドソースドライバー

プロプライエタリなドライバで PRIME を機能させる手順もほとんど同じです。以下の記事に従ってドライバをインストールしてください:

  • AMDGPU PRO: AMD GPU 用ドライバをインストール
  • NVIDIA: NVIDIA GPU 用ドライバをインストール

ドライバをインストールしたすぐ後に Xorg を再起動したり再実行したりしないでください。システム構成によっては設定を変更しないと Xorg が起動できなくなります。

ユースケースに合わせて設定を行ってください。必ずしもオープンソースドライバをアンインストールする必要はありませんが、アンインストールしておいたほうが将来的に問題が発生する可能性を少なくできます。

PRIME GPU オフロード

強力なカードでアプリケーションをレンダリングし、ディスプレイが接続されているカードにその結果を送信することが望ましいでしょう。

コマンド xrandr --setprovideroffloadsink provider sink を使うことで、レンダーオフロードプロバイダからシンクプロバイダ (ディスプレイに接続されているプロバイダ) に出力を送信することが可能です。プロバイダとシンクの識別子は、数字 (0x7d、0x56) あるいは大文字・小文字を区別する名前 (Intel、radeon) で指定することができます。

ノート:
  • 公式リポジトリのほとんどデフォルト Xorg DDX (xf86-video-* や組み込みの modesetting) ドライバでは、以下の設定はもはや必須ではありません。それらのドライバは、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 を参照してください。

DRI_PRIME を Vulkan アプリケーションで機能させるには、vulkan-mesa-layers と、32 ビットアプリケーション用に lib32-vulkan-mesa-layers をインストールする必要があります。

PRIME レンダーオフロード

NVIDIA ドライバは、バージョン 435.17以降、この方法をサポートしています。modesetting (xf86-video-amdgpu (450.57)) と xf86-video-intel (455.38) が iGPU ドライバとして公式にサポートされています。

nvidia-prime によって提供されている prime-run スクリプトを使うことで、NVIDIA カード上でプログラムを実行することができます:

$ prime-run glxinfo | grep "OpenGL renderer"
$ prime-run vulkaninfo

PCI-Express Runtime D3 (RTD3) Power Management

オープンソースドライバ

カーネルの PCI 電源管理は、PRIME オフロードや reverse PRIME が使用されていない時、GPU をオフにします。 この機能は modesetting、xf86-video-amdgpuxf86-video-intelxf86-video-nouveau ドライバによってサポートされています。

以下のコマンドにより、各 GPU の現在の電源状態を確認することができます:

$ cat /sys/class/drm/card*/device/power_state
NVIDIA
ノート: Ampere の場合は、この設定がデフォルトで有効化されているので、一般的に設定は必要ありません。一部の Ampere ユーザは、udev ルールが必要かもしれません。

Intel Coffee Lake 以降の CPU や (5800H などの) 一部の Ryzen CPU と、Turing 世代のカードの組み合わせの場合、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"

あるいは、これら2つの設定ファイルを提供する nvidia-prime-rtd3pmAUR をインストールすることもできます。

また、NVIDIA デバイスのリソースが利用されなくなったときにカーネルがデバイスの状態を破壊することを防ぐために、nvidia-persistenced.service有効化する必要があります。[1]

GPU を使ってレンダリングするようにアプリケーションを設定する

Dynamic Power Management を有効化せずとも、アプリケーションのオフロードレンダリングが必要です。[2]

Dynamic Power Management を有効にして NVIDIA GPU にオフロードしてアプリケーションを実行するには、以下の環境変数を追加してください: [3]

__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-controlインストールし、switcheroo-control.service有効化してください。

GNOME は デスクトップエントリPrefersNonDefaultGPU プロパティに従います。あるいは、アイコンを右クリックし Launch using Discrete Graphics Card を選択することで、アプリケーションを GPU で実行することが可能です。

トラブルシューティング

bumblebee がインストールされている場合、このパッケージは、X サーバがオフロードのために NVIDIA ドライバをロードする際に必要な nvidia_drm ドライバをブラックリストに追加するので、削除する必要があります。

PRIME 同期

PRIME を使用している時、プライマリ GPU がスクリーンのコンテンツおよびアプリケーションをレンダリングし、その結果を表示用のセカンダリ GPU に渡します。とある NVIDIA のスレッドを引用すると、(日本語訳)「従来の垂直同期は、アプリケーションのレンダリングとシステムメモリへのコピーを同期させることができます。しかし、システムメモリへのコピーと iGPU のディスプレイエンジンとを同期させるには、追加のメカニズムが必要になります。そのようなメカニズムは、従来の垂直同期とは異なり、dGPU のドライバと iGPU のドライバ間でコミュニケーションを取る必要があります。」

この同期は、PRIME 同期を使用して達成されます。PRIME 同期は、ディスプレイに対して有効化されます。xrandr --prop の出力を確認してください。

有効化するには、以下を実行してください:

$ xrandr --output <output-name> --set "PRIME Synchronization" 1
ノート:

Wayland 固有の設定

Wayland は Xorg よりも設定が少なくて済みます。また、KDE の KWin や GNOME の Mutter には GPU ホットプラグの予備的サポートも存在するようです (Issue 17マージリクエスト 1562)。

ディスクリートカードを使用するには、DRI_PRIME= 環境変数を (コマンドの) 先頭に追加してください。以下の例では、システムに Intel 統合カード、NVIDIA 外部 GPU、そして AMD 外部 GPU が存在すると仮定します。

統合 Intel チップを使用する場合、変更は必要ありません。それがすでにデフォルトであるからです:

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 を同時に同じマシン上で使用することができます。

ノート: 外部 GPU のホットプラグは制限付きで有効化されます: 正しいカーネルモジュールをロードするには再ログインが必須です。

PRIME に関する mesa3d ドキュメントを参照: https://docs.mesa3d.org/envvars.html

すべての XWayland アプリケーションは、Xorg で行うように、特に設定せずに動作するはずです。しかし、ドライババージョン 525.85 現在、modesetting が有効化されている場合、ネイティブな Wayland アプリケーションは、OpenGL のみが動作します。

Vulkan の Wayland アプリケーションは、NVIDIA ドライバが Intel や AMD の GPU には理解できないハードウェア固有のピクセルレイアウトを使用しているため、ウィンドウが見えなくなり、場合によってはクラッシュするかもしれません。詳細は NVIDIA の GitHub issue 72 を参照。

Reverse PRIME

セカンダリ GPU の出力にプライマリ GPU からアクセスできない場合、Reverse PRIME を使って出力を利用することができます。プライマリ GPU を使って画像をレンダリングして、セカンダリ GPU に出力を渡します。

上記の構成の場合、以下を実行:

$ xrandr --setprovideroutputsource radeon Intel

設定すると、ディスクリートカードの出力が xrandr で扱えるようになるので、以下のように出力を流し込みます:

$ xrandr --output HDMI-1 --auto --above LVDS1

ディスクリートカードをプライマリ GPU にする

次のようなシナリオを考えてみてください: LVDS1 (ノートパソコンの内蔵スクリーン) と VGA 出力の両方とも内蔵の Intel GPU からしかアクセスできず、ディスクリートの NVIDIA カードには HDMI と DisplayPort 端子が付いている。上述の Reverse PRIME テクノロジーを使うことで4つの出力を全て使うことはできますが、どの出力も内蔵の Intel カードによって作成されるためパフォーマンスが遅くなります。このような状況を改善する方法として、ディスクリートの NVIDIA カードでレンダリングを行なってから、フレームバッファを Intel カードの 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
ノート: プロプライエタリの NVIDIA ドライバーの場合、[4] を見てください。

Xorg を再起動してください。ディスクリートの NVIDIA カードが使われるようになっているはずです。HDMI と DisplayPort がメインの出力で LVDS1 と VGA の出力はオフになります。有効にするには次を実行:

$ xrandr --setprovideroutputsource Intel nouveau

上記のコマンドで xrandr でディスクリートの出力端子が使えるようになります。

ユーザのシナリオ

ディスクリートカードをプライマリ GPU にする

次のようなシナリオを考えてみてください: LVDS1 (ノートパソコンの内蔵スクリーン) と VGA 出力の両方とも内蔵の Intel GPU からしかアクセスできず、ディスクリートの NVIDIA カードには HDMI と DisplayPort 端子が付いている。上述の #Reverse PRIME テクノロジーを使うことで4つの出力を全て使うことはできますが、どの出力も内蔵の Intel カードによって作成されるためパフォーマンスが遅くなります。このような状況を改善する方法として、ディスクリートの NVIDIA カードでレンダリングを行なってから、フレームバッファを Intel カードの 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
ノート: プロプライエタリの NVIDIA ドライバーの場合、代わりに [5] を見てください。

Xorg を再起動してください。ディスクリートの NVIDIA カードが使われるようになっているはずです。HDMI と DisplayPort がメインの出力で LVDS1 と VGA の出力はオフになります。有効にするには次を実行:

$ xrandr --setprovideroutputsource Intel nouveau

上記のコマンドで xrandr でディスクリートの出力端子が使えるようになります。

ノート: NVIDIA がスクリーンのレンダリングに使用されている場合、スクロールが遅くなったり、スクリーンのティアリングが発生したりする場合があります。これを軽減する方法については NVIDIA/トラブルシューティング#画面のティアリングを抑える を確認してください。

トラブルシューティング

XRandR の出力プロバイダを1つだけに指定する

/etc/X11/xorg.conf ファイルおよび /etc/X11/xorg.conf.d/ の GPU に関連するその他のファイルを削除します。この変更後、X サーバを再起動します。

ビデオドライバが /etc/modprobe.d/ にブラックリスト登録されている場合は、モジュールをロードして X を再起動します。NVIDIA GPU 用に bbswitch モジュールを使用している場合は、この問題が発生する可能性があります。

もう1つ考えられる問題は、Xorg が2台目の GPU にモニタを自動的に割り当てようとする可能性があることです。ログを確認してください

$ grep "No modes" ~/.local/share/xorg/Xorg.0.log
AMDGPU(0): No modes.

これを解決するには、xorg.conf に非アクティブなデバイスの ServerLayout セクションを追加します。

/etc/X11/xorg.conf
Section "ServerLayout"
  Identifier     "X.org Configured"
  Screen      0  "Screen0" 0 0 # Screen for your primary GPU
  Inactive       "Card1"       # Device for your second GPU
EndSection

ディスクリートカードを使ってアプリケーションをレンダリングした場合に、黒画面しか表示されない

場合によって PRIME を使うにはコンポジットマネージャが必要になることがあります。ウィンドウマネージャがコンポジットを行わない場合、ウィンドウマネージャに加えて xcompmgr を使用してください。

Xfce を使用しているならば Menu->Settings->Window Manager Tweaks->Compositor からコンポジットを有効にできます。有効にした後にアプリケーションを実行してみてください。

GL ベースのコンポジタで黒画面が表示される

GL ベースのコンポジタと PRIME オフロードの組み合わせには問題が存在します。Xrender ベースのコンポジタ (xcompmgr, xfwm, picom のデフォルトバックエンド, cairo-compmgr など) に問題は起こりませんが、GL ベースのコンポジタ (Mutter/muffin, Compiz, GLX バックエンドの picom, Kwin の OpenGL バックエンドなど) では、まるでコンポジタが動いていないかのように黒画面が表示されます。オフロードしたウィンドウのサイズを変更することで画像を表示させることはできますが、フルスクリーンの Wine アプリケーションなどではどうしようもありません。GL ベースのコンポジタを使っている GNOME3 や Cinnamon などのデスクトップ環境でも PRIME オフロードを使用した場合に問題が発生します。

さらに、Intel IGP を使用している場合、IGP で SNA ではなく UXA を使うことで GL コンポジットの問題を解決できることがありますが、オフロードに問題を起こしてしまうこともあります (xrandr --listproviders でディスクリート GPU が表示されない)。

詳しくは FDO Bug #69101 を参照。

PRIME を使用してウィンドウやワークスペースを切り替えたときにカーネルがクラッシュする

ノート: Intel + AMD の環境で確認済みです。

内蔵カードの設定ファイルで DRI3 を使うようにすることで問題が解決します。

DRI3 を有効にするには、内蔵カードの設定に DRI3 オプションを追加してください:

Section "Device"
    Identifier "Intel Graphics"
    Driver "intel"
    Option "DRI" "3"
EndSection

上記の設定をした後、DRI_PRIME=1 を使うことで DRI3 がオフロードを行うようになります。xrandr --setprovideroffloadsink radeon Intel を実行する必要はありません。

Reverse PRIME を使用した場合にセカンドモニタで焼きつきなどの同期の問題が発生する

i3 などのウィンドウマネージャでコンポジットマネージャを使わないとこの問題が発生します [6]

GNOME で問題が発生するときは、/etc/environment で以下の環境変数を設定してみてください [7]:

CLUTTER_PAINT=disable-clipped-redraws:disable-culling
CLUTTER_VBLANK=True

GL アプリケーションを起動したときにエラー: "radeon: Failed to allocate virtual address for buffer:"

カーネルドライバーの電源管理が実行されているときに発生するエラーです。ブートローダーのカーネルパラメータに radeon.runpm=0 を追加することでエラーを抑えることができます。

VSync とクローズドソースのドライバと reverse PRIME を使用した Vulkan アプリケーション/ゲームでハング/フリーズが発生する

一部の Vulkan アプリケーション (特に VK_PRESENT_MODE_FIFO_KHR や VK_PRESENT_MODE_FIFO_RELAXED_KHR を使用しているもの (DXVK で実行される Windows ゲームを含む) は、reverse PRIME を使用するシステムで実行すると、GPU が常に (5~10秒間隔でフリーズ) [8] を繰り返したりします

GPU がハングアップすると、すべての入力が使用できなくなります (これには TTY の切り替えと SysRq 機能の使用が含まれます) 。

この NVIDIA のバグに対する既知の修正はないが、いくつかの回避策がある。

  • Vsync をオフにする (一部のアプリケーションでは不可能)
  • PRIME Synchronization [9] をオフにする (画面のティアリング)
xrandr --output HDMI-0 --set "PRIME Synchronization" 0 #replace HDMI-0 with your xrandr output ID

vulkan-tools パッケージの vkcube を実行するだけで、使用している構成がこの問題の影響を受けているかどうかを確認できます。

参照