VirtualGL

提供: ArchWiki
2024年9月3日 (火) 22:41時点におけるKusanaginoturugi (トーク | 投稿記録)による版 (カテゴリを修正)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

VirtualGL はアプリケーションの OpenGL/GLX コマンドを (3D グラフィックカードにアクセスできる) 別の X サーバーにリダイレクトして、レンダリングされた画像をキャプチャして、アプリケーションを実行している X サーバーに流し込みます。

リモートデスクトップ環境で、サーバー側のハードウェア支援による 3D レンダリングをできるようにするのが VirtualGL の主な用途です。

インストールとセットアップ

virtualgl パッケージをインストールして こちら の手順に従って設定してください。Arch では /opt/VirtualGL/bin/vglserver_config/opt/VirtualGL/bin/glxinfo はただの vglserver_config と vglxinfo です。

X11 フォワーディングで VirtualGL を使う

 server:                                              client:
······································               ·················
: ┌───────────┐ X11 commands         :               : ┌───────────┐ :
: │application│━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━▶│X server   │ :
: │           │        ┌───────────┐ :               : │           │ :
: │           │        │X server   │ :               : ├┈┈┈┈┈┈┈┈┈╮ │ :
: │ ╭┈┈┈┈┈┈┈┈┈┤ OpenGL │ ╭┈┈┈┈┈┈┈┈┈┤ : image stream  : │VirtualGL┊ │ :
: │ ┊VirtualGL│━━━━━━━▶│ ┊VirtualGL│━━━━━━━━━━━━━━━━━━▶│client   ┊ │ :      = "2D" rendering happens here
: └─┴─────────┘        └─┴─────────┘ :               : └─────────┴─┘ :      = "3D" rendering happens here
······································               ·················

VNC で VirtualGL を使うのに対して以下のメリットがあります:

  • シームレスなウィンドウ
  • サーバー側の CPU 使用量が減ります
  • ステレオレンダリング (3D メガネを使用) をサポート

準備

リモートサーバーで VirtualGL をセットアップするには、以下が必要です:

  • クライアント側にも virtualgl パッケージをインストール (ただし、サーバーと同じように設定する必要はありません。必要なのは vglconnectvglclient のバイナリだけです)。
  • SSH で X11 フォワーディングを設定 (ssh -X user@server でクライアントからサーバーに接続してシェルから GUI アプリケーションが実行できるか確認してください)。

接続

クライアント側で vglconnect を使うことでサーバーに接続できます:

$ vglconnect user@server     # X11 traffic encrypted, VGL image stream unencrypted
$ vglconnect -s user@server  # both X11 traffic and VGL image stream encrypted

上記のコマンドで ssh -X と同じように X11 フォワーディングの SSH セッションが開き、適切なパラメータを使ってバックグラウンドデーモンとして VirtualGL クライアント (vglclient) が自動的に起動します。デーモンはサーバーからの VirtualGL 画像ストリームを処理して、SSH シェルを閉じた後もバックグラウンドで動作し続けます。終了するには vglclient -kill を実行してください。

アプリケーションの実行

SSH シェルの中から vglrun でアプリケーションを実行することで、OpenGL で VirtualGL レンダリングを有効にしてリモートのアプリケーションを実行できます。

vglconnect によって開かれたシェルに閉じこもる必要はありません。同一の X セッションから ssh -X または ssh -Y シェルを同一の user@server で開くことができます。vglrun は SSH シェルを認識して、VGL 画像ストリームがネットワークを介して送信されます (実行中の vglclient インスタンスによって受信・処理されます)。

VNC で VirtualGL を使う

 server:                                                           client:
···················································               ················
: ┌───────────┐ X11 commands         ┌──────────┐ : image stream  : ┌──────────┐ :
: │application│━━━━━━━━━━━━━━━━━━━━━▶│VNC server│━━━━━━━━━━━━━━━━━━▶│VNC viewer│ :
: │           │        ┌───────────┐ └──────────┘ :               : └──────────┘ :
: │           │        │X server   │        ▲     :               :              :
: │ ╭┈┈┈┈┈┈┈┈┈┤ OpenGL │ ╭┈┈┈┈┈┈┈┈┈┤ images ┃     :               :              :
: │ ┊VirtualGL│━━━━━━━▶│ ┊VirtualGL│━━━━━━━━┛     :               :              :      = "2D" rendering happens here
: └─┴─────────┘        └─┴─────────┘              :               :              :      = "3D" rendering happens here
···················································               ················

X11 フォワーディングで VirtualGL を使うのに対して以下のメリットがあります:

  • ネットワークの速度が遅かったり遅延が著しい場合でもパフォーマンスを維持できます。
  • 複数のクライアントに同一の画像ストリームを送信できます ("デスクトップ共有")。
  • ネットワークの接続が途絶えてもリモートアプリケーションを実行し続けることができます。
  • アーキテクチャはクライアント側の X サーバーに依存しないため、Linux 以外のサポートが充実しています。

手順

リモートサーバーに VirtualGL をセットアップした後、適当な VNC クライアント・サーバーを使ってリモートデスクトップ接続を確立してください。特に設定は必要ありません。

VNC セッションの中で (例: VNC デスクトップのターミナルエミュレータ、あるいは ~/.vnc/xstartup に直接)、vglrun で動かしたいアプリケーションを実行してください。

vglrun でセッション全体を動作させて、全ての OpenGL アプリケーションをデフォルトで動かすこともできます。例えば、Xfce を使用する場合、X のスタートアップスクリプト (~/.vnc/xstartup.xinitrc) で startxfce4 の代わりに vglrun startxfce4 を実行するか、ディスプレイマネージャを使用するのであれば /usr/share/xsessionsデスクトップファイルをコピー・編集します。

適切な VNC パッケージの選択

VirtualGL はあらゆる VNC サーバー実装 (例: TightVNC, RealVNC, ...) に対して 3D レンダリングを提供することができます。

しかしながら、性能を引き出したい場合、特別に最適化された VNC 実装を使うと良いでしょう:

  • turbovncAUR: VirtualGL と同じチームによって開発されており、VirtualGL と組み合わせて使うことで最高のパフォーマンスを発揮します。ただし、通常の Xorg サーバーが提供している機能を全てサポートしているわけではないため、一部のアプリケーションが遅くなったり全く動作しなかったりします。
  • TigerVNC: VirtualGL を念頭に開発されており素晴らしいパフォーマンスを出すことができます。さらに、TurboVNC よりも Xorg の互換性が高くなっています。

アプリケーションの実行

VirtualGL に対応したリモートデスクトップ接続をセットアップできたら、OpenGL を VirtualGL でレンダリングするために vglrun を使ってアプリケーションを実行します:

$ vglrun glxgears

もちろん上記のコマンドはリモートコンピュータ (SSH または VNC セッション) で実行する必要があります。使用する X サーバーは以下の環境変数で決定されます:

DISPLAY アプリケーションを処理し、OpenGL 以外の部分をレンダリングする X サーバー。

VNC を使用する場合、VNC サーバーが参照されます。SSH フォワーディングの場合、SSH によって内部的にマッピングされた実際の X サーバーの仮想 X サーバー番号になります。VirtualGL 特有のことは何もなく、SSH または VNC セッションの中で適当な値に設定されます。

VGL_DISPLAY VirtualGL によって OpenGL のレンダリングがリダイレクトされる X サーバー。

設定していない場合、:0.0 が使われます。ドットの後ろの番号を使ってグラフィックカードを選択することができます。

他にも様々な環境変数やコマンドラインパラメータで vglrun を設定できます。詳しくはユーザーマニュアルや vglrun -help を参照してください。VirtualGL の挙動はさらに以下のどちらのモードが使われているかによって左右されます (vglrun によって環境に応じて自動的に選択されます):

このモードでは特別なネットワークプロトコルを使ってレンダリングされた OpenGL シーンが圧縮済みの画像ストリームとして vglclient インスタンスに送信されます。デフォルトでは 90% 品質の JPEG 圧縮が使われますが、カスタマイズすることもできます。例:
$ vglrun -q 30 -samp 4x glxgears              # use aggressive compression (to reduce bandwidth demand)
$ VGL_QUAL=30 VGL_SUBSAMP=4x vglrun glxgears  # same as above, using environment variables
vglrun で起動した後にアプリケーションの VirtualGL のレンダリング・圧縮オプションを変更できる GUI ダイアログも存在します。アプリケーションにキーボードのフォーカスがあたっているときに Ctrl+Shift+F9 を押すことでダイアログが開きます。
  • X11 Transport - VNC を使用する場合のデフォルト
このモードでは VirtualGL は生の (圧縮されていない) 画像を通常の X11 プロトコルで直接 X サーバー (例: 同一マシンで動作する VNC サーバー) に送信します。vglrun のコマンドラインオプションのほとんどが使用できません (画像ストリーム圧縮やステレオレンダリングに関するオプションなど)。クライアント側で vglclient が動作していないためです。VNC サーバーが画像ストリームの最適化や圧縮を全て扱うようになるため、あなた自身で設定を行う必要があります。
ヒント: vglrun is actually just a shell script that (temporarily) sets some environment variables before running the requested application - most importantly it adds the libraries that provide all the VirtualGL functionality to LD_PRELOAD. If it better suits your workflow, you could just set those variables yourself instead. The following command lists all environment variables that vglrun would set for your particular set-up:
comm -1 -3 <(env | sort) <(vglrun env | grep -v '^\[' | sort)

VirtualGL のレンダリングが有効になっていることを確認

アプリケーションを起動する前に VGL_LOGO 環境変数を設定すると、VirtualGL でアプリケーションがレンダリングされたときに OpenGL シーンの右下隅に "VGL" と書かれた小さなロゴが表示されます:

$ VGL_LOGO=1 vglrun glxgears

アプリケーションを実行してもロゴが表示されない場合、VirtualGL が使われておらずアプリケーションはソフトウェアレンダリングで実行されています (下の#トラブルシューティングを参照)。

パフォーマンスの測定

FPS カウンタを表示できる OpenGL プログラムは多数存在しますが、VirtualGL を使う場合、その値はあまり意味を持ちません。あくまでサーバー側でレンダリングしたときのフレームレートを計測するためです。実際にクライアント側に表示されるフレームレートは考慮されません。

ユーザーマニュアルの "Performance Measurement" の章には VirtualGL の画像パイプラインのスループットを計測する方法や、ボトルネック (特に X11 フォワーディングを使用する場合) を見つけ出す方法が載っています。VNC を使用する場合であれば VNC クライアントでフレームレートを確認できるはずです。

トラブルシューティング

ヒント: Running vglrun with the +v command-line switch (or environment variable VGL_VERBOSE=1) makes VirtualGL print out some details about its attempt to initialize rendering for the application in question. The +tr switch (or variable VGL_TRACE=1) will make it print out lots of live info on intercepted OpenGL function calls during the actual rendering. By default VirtualGL prints all its debug output to the shell - if you want to separate it from the application's own STDERR output you can set VGL_LOG=/tmp/virtualgl-$USER.log.

vglrun が "Could not open display" で停止する

vglrun が以下のエラーメッセージで終了してしまう場合:

[VGL] ERROR: Could not open display :0.

サーバー側で 3D が利用できる X サーバーが実行されていないか、VirtualGL が正しくセットアップされていないか、あるいは VGL_DISPLAY が正しく設定されていません。パッケージのアップグレードによって vglserver_config で書き換えたファイルが上書きされてしまったのかもしれません。スクリプトをもう一度実行してサーバー側の X サーバーを再起動してみてください。

vglrun が全く機能しない

以下のような場合:

  • VirtualGL で 3D レンダリングが支援されない。プログラムが停止したりソフトウェアレンダリングにフォールバックする (確認方法)。
  • 同時に、VirtualGL 関連のエラーメッセージがシェルに出力されていない。

アプリケーションの実行ファイルへの VirtualGL のプリロードが何らかの理由でブロックされている可能性があります。アプリケーションを起動するコマンドを実行する前に vglrun は VirtualGL ライブラリの名前を LD_PRELOAD 環境変数に追加し、アプリケーションの実行時に Linux カーネルは動的リンカをロードして LD_PRELOAD 変数を認識して指定されたライブラリをアプリケーションのメモリ内コピーにリンクします。環境変数が動的リンクに渡されないと、プリロードは上手くいきません:

  • アプリケーションを実行するスクリプトで LD_PRELOAD の設定が解除、あるいは上書きされている。
スクリプトを編集して問題の行をコメントアウト・修正してください (スクリプトを /usr/local/bin/ に配置することでパッケージのアップグレードで上書きされることを防げます)。
  • アプリケーションが複数のスクリプトで起動するため、環境変数がその中のどこかで消える。
アプリケーションを実行する最終的なスクリプトを編集して vglrun でアプリケーションを実行するようにしてください。
  • アプリケーションがローダーバイナリで実行されるため、LD_PRELOAD が利用されない。
可能であれば、ローダーバイナリを迂回して vglrun で直接 OpenGL アプリケーションを実行してください。例えば VirtualBox の場合、VirtualBox の GUI を使うのではなく仮想マシンのセッションを vglrun VirtualBox -startvm "Name of the VM" で直接起動する必要があります。バイナリの中で LD_PRELOAD が解除されるときは、vglrun-ge コマンドラインスイッチを使うことで解決できる場合があります。

上記のような対策が必要なアプリケーションのリストがユーザーマニュアルの "Application Recipes" に載っています。

vglrun が ld.so のエラーで終了する

VirtualGL による 3D レンダリングが機能せず、以下のようなエラーメッセージが表示される場合:

ERROR: ld.so: object 'libdlfaker.so' from LD_PRELOAD cannot be preloaded: ignored.
ERROR: ld.so: object 'librrfaker.so' from LD_PRELOAD cannot be preloaded: ignored.

動的リンカが VirtualGL バイナリをアプリケーションにプリロードする指示を正しく受けているのに、何らかの理由でロードができていません。2つの原因が考えられます:

  • 適切なアーキテクチャの VirtualGL ライブラリがインストールされていない。
VirtualGL で32ビットのアプリケーション (Wine など) を実行したい場合、Multilib リポジトリから lib32-virtualgl をインストールしてください。
  • アプリケーションの実行ファイルに setuid/setgid フラグが設定されている。
ls -l を使って実行ファイルのパーミッションを確認してみてください: setuid が設定されている場合、ユーザーの実行可能ビットのところに s が表示され (例: -rwsr-xr-x)、setgid が設定されている場合、グループの実行可能ビットのところに s が表示されます。そのような場合、プリロードされるライブラリも setuid フラグが設定されていないかぎり、かならずプリロードは失敗します。以下のコマンドを root で実行することで VirtualGL ライブラリにフラグを設定することができます:
$ chmod u+s /usr/lib/lib{rr,dl}faker.so    # for the native-architecture versions provided by virtualgl
$ chmod u+s /usr/lib32/lib{rr,dl}faker.so  # for the multilib versions provided by lib32-virtualgl
セキュリティが重要なサーバー環境で setuid を設定することによるセキュリティ上の影響に注意してください。

vglrun で ERROR: Could not connect to VGL client. で終了する

同一のサーバー上でクライアントプログラムを実行している場合 (VirtualGL を VNC のために使っている場合など)、vglrun -c proxy を使ってみてください。

/etc/opt/VirtualGL/vgl_xauth_key が存在しないというエラー

virtualGL X サーバーで vglgenkey が動作していないか、あるいは別の X サーバーで実行中のどちらかです。vglserver_config によって以下が追加されたために LightDM が間違った (vnc remote) X サーバーで vglgenkey を実行するようになったのが原因かもしれません:

/etc/lightdm/lightdm.conf
...
[Seat:*]
display-setup-script=/usr/bin/vglgenkey

以下のように修正することで問題を解決できます:

/etc/lightdm/lightdm.conf
...
[Seat:seat0]
display-setup-script=/usr/bin/vglgenkey

vglrun が ERROR: VirtualGL attempted to load the real glXCreatePbuffer function and got the fake one instead. で終了する

VirtualGL が間違ったライブラリから関数をロードしようとしています。LD_PRELOAD を設定して使用する OpenGL ライブラリのパスを指定してください。64ビットアプリケーションなら /usr/lib/libGL.so で動作するようです。(Steam や Wine) など32ビットのアプリケーションは32ビットの OpenGL を必要とします。32ビットと64ビットの両方のライブラリを使用する必要がある場合、LD_PRELOAD="/path/to/libGL.so /path/to/lib32/libGL.so" でロードできます。

レンダリングがおかしい、パフォーマンスが低い、アプリケーションエラー

OpenGL は低水準で柔軟な API を用意しており、OpenGL アプリケーションは様々なレンダリング技術を使用します。VirtualGL のデフォルトのレンダリングのリダイレクト手法はインタラクティブな 3D プログラムでは上手く機能しますが、一部のアプリケーションでは問題が起こる可能性があります。vglrun でアプリケーションを起動する前に環境変数を設定することで VirtualGL の実行モードを調整できます。以下のような環境変数が使えます (ひとつずつ試してみてください、変数によってはさらに問題が深刻になる可能性もあります):

VGL_ALLOWINDIRECT=1
VGL_FORCEALPHA=1
VGL_GLFLUSHTRIGGER=0
VGL_READBACK=pbo
VGL_SPOILLAST=0
VGL_SYNC=1  # use VNC with this one, it is very slow with X11 forwarding

OpenGL アプリケーションの中には少数ながら X サーバー環境やロードされるライブラリを決め打ちしているものがあり、VirtualGL で上手く動かないことがあります。そのようなときは VGL_DEFAULTFBCONFIG, VGL_GLLIB, VGL_TRAPX11, VGL_X11LIB, VGL_XVENDOR 環境変数を使うことで問題を解決できる場合があります。

利用可能な環境変数についてはユーザーマニュアルの "Advanced Configuration" セクションを参照してください。また、"Application Recipes" セクションには VirtualGL で動かすときに設定が必要なアプリケーションの情報が載っています。

参照