TritonがQEMU WindowsゲストにDirectX 11アクセラレーションをもたらす
Neptuneプロトコルと組み合わせたTriton Windowsドライバーは、DirectX DDIを実装し、それをAPI呼び出しに変換することで、QEMU VMに完全なDirectX 11サポートを提供し、以前のアプローチの落とし穴を回避します。
Neptune Direct3D仮想化レイヤーのチームは、QEMU仮想マシンに完全なDirectX 11アクセラレーションをもたらすWindowsドライバーであるTritonをリリースしました。TritonはNeptuneと連携して、Windowsゲストにハードウェアアクセラレーションされたグラフィックスを提供します。これはQEMUが歴史的に苦労してきた分野です。
Neptuneはハイパーバイザー境界を越えてDirect3D API呼び出しをシリアライズします。元々はLinuxゲスト上のWineゲームを加速するために構築されました。新しいTritonドライバーは、システムDLLを置き換える代わりにDirectXデバイスドライバーインターフェース(DDI)を実装することで、その機能をWindowsゲストに拡張します。
なぜ単にd3d11.dllを置き換えないのか?
QEMUでのWindows GPUアクセラレーションの以前の試みは、アプリケーションと一緒にカスタムのd3d11.dllおよびdxgi.dllファイルを配布することに依存していました。このアプローチには深刻な欠点があります:
- デスクトップウィンドウマネージャー(DWM)がフレームを画像として扱うため、CPUブリッティングが必要となり、パフォーマンスが低下します。
- システムDLLを置き換えるとWindowsが壊れる可能性があり、アンチチートソフトウェアがそのような変更をフラグします。
- ユーザーはすべてのアプリケーションに手動でDLLをコピーする必要があり、ユーザーフレンドリーではありません。
正しいアプローチは、API自体ではなく、Windowsがグラフィックスドライバーと通信するために使用するインターフェースであるDDIを実装することです。
DDIの実装
Windowsでは、アプリケーションはd3d11.dllおよびdxgi.dllと通信します。これらは状態追跡を処理し、DDIを実装するユーザーモードドライバー(UMD)にサニタイズされたコマンドを送信します。UMDはカーネルモードドライバー(KMD)と通信して実際のハードウェアを駆動します。TritonはQEMUの仮想GPU用にUMDとKMDの両方を実装します。
KMD部分はすでに解決されていました:既存のオープンソースプロジェクト(anonymix007とarehnman)がVenus(Vulkan)用のKMDを構築しており、NeptuneはVenusをモデルにしているため、カーネルインターフェースはほぼ同一です。チームはより多くの機能が動作するため、anonymix007のブランチをベースとして選択しました。
難しい部分はDDI自体でした。オープンソースの実装はほとんど存在しません—MesaにはDirectX 10 UMDがあり、VirtualBoxにはDirectX 11 UMDがあります。VirtualBoxのドライバーはDDI呼び出しをバイトコードに変換し、そのバイトコードをホスト上のDirectX API呼び出しに解釈します。チームは互換性バグ、メンテナンス負担、ライセンスの非互換性(GPLv3対MIT/LGPL)のため、このアプローチを拒否しました。
逆変換:DDI → API
DDI呼び出しのための新しいトランスポートを発明する代わりに、TritonはDDI呼び出しをDirectX API呼び出しに変換します。これにより、チームはテスト済みのNeptuneプロトコルを再利用できます—ホスト側では、デシリアライズされたNeptuneコマンドはそのままDirectX 11 API呼び出しであるため、追加の解釈は不要です。これにより、レイテンシとエラーの機会が減少します。
ほとんどのDDI呼び出しには直接的なAPI相当があり、変換は簡単です—マッピングと列挙型ルックアップを処理するだけです。難しい部分はDXBCシェーダーバイトコードですが、Tritonは逆方向に動作するため、シェーダーを逆アセンブルする必要がなく、複雑さが大幅に軽減されます。
結果:macOSホスト上のWindows 11 ARM64ゲストは、QEMUを通じてハードウェアアクセラレーションでCrash Bandicoot Trilogyなどのゲームを実行できます—これはプロジェクトにとって初めてのことです。
正しいアプローチは、DirectX APIを実装することではなく、DirectX DDI(デバイスドライバーインターフェース)を実装することです。