VirtualGL

提供: ArchWiki
2018年3月6日 (火) 22:27時点におけるKusakata (トーク | 投稿記録)による版 (ページの作成:「Category:グラフィック Category:リモートデスクトップ en:VirtualGL VirtualGL はアプリケーションの OpenGL/GLX コマンドを (3D グ...」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

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 のエラーで終了する

If VirtualGL-accelerated 3D rendering does not work (like with the previous section), but in addition you see error messages like...

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.

...in the shell output, then the dynamic linker is correctly receiving instructions to preload the VirtualGL libraries into the application, but something prevents it from successfully performing this task. Two possible causes are:

  • The VirtualGL libraries for the correct architecture are not installed
To run a 32-bit application (like Wine) with VirtualGL, you need to install lib32-virtualgl from the Multilib repository.
  • The application executable has the setuid/setgid flag set
You can confirm whether this is the case by inspecting the executable's file permissions using ls -l: It will show the letter s in place of the user executable bit if setuid is set (for example -rwsr-xr-x), and in place of the group executable bit if setgid is set. For such an application any preloading attempts will fail, unless the libraries to be preloaded have the setuid flag set as well. You can set this flag for the VirtualGL libraries in question by executing the following as root:
$ 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
However, make sure you fully understand the security implications of setuid before deciding to do this in a server environment where security is critical.

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

If your 'client' program is running on the same server as virtualGL (e.g. if you're using virtualGL for VNC), try using vglrun -c proxy.

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

This means that vglgenkey is either not being run at all for your virtualGL X server, or that it is being run again by another X server. For me, lightdm was running vglgenkey on the wrong (vnc remote) X servers, because vglserver_config adds the following:

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

Changing it to

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

so it only runs on the first X server fixed my problem.

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

This means that VirtualGL is trying to load a function from the wrong library. You can specify which OpenGL library to use by setting LD_PRELOAD to the path of the library. /usr/lib/libGL.so appears to work for 64-bit applications. Keep in mind that 32-bit applications (like Steam or Wine) will require 32-bit OpenGL. If you need to use both 32-bit and 64-bit libraries, you can load them both with LD_PRELOAD="/path/to/libGL.so /path/to/lib32/libGL.so".

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

OpenGL has a really low-level and flexible API, which means that different OpenGL applications may come up with very different rendering techniques. VirtualGL's default strategy for how to redirect rendering and how/when to capture a new frame works well with most interactive 3D programs, but may prove inefficient or even problematic for some applications. If you suspect that this may be the case, you can tweak VirtualGL's mode of operation by setting certain environment variables before starting your application with vglrun. For example you could try setting some of the following values (try them one at a time, and be aware that each of them could also make things worse!):

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

A few OpenGL applications also make strong assumptions about their X server environment or loaded libraries, that may not be fulfilled by a VirtualGL set-up - thus causing those applications to fail. The environment variables VGL_DEFAULTFBCONFIG, VGL_GLLIB, VGL_TRAPX11, VGL_X11LIB, VGL_XVENDOR can be used to fix this in some cases.

See the "Advanced Configuration" section in the user manual for a proper explanation of all supported environment variables, and the "Application Recipes" section for info on some specific applications that are known to require tweaking to work well with VirtualGL.

参照