1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

プロプライエタリ nvidia ドライバでの GPU オフロードで、 bumblebee が不要になる

概要

オンボードグラフィックスとディスクリート GPU を両方積んでいるような状況、たとえば典型的にはグラボを積んだラップトップなどにおいて、通常はオンボードのグラフィックスを利用し、ゲーム等の特別に重い処理のみディスクリート GPU に任せる、 GPU オフロードという技術がある。

従来、 nvidia の GPU をプロプライエタリのドライバで利用する場合、 GPU オフロードには bumblebeeprimus などを使う必要があった。
また、 bumblebee や primus は OpenGL 用のものであり、 Vulkan で GPU オフロードするにはまた別の実装が必要であった。

しかし、 nvidia-drivers 435 あたりからはプロプライエタリドライバに PRIME render offload の対応が入り、 bumblebee なしで OpenGL や Vulkan の GPU オフロードができるようになった。

以下では、この新機能を gentoo で利用する手順を説明する。

この情報は 2019-10-17 時点のものであり、現時点または将来に渡る安定した動作は保証しないことに留意せよ。
(まあそもそも nvidia-drivers 自体が安定していないという話はある🙄)

追記 2019-12-06: libglvnd USE flag と media-libs/libglvnd-1.3.0 の mask が解除されたため、以下の手順の大半は不要になった。
現時点で (これからも) 必要な手順は以下の通り:

  • libglvnd USE flag を通常の手順で有効化する (と同時に x11-drivers/nvidia-drivers の関連するフラグも設定する)
    • もはや profile/package.use.mask の編集は不要
  • >=x11-base/xorg-server-1.20.6>=media-libs/libglvnd-1.3.0>=x11-drivers/nvidia-drivers-435.21 を emerge する
    • もはや package.unmask の編集は不要
    • パッチ適用も不要

(追記終わり)

環境

  • Gentoo Linux (amd64)
  • x11-base/xorg-server-1.20.5
    • 今のところ入手できるパッチが 1.20.5 用なので、 1.20.6 などが出たときはまた手を加える必要があるかもしれない (たぶん次は 1.21 だと思うけど)。
  • x11-drivers/nvidia-drivers-435.21
    • 430.50 だとたぶん無理。試してないけど。
    • 435.21 だと bumblebee や primus が (少なくとも私の環境では) 正常に動作しないようなので、 bumblebee を使うつもりならしばらくは 430.50 を使い続けた方がよさそう。

未リリースのソフトウェアやパッチが必要になりそうなので、 gentoo amd64 以外の環境でどうなるか (いつごろ利用可能になるか、あるいは既に可能か) は知らない。

手順

1. 関連機能を unmask し有効化する

portage の設定を編集

まず libglvnd USE flag が mask されているため、これを unmask し、かつ有効化する。

/etc/portage/profile/package.use.mask
>=media-libs/mesa-19.2.1 -libglvnd
>=x11-base/xorg-server-1.20.5 -libglvnd
>=x11-drivers/nvidia-drivers-435.21 -libglvnd

また、 PRIME render offload には kernel modesetting を使うため、 kms フラグも同時に有効化する。
compat フラグを有効化してしまうと non-GLVND の libGL がインストールされてしまうため、これは無効化すること。

/etc/portage/package.use/nvidia
# Proprietary nvidia-drivers require glvnd for PRIME render offloading.
# See <http://us.download.nvidia.com/XFree86/Linux-x86_64/435.21/README/primerenderoffload.html>
# and <https://bugs.gentoo.org/692206>.
>=media-libs/mesa-19.2.1 libglvnd
>=x11-base/xorg-server-1.20.5 libglvnd
>=x11-drivers/nvidia-drivers-435.21 libglvnd -compat
>=x11-drivers/nvidia-drivers-435.21 kms

また、 media-libs/libglvnd も mask されているため、これも unmask する。

/etc/portage/package.unmask/libglvnd
# See <https://bugs.gentoo.org/692206>.
# 将来的に標準で unmask されたら、この行は削除すべし
<media-libs/libglvnd-9999

2. X サーバにパッチを当ててリビルド

更新 (2019-11-23): x11-base/xorg-server-1.20.6 がリリースされ、これに以下で必要なコードは全て入っている。
そのため、 1.20.6 以上をインストールするならパッチを導入する工程は不要。

パッチを当てる

https://bugs.gentoo.org/692206#c30 の人が必要な変更を抽出してくれているので、これを xorg-server-1.20.5 に当てる。

https://github.com/LuoJinghua/gentoo-overlay/tree/master/x11-base/xorg-server/files にある xorg-server-1.21-*.patch のような名前のパッチ計6つを /etc/portage/patches/x11-base/xorg-server-1.20.5 に配置する。

$ ls /etc/portage/patches/x11-base/xorg-server-1.20.5/ | cat
xorg-server-1.21-autobind-gpu.patch
xorg-server-1.21-multigpu-00-7f962c70.patch
xorg-server-1.21-multigpu-01-37a36a6b.patch
xorg-server-1.21-multigpu-02-8b67ec7c.patch
xorg-server-1.21-multigpu-03-56c0a71f.patch
xorg-server-1.21-multigpu-04-b4231d69.patch

emerge

ビルドする。
xorg-server だけでなく、 USE flag を変更した他のパッケージもリビルドを忘れないこと。

$ sudo emerge -1uv mesa xorg-server nvidia-drivers

この手順はうどんワールドでも何でもいい。
とにかく更新した use flag が反映されていればおk。
また、ビルド時にパッチが当たっていることも念のため確認しておいた方がいい。

$ sudo emerge -1v xorg-server

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] x11-base/xorg-server-1.20.5:0/1.20.5::gentoo  USE="glamor ipv6 libglvnd suid systemd udev wayland xorg -debug -dmx -doc (-elogind
) -kdrive -libressl -minimal (-selinux) -static-libs -unwind -xcsecurity -xephyr -xnest -xvfb" 0 KiB

Total: 1 package (1 reinstall), Size of downloads: 0 KiB


>>> Verifying ebuild manifests

>>> Emerging (1 of 1) x11-base/xorg-server-1.20.5::gentoo
 * xorg-server-1.20.5.tar.bz2 BLAKE2B SHA512 size ;-) ...                                                                                  [ ok ]
>>> Unpacking source...
>>> Unpacking xorg-server-1.20.5.tar.bz2 to /var/tmp/portage_tmpfs/portage/x11-base/xorg-server-1.20.5/work
>>> Source unpacked in /var/tmp/portage_tmpfs/portage/x11-base/xorg-server-1.20.5/work
>>> Preparing source in /var/tmp/portage_tmpfs/portage/x11-base/xorg-server-1.20.5/work/xorg-server-1.20.5 ...
 * Applying xorg-server-1.20.4-shm-reindent-shm_tmpfile-to-follow-our-standards.patch ...                                                  [ ok ]
 * Applying xorg-server-1.20.4-shm-Pick-the-shm-dir-at-run-time-not-build-time.patch ...                                                   [ ok ]
 * Applying xorg-server-1.20.4-shm-Use-memfd_create-when-possible.patch ...                                                                [ ok ]
 * Applying xorg-server-1.12-unloadsubmodule.patch ...                                                                                     [ ok ]
 * Applying xorg-server-1.18-support-multiple-Files-sections.patch ...                                                                     [ ok ]
 * Applying xorg-server-1.21-autobind-gpu.patch ...                                                                                        [ ok ]
 * Applying xorg-server-1.21-multigpu-00-7f962c70.patch ...                                                                                [ ok ]
 * Applying xorg-server-1.21-multigpu-01-37a36a6b.patch ...                                                                                [ ok ]
 * Applying xorg-server-1.21-multigpu-02-8b67ec7c.patch ...                                                                                [ ok ]
 * Applying xorg-server-1.21-multigpu-03-56c0a71f.patch ...                                                                                [ ok ]
 * Applying xorg-server-1.21-multigpu-04-b4231d69.patch ...                                                                                [ ok ]
 * User patches applied.
(後略)

3. Xorg の設定

/etc/X11/xorg.conf.d/60-nvidia-offload.conf
# See <http://us.download.nvidia.com/XFree86/Linux-x86_64/435.21/README/primerenderoffload.html>.
Section "ServerLayout"
    Identifier "layout"
    Option "AllowNVIDIAGPUScreens"
EndSection

4. 再起動と確認

再起動したのち X を起動し、以下のことを確認する。
全てで問題がなければ、 PRIME render offload が利用可能のはずである。

glxinfo

成功例
$ __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo | grep vendor
server glx vendor string: NVIDIA Corporation
client glx vendor string: NVIDIA Corporation
OpenGL vendor string: NVIDIA Corporation

ベンダーが NVIDIA Corporation になっていればおk。

失敗例
$ __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo | grep vendor
X Error of failed request:  BadValue (integer parameter out of range for operation)
(後略)

BadValue (integer parameter out of range for operation) などと言われた場合、おそらく x11-drivers/nvidia-driverskms USE flag が有効化されていない。

xrandr

成功例
$ xrandr --listproviders | grep NVIDIA
Provider 1: id: 0x1b8 cap: 0x0 crtcs: 0 outputs: 0 associated providers: 0 name:NVIDIA-G0

name:NVIDIA-G0 のような provider が含まれていればおk。

X のログ

成功例
$ grep 'NVIDIA(G0)' /var/log/Xorg.0.log | head -1
[    23.123] (==) NVIDIA(G0): Depth 24, (==) framebuffer bpp 32

NVIDIA(G0) のような行が含まれていればおk。

成功例
$ grep PRIME /var/log/Xorg.0.log
[    23.161] (II) NVIDIA: The X server supports PRIME Render Offload.

The X server supports PRIME Render Offload. という行が含まれていればおk。

もし "The X server does not supports ..." (強調は筆者) となっていたら、 X サーバ側に必要なパッチが当たっていない。
(参考: PRIME offload not working - NVIDIA Developer Forums)

利用方法

基本的には Chapter 35. PRIME Render Offload で紹介されている通り。

OpenGL (GLX) のアプリケーションなら、環境変数2つを __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia のように設定する。

$ glxinfo | grep vendor
server glx vendor string: SGI
client glx vendor string: Mesa Project and SGI
OpenGL vendor string: Intel Open Source Technology Center
$ __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo | grep vendor
server glx vendor string: NVIDIA Corporation
client glx vendor string: NVIDIA Corporation
OpenGL vendor string: NVIDIA Corporation
$

EGL や Vulkan なら、環境変数は __NV_PRIME_RENDER_OFFLOAD=1 だけで良い。

$ __NV_PRIME_RENDER_OFFLOAD=1 vkcube
(キューブが回転する)

(vkcube は dev-util/vulkan-toolscube USE フラグを有効化するとインストールできる。)

Vulkan アプリケーションで __GLX_VENDOR_LIBRARY_NAME=nvidia を付けていても特に問題は見られないので、必要かわからない場合はとりあえず両方とも付けておけばよさそう。

もし上のようなコマンドが失敗したり vkcube がクラッシュするようなら、 x11-drivers/nvidia-driverscompat USE フラグがちゃんと無効化されているか確認すること。
これが有効のままだと、 libpthread あたりでクラッシュして coredump する。

他の話題

EGL

OpenGL は GLX のみの対応で、 EGL は今のところ (435.21) 未対応っぽい。

NVIDIA's EGL implementation does not yet support PRIME render offload.

―― http://us.download.nvidia.com/XFree86/Linux-x86_64/435.21/README/primerenderoffload.html

更新 2019-11-22: EGL 対応

440.31 のドキュメントを確認したところ、 EGL にも対応した模様。
EGL を使う場合にも、 __NV_PRIME_RENDER_OFFLOAD=1 のみの設定でオフロードできるらしい。

To configure a graphics application to be offloaded to the NVIDIA GPU screen, set the environment variable __NV_PRIME_RENDER_OFFLOAD to 1. If the graphics application uses Vulkan or EGL, that should be all that is needed.

確認してみよう。

オフロードした場合
$ __NV_PRIME_RENDER_OFFLOAD=1 eglinfo | grep -A 2 'platform:'
GBM platform:
EGL API version: 1.4
EGL vendor string: Mesa Project
--
Wayland platform:
eglinfo: eglInitialize failed

X11 platform:
EGL API version: 1.5
EGL vendor string: NVIDIA
--
Device platform:
EGL API version: 1.5
EGL vendor string: NVIDIA
オフロードしない場合
$ eglinfo | grep -A 2 'platform:'
GBM platform:
EGL API version: 1.4
EGL vendor string: Mesa Project
--
Wayland platform:
eglinfo: eglInitialize failed

X11 platform:
EGL API version: 1.4
EGL vendor string: Mesa Project
--
Device platform:
EGL API version: 1.5
EGL vendor string: NVIDIA

DRI_PRIME

PRIME は本来、環境変数 DRI_PRIME=1 で有効化できるはずなのだが、どうもこれが (現状の私の環境だと) 動かないっぽい。

$ DRI_PRIME=1 glxinfo | grep vendor
libGL error: MESA-LOADER: failed to open nouveau (search paths /usr/lib64/dri)
libGL error: failed to load driver: nouveau
server glx vendor string: SGI
client glx vendor string: Mesa Project and SGI
OpenGL vendor string: Intel Open Source Technology Center
$

どこに原因があるのかはわからないが、とにかく動かない。

これが問題になるのは、たとえば lutris のランチャーの "System options" で "Use discrete graphics" などを有効化すると DRI_PRIME=1 でゲームを起動してくれるなどの機能があり、これが意図した通りにディスクリート GPU を使ってくれないということである。
仕方ないので、この場合は同じく "System options" の "Environment variables" から2つの環境変数を手動で設定してやるなどする必要がある。

screenshot-2019-10-17-021319+0900.png

参考

あとがき: --my-next-gpu-wont-be-nvidia

If the nvidia module is loaded on your system, you are not permitted to file bugs of any sort.

―― https://github.com/swaywm/sway/issues/3039#issuecomment-434663746

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
1
Help us understand the problem. What are the problem?