ハイライト
Metal Shader Converter は、DXIL 入出力 Metal IR を受け入れ、バイナリ レベルで HLSL から Metal への変換を完了し、従来のジオメトリ シェーダから最新のメッシュ シェーダまでのすべての段階をサポートし、オフライン GPU バイナリ コンパイルによるランタイム シェーダ コンパイルの遅延を排除できます。
主な内容
シェーダコンバータが必要な理由は何ですか?
Metal コンパイル ツール チェーンは、Metal Shading Language (MSL) を事前に Metal IR にコンパイルし、Metal ライブラリに保存できます。しかし、他のプラットフォームの開発者はすでに多数の HLSL シェーダーを持っており、移行パスが必要です。
Metal Shader Converter はこのギャップを埋めます。 DXIL (DirectX Intermediate Language) を消費し、Metal IR を生成します。オープンソースの DXC コンパイラーと組み合わせることで、完全な HLSL → DXIL → Metal IR パイプラインが形成されます。
変換はバイナリ レベルで行われ、非常に高速であるため、シェーダ アセットのビルド時間が大幅に短縮されます。
(01:27)
サポートされているシェーダー ステージ
Metal Shader Converter は、最新のゲームで使用例されるほぼすべてのシェーダー タイプをカバーします。
- 従来のグラフィックス パイプライン: 頂点シェーダー、フラグメント シェーダー、ジオメトリ シェーダー、テッセレーション
- シェーダの計算
- レイ トレーシング ステージとシェーダー
- 増幅シェーダーとメッシュシェーダー
(02:41)
コマンドラインの使用例法
最も単純な使用例シナリオは、ターミナル経由でシェーダーを 1 つずつ変換することです。
# 1. DXC で HLSL を DXIL にコンパイル
dxc -T ps_6_0 -E main myshader.hlsl -Fo myshader.dxil
# 2. Shader Converter で DXIL を Metal ライブラリへ変換
metal-shaderconverter myshader.dxil -o myshader.metallib
デフォルトの出力には次のものが含まれます。
- メタルライブラリファイル(
.metallib) - JSON リフレクション データ ファイル
実行時に、この Metal ライブラリは Metal デバイスに渡され、パイプライン状態オブジェクトがロードされて構築されます。
(03:06)
動的ライブラリの統合方法
ゲーム エンジンにカスタム アセット ビルダーがある場合、または Windows 上で変換プロセスを統合したい場合は、ダイナミック ライブラリ バージョンを使用例できます。
// 動的ライブラリは純粋な C インターフェイスを提供
// macOS と Windows のどちらでも利用可能
#include <metal_shader_converter.h>
// コンバーターを初期化
MSCConverterRef converter = MSCCreateConverter();
// 変換オプションを設定
MSCConversionOptions options = {};
options.inputFormat = MSCInputFormatDXIL;
options.outputFormat = MSCOutputFormatMetalIR;
// 変換を実行
MSCConvert(converter, dxilData, dxilSize, &options, &metalIR, &metalIRSize);
重要なポイント:
- ダイナミックライブラリとCLIツールの機能は全く同じです
- 純粋な C インターフェイス、既存のコード ベースへの統合が簡単
- macOS と Windows のデュアル プラットフォームのサポート
(04:36)
リソースバインディングモデル
HLSL のリソースは、register 宣言を通じてスロットにバインドされます。 Metal は、より柔軟な Argument Buffer を使用例します。 Shader Converter には 2 つのレイアウト モードが用意されています。
自動レイアウト: リソースは順番に配置され、最も単純です。
明示的なレイアウト: ルート署名と一致し、個別のテクスチャ/サンプラー テーブルまたはバインドレス シナリオに適しています。
// 自動レイアウト: 1 つの Argument Buffer をバインドし、すべてのリソースはそれを通じて参照される
[encoder setVertexBuffer:argumentBuffer offset:0 atIndex:0];
// 明示的レイアウト: root signature の構造に合わせる
struct RootSignature {
MTLResourceID* textureTable;
float* myBuffer;
uint32_t myConstant;
MTLResourceID* samplerTable;
};
引数バッファは CPU と GPU によって共有されるリソースであり、書き込み時に調整されたアクセスが必要です。バンプ アロケータを使用例することをお勧めします。大きなメタル バッファを割り当て、各フレームで中性子からリソースを割り当て、各フレームで処理されるリソース用のシャドウ バッファを作成します。
(05:22)
メッシュ シェーダーにマッピングされたジオメトリとテッセレーション
Metal は最新の API、ビューポート ID、および増幅により、従来のジオメトリ/テッセレーション ステージが不要になります。ただし、ゲームがこれらのパイプラインに依存している場合、手動変換はコストがかかります。
Shader Converter は、ジオメトリとテッセレーション パイプラインをメッシュ シェーダーに自動的にマッピングします。ツールは、従来の固定機能テッセレーターを Metal IR にマッピングするなど、複雑なマッピング タスクを実行します。
今年の Metal の新機能は、目に見える関数をメッシュ シェーダーのオブジェクトおよびメッシュ ステージにリンクする機能です。メッシュ レンダー パイプライン記述子を構築するとき、Metal はすべての Metal IR をコンパイルしてリンクし、すべての関数を単一のパイプラインにベイクし、関数呼び出しのオーバーヘッドを完全に回避します。
(07:16)
##詳細
オフライン GPU バイナリ コンパイル
シェーダを Metal ライブラリにコンパイルするだけでは十分ではありません。実行時にパイプライン状態オブジェクト (PSO) を作成する場合、Metal ライブラリも GPU バイナリにファイナライズする必要があります。この手順は通常、アプリの起動時に実行されるため、読み込み時間が長くなります。オンデマンドのコンパイルを実行時まで遅らせると、フレームレートが低下する可能性があります。
Metal GPU バイナリ コンパイラを使用例すると、ビルド時に GPU バイナリを生成できます。
- Metalライブラリとパイプライン設定スクリプト(JSON形式)を準備する
metal-ttツールを使用例してバイナリ アーカイブを生成します- バイナリ アーカイブをアプリケーションにパッケージ化する
JSON パイプライン スクリプトの例:
{
"libraries": {
"paths": [
{"path": "ba.metallib", "label": "myMetalLib"}
]
},
"pipelines": {
"render_pipelines": [{
"vertex_function": "alias:myMetalLib#v",
"fragment_function": "alias:myMetalLib#f",
"raster_sample_count": 2,
"color_attachments": [{
"pixel_format": "BGRA8Unorm"
}],
"depth_attachment_pixel_format": "Depth32Float"
}]
}
}
重要なポイント:
libraries.pathsは、メタル ライブラリのパスとエイリアスを指定します。pipelines.render_pipelinesはレンダリング パイプライン構成を定義しますvertex_functionおよびfragment_functionはライブラリ内の関数を参照します- その他のフィールドは、Metal API のパイプライン ステータス記述子のプロパティに対応します。
(14:28)
バイナリ アーカイブ ヒットをテストする
公開する前に、バイナリ アーカイブに必要なパイプラインがすべて含まれていることを確認します。
// パイプライン記述子を作成
MTLComputePipelineDescriptor *computeDesc = [MTLComputePipelineDescriptor new];
computeDesc.binaryArchives = @[existingBinaryArchive];
computeDesc.computeFunction = computeFn;
id<MTLComputePipelineState> computePS =
[device newComputePipelineStateWithDescriptor:computeDesc
options:MTLPipelineOptionFailonBinaryArchiveMiss
error:&err];
if (computePS == nil) {
// バイナリアーカイブにこのシェーダーのコンパイル結果がない
NSLog(@"Binary archive miss for compute shader");
}
重要なポイント:
MTLPipelineOptionFailonBinaryArchiveMissは、アーカイブミス時に Metal が nil を返すようにします- オンデバイスコンパイルにフォールバックする代わりに
- これにより、欠落しているパイプライン構成を事前に発見できるようになります。
(16:30)
複数の OS バージョンのサポート
すべてのプレイヤーが最新のシステムを使用例しているわけではありません。 OS のメジャー バージョンごとにバイナリ アーカイブを生成します。
MTLComputePipelineDescriptor *computeDesc = [MTLComputePipelineDescriptor new];
if (@available(macOS 14, *)) {
computeDesc.binaryArchives = @[binaryArchive_macOS14];
} else {
computeDesc.binaryArchives = @[binaryArchive_macOS13_3];
}
computeDesc.computeFunction = computeFn;
id<MTLComputePipelineState> computePS =
[device newComputePipelineStateWithDescriptor:computeDesc
options:nil
error:&err];
重要なポイント:
- 実行時にOSのバージョンを確認する
- 対応するバイナリ アーカイブを選択します
- Metal は、現在の GPU に適切なバイナリをアーカイブから自動的に選択します
(17:03)
重要なポイント
-
やること: Metal Shader Converter を使用例して既存の HLSL シェーダをバッチ変換します
- 䡡値: バイナリ レベル変換、非常に高速、すべてのシェーダ ステージをサポートし、手動での書き換えを不要にします。
- Haigata: DXC と Shader Converter をインストールし、バッチ処理用のシェル スクリプトを作成します:
dxcHLSL を DXIL にコンパイルし、metal-shaderconverterを Metal ライブラリに変換します
-
やること: 実行時のコンパイルラグを排除するために、ビルド時に GPU バイナリをプリコンパイルします。
- 䡡値: プレイヤーはゲーム開始時にシェーダーのコンパイルを待つ必要がなく、ゲーム中のコンパイルによるフレーム レートの低下もありません。
- Haikata: JSON パイプライン スクリプトで
metal-ttツールを使用例して、ビルド フェーズ中にバイナリ アーカイブを生成します
-
やること: ダイナミック ライブラリ バージョンを使用例して、Shader Converter を既存のビルド パイプラインに統合します。
- 䡡価値: 通常、ゲーム エンジンにはカスタム アセット構築プログラムがあり、CLI ツールを統合するのは簡単ではありません。
- Hai Fang:
metal_shader_converterダイナミック ライブラリにリンクし、純粋な C インターフェイスを使用例してメモリ内で変換を完了します
-
やこと: Converter で生成されたライブラリとネイティブ MSL ライブラリの混合使用例
- 䡡値: 段階的に移行できます。最初に既存の HLSL を変換し、新しい関数は MSL で記述され、同じパイプライン内で 2 つを混合できます。
- Haikata: Converter が出力する Metal ライブラリと Metal コンパイラが生成するライブラリの形式はまったく同じであり、直接一緒にロードできます。
関連セッション
- Bring your game to Mac, Part 1: Make a game plan — Game Porting Toolkit を使用例して、Mac 上での Windows ゲームの実現可能性を評価します。
- Bring your game to Mac, Part 3: Render with Metal — Metal での高性能レンダリング
- Optimize GPU renderers with Metal — Metal の最新機能を使用例した最適化された GPU レンダラー
コメント
GitHub Issues · utterances