PRIME
PRIME は最近のノートパソコンで使われているハイブリッドグラフィック (NVIDIA の Optimus や Radeon の AMD Dynamic Switchable Graphics) を管理するためのテクノロジーです。Linux カーネルでマルチプレクサを必要としないハイブリッドグラフィックを実現するものとして PRIME GPU オフロードと Reverse PRIME が存在します。
目次
- 1 インストール
- 2 PRIME GPU オフロード
- 3 Reverse PRIME
- 4 トラブルシューティング
- 4.1 ディスクリートカードを使ってアプリケーションをレンダリングした場合に、黒画面しか表示されない
- 4.2 PRIME を使用してウィンドウやワークスペースを切り替えたときにカーネルがクラッシュする
- 4.3 Reverse PRIME を使用した場合にセカンドモニタで焼きつきなどの同期の問題が発生する
- 4.4 GL アプリケーションを起動したときにエラー: "radeon: Failed to allocate virtual address for buffer:"
- 4.5 Error "radeon: Failed to allocate virtual address for buffer:" when launching GL application
- 4.6 Constant hangs/freezes with Vulkan applications/games using VSync with closed-source drivers and reverse PRIME
- 5 参照
インストール
オープンソースドライバー
クローズドソースのグラフィックドライバーを削除して、オープンソースのドライバーで置き換えてください:
再起動して、使われているグラフィックドライバーのリストを確認:
$ 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
クローズドソースドライバー
プロプライエタリドライバーで PRIME を機能させる手順もほとんど同じです。以下の記事に従ってドライバーをインストールしてください:
ドライバーをインストールしたすぐ後に再起動したり Xorg を再実行しないでください。システム構成によっては設定を変更しないと Xorg が起動できなくなります。
ユースケースにあわせて設定を行ってください。必ずしもオープンソースドライバーをアンインストールする必要はありませんが、アンインストールしておいたほうが将来的に問題が起こる可能性を少なくできます。
PRIME GPU オフロード
GPU の負担が大きいアプリケーションは強力なディスクリートカードを使ってレンダリングするべきです。xrandr --setprovideroffloadsink provider sink
コマンドを使うことでレンダーオフロードプロバイダからシンクプロバイダ (ディスプレイに接続されたプロバイダ) に出力を送信することが可能です。プロバイダとシンクの識別子は数字 (0x7d, 0x56) あるいは大文字・小文字を区別する名前 (Intel, radeon) で指定します。
例:
$ xrandr --setprovideroffloadsink radeon Intel
プロバイダの名前の代わりにプロバイダのインデックスを使うこともできます:
$ xrandr --setprovideroffloadsink 1 0
これで、DRI_PRIME=1
環境変数を付けることでグラフィック性能を必要とするアプリケーション (例えばゲームや 3D モデラーなど) でディスクリートカードを使うことができます:
$ DRI_PRIME=1 glxinfo | grep "OpenGL renderer"
OpenGL renderer string: Gallium 0.4 on AMD TURKS
他のアプリケーションは電力の消費量が少ない内蔵カードを使います。X サーバーを再起動すると上記の設定は消失するため、スクリプトを作成して、デスクトップ環境の起動時に自動でスクリプトが実行されるようにすると良いでしょう (もしくは、スクリプトを /etc/X11/xinit/xinitrc.d/
に保存)。バッテリーの持ちが良くなって熱が少なくなることもあるでしょう。
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
Xorg を再起動してください。ディスクリートの NVIDIA カードが使われるようになっているはずです。HDMI と DisplayPort がメインの出力で LVDS1 と VGA の出力はオフになります。有効にするには次を実行:
$ xrandr --setprovideroutputsource Intel nouveau
上記のコマンドで xrandr でディスクリートの出力端子が使えるようになります。
トラブルシューティング
ディスクリートカードを使ってアプリケーションをレンダリングした場合に、黒画面しか表示されない
場合によって 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 を使用してウィンドウやワークスペースを切り替えたときにカーネルがクラッシュする
内蔵カードの設定ファイルで 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 などのウィンドウマネージャでコンポジットマネージャを使わないとこの問題が発生します [2]。
GNOME で問題が発生するときは、/etc/environment
で以下の環境変数を設定してみてください [3]:
CLUTTER_PAINT=disable-clipped-redraws:disable-culling CLUTTER_VBLANK=True
GL アプリケーションを起動したときにエラー: "radeon: Failed to allocate virtual address for buffer:"
カーネルドライバーの電源管理が実行されているときに発生するエラーです。ブートローダーのカーネルパラメータに radeon.runpm=0
を追加することでエラーを抑えることができます。
Error "radeon: Failed to allocate virtual address for buffer:" when launching GL application
This error is given when the power management in the kernel driver is running. You can overcome this error by appending radeon.runpm=0 to the kernel parameters in the bootloader.
Constant hangs/freezes with Vulkan applications/games using VSync with closed-source drivers and reverse PRIME
Some Vulkan applications (particularly ones using VK_PRESENT_MODE_FIFO_KHR and/or VK_PRESENT_MODE_FIFO_RELAXED_KHR, including Windows games ran with DXVK) will cause the GPU to lockup constantly (~5-10 seconds freezed, ~1 second working fine)[4] when ran on a system using reverse PRIME.
A GPU lockup will render any input unusable (this includes switching TTYs and using SysRq functions).
There's no known fix for this NVIDIA bug, but a few workarounds exist:
- Turning Vsync off (not possible for some applications)
- Turning PRIME Synchronization[5] off (will introduce screen tearing):
xrandr --output HDMI-0 --set "PRIME Synchronization" 0 #replace HDMI-0 with your xrandr output ID
You can verify if your configuration is affected by the issue simply by running vkcube from the vulkan-tools package.