Metal Shading Language コンパイラの使い方
OS X El CapitanからいよいよMacでもMetalが使えるようになりました。 良い機会なので、次にグラフィックスやGPGPU関連の実装が必要になったときはMetalを使ってみようと思い、 とりあえずHello World的なものを書いて入門してみました。 https://github.com/n-yoda/metal-without-xcode
ちょっとしたプログラムのためにIDEでプロジェクトを作ることに何故か抵抗を覚えるので、
コマンドラインで全てを済ませようとした結果、
シェーダーのコンパイルに関してあまり良いドキュメントが無かったので覚書きを以下にまとめておきます。
(追記 15/11/10)普通にドキュメントがありました↓ https://developer.apple.com/library/ios/documentation/Miscellaneous/Conceptual/MetalProgrammingGuide/Dev-Technique/Dev-Technique.html
ちなみに、以下はシェーダーを事前にコンパイルしておく場合の話です。 実行時にコンパイルする場合はnewLibraryWithSource:options:error:を参照。
XCodeを使う場合
公式のサンプルコード をダウンロードしてビルドすればわかりますが、プロジェクト内に.metalファイルを置いておけば、勝手にコンパイルしてくれます。 シェーダーを使う際はnewDefaultLibrary: で読み込めます。
id <MTLDevice> device = ...; id <MTLLibrary> = [device newDefaultLibrary];
コマンドラインでコンパイルしたい場合
公式のサンプルをxcodebuildコマンドでビルドして出力を見て調べたので、あまり意味は理解していませんが、以下で動きました。
1. PATHを通す
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/usr/bin
以下にコンパイラが入っているので、PATHを通しておくと良いでしょう。 Metal and C++11 に書いてあるように、Metalのシェーディング言語はほぼC++11なので実態はLLVM/Clangです。
2. コンパイル
ソース名をshaders.metalとして、それをコンパイルしてshaders.airを出力します。
metal -std=osx-metal1.1 -o shaders.air shaders.metal
ソースに.metal以外の拡張子を付けたい場合*1 は「-x metal」を追加して、
metal -std=osx-metal1.1 -o shaders.air -x metal shaders.cpp
のようにします。 ソース中でC++とMetalを判別して処理を分けたい場合は、
#ifdef __METAL_VERSION__
が使えるみたいですが、公式のドキュメントは見つけていません*2。
その他オプションは Compiler Options を参照。また、Clangで使えるオプションはそのまま使えるみたいですが良くわかりません。
3. アーカイブ
複数の.air(今回は1つ)をアーカイブして.metal-arを作ります。
metal-ar r shaders.metal-ar shaders.air
4. ライブラリの生成
.metal-arから.metallibを生成します。
metallib -o shaders.metallib shaders.metal-ar
5. ライブラリの読み込み
シェーダーを使う際は newLibraryWithFile:error: で読み込みます。
id <MTLDevice> device = ...; NSError *error = nil; id <MTLLibrary> lib = [device newLibraryWithFile: @"shaders.metallib" error:&error]; if (!lib) { NSLog(@"Failed to load library. error %@", error); }