VirtualGL
VirtualGL はアプリケーションの OpenGL/GLX コマンドを (3D グラフィックカードにアクセスできる) 別の X サーバーにリダイレクトして、レンダリングされた画像をキャプチャして、アプリケーションを実行している X サーバーに流し込みます。
リモートデスクトップ環境で、サーバー側のハードウェア支援による 3D レンダリングをできるようにするのが VirtualGL の主な用途です。
目次
- 1 インストールとセットアップ
- 2 X11 フォワーディングで VirtualGL を使う
- 3 VNC で VirtualGL を使う
- 4 アプリケーションの実行
- 5 トラブルシューティング
- 5.1 vglrun が "Could not open display" で停止する
- 5.2 vglrun が全く機能しない
- 5.3 vglrun が ld.so のエラーで終了する
- 5.4 vglrun で ERROR: Could not connect to VGL client. で終了する
- 5.5 /etc/opt/VirtualGL/vgl_xauth_key が存在しないというエラー
- 5.6 vglrun が ERROR: VirtualGL attempted to load the real glXCreatePbuffer function and got the fake one instead. で終了する
- 5.7 レンダリングがおかしい、パフォーマンスが低い、アプリケーションエラー
- 6 参照
インストールとセットアップ
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 パッケージをインストール (ただし、サーバーと同じように設定する必要はありません。必要なのは
vglconnect
とvglclient
のバイナリだけです)。 - 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 サーバー。
設定していない場合、 |
他にも様々な環境変数やコマンドラインパラメータで vglrun
を設定できます。詳しくはユーザーマニュアルや vglrun -help
を参照してください。VirtualGL の挙動はさらに以下のどちらのモードが使われているかによって左右されます (vglrun
によって環境に応じて自動的に選択されます):
- VGL Transport - X11 フォワーディングを使用する場合のデフォルト
- このモードでは特別なネットワークプロトコルを使ってレンダリングされた 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 サーバーが画像ストリームの最適化や圧縮を全て扱うようになるため、あなた自身で設定を行う必要があります。
VirtualGL のレンダリングが有効になっていることを確認
アプリケーションを起動する前に VGL_LOGO
環境変数を設定すると、VirtualGL でアプリケーションがレンダリングされたときに OpenGL シーンの右下隅に "VGL" と書かれた小さなロゴが表示されます:
$ VGL_LOGO=1 vglrun glxgears
アプリケーションを実行してもロゴが表示されない場合、VirtualGL が使われておらずアプリケーションはソフトウェアレンダリングで実行されています (下の#トラブルシューティングを参照)。
パフォーマンスの測定
FPS カウンタを表示できる OpenGL プログラムは多数存在しますが、VirtualGL を使う場合、その値はあまり意味を持ちません。あくまでサーバー側でレンダリングしたときのフレームレートを計測するためです。実際にクライアント側に表示されるフレームレートは考慮されません。
ユーザーマニュアルの "Performance Measurement" の章には VirtualGL の画像パイプラインのスループットを計測する方法や、ボトルネック (特に X11 フォワーディングを使用する場合) を見つけ出す方法が載っています。VNC を使用する場合であれば VNC クライアントでフレームレートを確認できるはずです。
トラブルシューティング
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 letters
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.
参照
- VirtualGL Online Documentation (virtualgl パッケージをインストールしている場合
/usr/share/doc/virtualgl/index.html
からも確認できます)