DirectXシェーダーコンパイラをマイクロソフトよりうまく作る
- MicrosoftのDirectXシェーダーコンパイラの複雑な現状と、ゲーム開発者により良い体験を提供するための取り組みについての話。
- MachエンジンのためにZigを使い、WebGPUの後継となる
sysgpu という実験的なグラフィックスAPIを開発中で、Metal、Vulkan、Direct3D、OpenGLバックエンドをサポートする予定。
- Direct3D 12で使用できるシェーダープログラムをコンパイルする必要がある。
DirectXの簡単な歴史
- DirectXグラフィックスAPIは、シェーディング言語としてHLSLを使用する。
- 過去にはDirect3D 11以前で
FXC というコンパイラが使われていたが、遅く、最適化の弱いコード生成で知られていた。
FXCはもはや使われず、Direct3D 12とともにDXCが登場
- Direct3D 12とShader Model 6.0(SM6)のリリースに合わせて、MicrosoftはFXCを廃止し、
DXC という新しいコンパイラを公開した。
- DXCはLLVM/Clang v3.7のMicrosoft公式フォークであり、変更点はコメントで明確に示されている。
DirectXドライバーが朝食として食べるもの: DXBCまたはDXIL
- HLSLはDirect3Dプログラミングで選ばれる言語だが、実際のGPUは多様なコンピュートアーキテクチャと要件を持っている。
- Microsoftは開発者向けのフロントエンドAPIを提供し、各独立系ハードウェアベンダーがドライバーを書いて、実際のハードウェアISAに最も近いものへ変換する。
- DirectX 12とShader Model 6.0の登場により、DXBCの代わりにDXILという新しいフォーマットが使われるようになった。
DXIL
- DXILは現在、DirectX 12ドライバーのメーカーが使用している公式フォーマット。
- ゲーム開発者はDXCコンパイラを使ってDXILバイトコードを生成し、それをグラフィックスドライバーに渡して、GPUハードウェア上で実行される実際のマシンコードへ変換する。
Microsoft LLVMフォークの修正
- Microsoftは、独立系ドライバーベンダーが特定のLLVMビットコード形式を使うのが理想的ではないことを認識しており、LLVMフォークの保守が楽しくないことも認めている。
- Microsoftは、HLSLコンパイル対応をLLVM/Clangへ直接統合する作業を開始した。
ゲーム開発者、WebGPUなどへの課題
- グラフィックス抽象化レイヤーは統一されたシェーディング言語を提供する必要があり、現在の多くのWebGPU実装はHLSLをDXBCまたはDXILへコンパイルする方式を使っている。
簡単な回避策: SPIR-V
- Vulkan/SPIR-Vも似た方式を採用しており、SPIR-Vが最適化されるかどうかはGPUメーカーが決める。
dxcompiler.dll を使うべきか?
- WebGPUランタイムは、新しいDXC HLSLコンパイラを使うか、性能とコード生成品質で劣る正式に廃止されたFXCコンパイラを使うかを判断しなければならない。
なぜ静的リンクできないのか?
- MicrosoftのLLVMフォークは静的リンクをサポートしておらず、その理由はビルドシステムの複雑さにある。
dxil.dll の紹介 - DirectXシェーダー向けの独占的なコード署名ブロブ
dxil.dll はソースからビルドされず、Microsoftの「オープンソース」リポジトリに依存する、プロプライエタリなプラットフォーム別コードブロブに依存している。
プラットフォームサポートの問題
- MicrosoftはWindows(x86/arm)とLinux(x86)向けの
dxil.dll しか配布しておらず、macOSやLinux aarch64向けバイナリは提供していない。
要約
- DXCを静的ライブラリとしてビルドすることはできず、プロプライエタリなコード署名ブロブのためにLLVM機能を復元するのは大規模な作業になる。
- macOSやarm LinuxのCIパイプラインでは、クロスプラットフォームゲーム向けのオフラインシェーダーコンパイルを実行できない。
ビルドシステムの改善
- CMakeビルドシステムを
build.zig に移行し、単一の静的ライブラリとしてビルドする方法を模索した。
動的ライブラリ依存の解消
- DXCコードベースをフォークし、C++コードを修正して動的ライブラリ依存を取り除いた。
プロプライエタリなコード署名への対応
dxil.dll に依存せずにHLSLシェーダーをコンパイルする方法を見つけた。
結果
- プロプライエタリな
dxil.dll に依存しない静的バイナリ版の dxcompiler ライブラリと dxc CLIを提供する。
- macOS、Linux、Windows向けバイナリをCIパイプラインでビルドする。
注意事項
- 一部のバイナリはまだビルドまたはテストされておらず、将来的にはHLSLではなくZig自体をシェーディング言語として使う計画もある。
個人的なメモ
- Stephenという名前で、正社員の技術職を得た後、Machエンジンを構築するためにオンラインで活動している。
- FOSSに根ざしており、ツールは自分たちのものであるべきで、それによって力を得られるべきだと信じている。
- みんなのためにMachを作り、高品質なゲームを販売して生計を立てるのが夢だ。
読んでいただきありがとうございます
- machengine.orgを見てみてください。
- 開発を支援して、さらに多くの作業ができるよう後押しすることを検討してください。
- Mach Discordサーバーに参加してください。
- GitHubでスポンサーしてください。
- machengine.org
GN⁺の意見
- この記事で最も重要なのは、MicrosoftのDirectXシェーダーコンパイラDXCの複雑さと限界を乗り越えようとする開発者コミュニティの努力である。
- Machエンジンの開発者がZigを使ってDXCのビルドシステムを改善し、プロプライエタリな
dxil.dll に依存しない形でHLSLシェーダーをコンパイルする新しいアプローチを提示したことで、クロスプラットフォームゲーム開発に重要な貢献をしている。
- この記事は、オープンソースソフトウェアの重要性と、開発者が自分のツールを所有し制御できるべきだという点を強調し、技術コミュニティにおける協業と革新の価値を示している。
1件のコメント
Hacker Newsの意見
3D APIのシェーダーコンパイルの複雑さに関する優れた概観
Godotに関連する問題
dxil.dllライブラリに依存している。追加の
.dll配布に関する議論.dllを配布することは珍しいことではない。.DLLを要求する。dxil.dllを含めている。dxil.dllの出力とビット単位で同一であることを考えると、驚くべきものだ。DXIL.dllの署名に関する質問
DXIL.dllが行う署名は、単なる改変版MD5なのか?LLVMのコード生成レイヤーとインフラに対するDXCの変更
Machエコシステムへの助言
mach-sysgpuを調べることを勧めている。これはWebGPUの完全な再実装であり、主に17歳のAli Chraghiによって書かれている。SDL_gpuとSDL3に関する議論
SDL_gpuという新しいシェーダー言語を開発中である。Zig言語の活用
インフラ作業への感謝
DXILの発音への言及
pをdに置き換えたものと同じだ。