4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NVIDIA環境でも仮想GPUを使用してWaydroidが快適に動かせた話

4
Posted at

はじめに

2ヶ月ほどLinuxでソシャゲを動かすことに全力を尽くしていたのですが、ついにヌルヌル動くようになったので方法をシェア。
NVIDIAではなく、RadeonやIntelといったMesaが使えるGPUに関しては、以下の記事をご覧ください。

やり方

構成の概要

ホストOS上のLinuxの中でQEMUを使ってLinuxのVMを動かし、そのVMの中でLXCコンテナであるWaydroidを動かします。
unnamed (1).jpg

GPU目線だと、ホストOSのNVIDIA GPUをQEMUの機能である仮想GPUに抽象化し、それをLXCコンテナで利用するという感じです。

私の構成の詳細

ホストOS: Ubuntu25.10
VM: QEMU上のUbuntu25.10
Waydroid: Android13
ARMの翻訳レイヤー(任意): libndk

やり方

1. QEMUの環境構築

特に特別なやり方はしていないので省略。
AIや他のサイトに教えてもらってください。
最新のQEMUを使用しているか確認をしてください。特にlibvirglrendererはQEMUと一緒にインストールされていることを確認してください。
ちなみに、今回はQEMUをGUIで操作できるvirt-managerは使わず、CLIから操作します。なのでvirt-managerのインストールは不要です。

2. UbuntuのISOのダウンロード

3. 仮想ディスクを作る

任意でディスクサイズを変えてください。

qemu-img create -f qcow2 ubuntu25.img 42G

4. (任意だけどおすすめ)OVMFをコピーしてくる

VM内のUEFIの設定を保存するためのOVMFを持ってきます。

cp /usr/share/ovmf/OVMF.fd ./

5. VMを起動してOSをインストールする

以下が初回起動用のシェルスクリプトです。

init.sh
#!/bin/bash

BIOS_FILE="./ovmf.fd"

qemu-system-x86_64 \
-enable-kvm \
-M q35 \
-m 8192 -smp 4 -cpu host \
-drive if=pflash,format=raw,file=$BIOS_FILE \
-drive file=ubuntu25.img,if=virtio \
-cdrom ubuntu-25.10-desktop-amd64.iso \
-usb \
-device virtio-tablet \
-device virtio-keyboard \
-device qemu-xhci,id=xhci \
-machine vmport=off \
-device virtio-vga \
-display sdl \
-audiodev pa,id=snd0 -device AC97,audiodev=snd0 \
-net nic,model=virtio-net-pci -net user,hostfwd=tcp::4444-:5555

この時点ではGPUは使用せずソフトウェアレンダリングを使用します。
GPUの設定で動かないのか、他の原因で起動できていないのかを切り分けるためです。
インストール手順は画面の指示にしたがって行ってください。

6. OSインストール後にGPUを使用して起動する

OSインストール後にGPUを使用して起動するには以下のコマンドを使用します。

#!/bin/bash

BIOS_FILE="./ovmf.fd"

qemu-system-x86_64 \
-enable-kvm \
-M q35 \
-m 8192 -smp 4 -cpu host \
-drive if=pflash,format=raw,file=$BIOS_FILE \
-drive file=ubuntu25.img,if=virtio \
-usb \
-device virtio-tablet \
-device virtio-keyboard \
-device qemu-xhci,id=xhci \
-machine vmport=off \
-device virtio-vga-gl \
-display egl-headless,rendernode=/dev/dri/renderD128 \
-display sdl,gl=on \
-audiodev pa,id=snd0 -device AC97,audiodev=snd0 \
-net nic,model=virtio-net-pci -net user,hostfwd=tcp::4444-:5555

※環境によって /dev/dri/renderD128 ではない場合(129など)があるので、ls -l /dev/dri/ コマンドでNVIDIAのデバイスを確認してください

ソフトウェアレンダリングと仮想GPUレンダリングの変更点は以下の通りです。

ソフトウェアレンダリング 仮想GPU コメント
-device virtio-vga -device virtio-vga-gl -glを付け足すことでハードウェアレンダリングを使用している
-display egl-headless,rendernode=/dev/dri/renderD128 eglをヘッドレスモードに。レンダラーノードにGPUデバイスを指定。
-display sdl -display sdl,gl=on gl=onを付け足すことでハードウェアレンダリングを使用している

特にNVIDIA環境下ではegl-headlessを指定することがとても大事です。

7. GPUレンダリングができているか確認する

VM内のUbuntuの設定->システム->このシステムについて->システムの詳細で確認できます
image.png
グラフィックがこのようになっていたら成功

8. waydroidのインストール

以下をご覧ください。

9. (任意)ARMの翻訳レイヤーの導入

ARM専用アプリを動かすときに必要です

おまけ1 ブルアカの動作状況

60fps高設定でもヌルヌル動きます
やる気が出たら動作している動画撮ります

おまけ2 WaydroidとNVIDIA GPUの関係について

なぜホストOSに直接Waydroidを入れてもGPUが動かないのか

結論から言うとNVIDIA GPUはプロプライエタリなので、Android用にビルドし直せないからというのが理由になります。
詳細を以下で説明します。

前提知識1 LXCコンテナとは

WaydroidはLXCコンテナというものを使っています。
コンテナもVMもどちらも仮想化技術ですが、大きな違いは以下の通りです。

  • VM: ホストOSとカーネルを共有しない
  • コンテナ: ホストOSとカーネルを共有する

VMはカーネルをホストと共有していないので、Linux上でWindowsを動かせたりと違うカーネルが動かせたりします。対して、コンテナは同じカーネルのOSになるという縛りが発生しますが、その分軽量になります。

また、コンテナといえばDockerが有名ですが、一般的な利用上のLXCコンテナとDockerコンテナの違いは以下のようになります。

  • LXCコンテナ: initプロセスがsystemdであることが多い
  • Docker: initプロセスがアプリケーションであることが多い

よってアプリケーションを動かすための環境としてDockerがよく使われますが、LXCコンテナはOSの仮想環境として使われることが多いです。なので、Dockerはアプリケーションコンテナ、LXCはシステムコンテナと呼ばれます。
また、LXCと最近のDockerコンテナでは実装方法が全然違うらしいです。

前提知識2 GPUによるドライバーの違い

LinuxでのGPUドライバーは以下のようになっています。
image.png

下側がカーネルに組み込まれたドライバーで上側はユーザーランド側のドライバーです。
ざっくり言うと、カーネル側はメモリに保存された機械語を受け取るのを担当し、ユーザーランド側はアプリケーションから利用しやすいように整備されたAPI(OpenGLなど)を機械語に変換する役目を負っています。
また、LXCコンテナの境界に関してもユーザーランドとカーネルの境界と同じになります。つまり、上側がLXCコンテナ内で下がユーザーランドとも言えます。
ちなみに上の図はRadeonやIntelのGPUが使用しているMesaのドライバーの図でしたが、下の図はNVIDIAの図となります。
image.png

似てはいますが大きな違いが2つあります。

  • ユーザーランドのドライバーがプロプライエタリである
  • カーネルランドのドライバーがそもそもカーネルにないかもしれない (カーネルだけで処理しておらず、GPU内のチップでも処理することで高速化している)

つまり、NVIDIAのGPUはプロプライエタリのユーザーランドのドライバーを使わないと動かすことができないということです。(有志によるドライバー制作はされていますが、あまりパフォーマンスが出ないというのが現状です)

AndroidのGPU環境

AndroidもLinuxなのでカーネル部分は同じですが、かなりGoogleの独自実装が多くなっています。

image.png

違いは

  • DRM操作のために生えているAPIが通常のlibDRMと異なる
  • OpenGLといったドライバーから生やすAPIもAndroid用に調整が必要

ということです。

さて、ここでまずMesaを動かすことを考えましょう。
幸いにして、Mesaはオープンソースなので自由に改変して調整することが可能です。つまり、Android用にDRM操作の部分と生やすAPIを調整することが可能です。つまり、MesaはAndroidのドライバーとして改造できるということですね。
image.png

今度は、Nvidiaのドライバーを動かすことを考えてみましょう。
Nvidiaドライバーは先程言及したように

  • プロプライエタリなドライバーである
  • NVIDIAのユーザーランド側のドライバーを使わないと動かせない

といった特徴があるので、Mesaのようにドライバーを改変することはできません。
よって、Nvidiaカードを使ってAndroidを動かすのはだいぶ難しいのです。

ちなみに、Android用に調整されたMesaが入ったAndroidイメージはWaydroidに標準装備されています。

仮想GPUで回避する

VMを使うと仮想GPUというものを使えることがあります。
仮想GPUはカーネル内でGPUの処理を行うのではなく、中間言語に変換します。
その中間言語をホストOSで受け取り、GPU処理を行い、その結果をVMに返すことでVM側からGPUを利用できる技術です。
これはLinuxカーネルに組み込まれた技術であり、Mesaにも対応しています。
これを使うことでNvidiaカードでもWaydroidでGPUを動かすことが可能になっています。

image.png

4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?