MicrosoftがMesh ShaderとAmplification Shaderの仕様を紹介する記事を公開

Microsoftが Windows 10 20H1で追加されるMesh ShaderとAmplification Shaderの仕様を紹介する記事を公開しています.

Coming to DirectX 12— Mesh Shaders and Amplification Shaders: Reinventing the Geometry Pipeline
https://devblogs.microsoft.com/directx/coming-to-directx-12-mesh-shaders-and-amplification-shaders-reinventing-the-geometry-pipeline/

Githubの方には仕様ドキュメントが公開されています.

https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html.

Mesh ShaderとAmplification ShaderはCompute Shaderのルールをベースにした新しいシェーダステージです.頂点シェーダ,テセレーション,ジオメトリシェーダを統合したような形になりますが,Input Assemblyを介さないことで頂点へのアクセスのレイテンシを小さくしたり,インデックスバッファの考え方も大きく変わります.

Mesh Shaderはメッシュの中のデータをチャンク単位で並列化するもので,このチャンクをMeshletと呼ぶようです.旧来のシェーダではInput Assemblyがインデックスバッファを見て頂点シェーダに頂点バッファからのデータを流していましたが,こうした処理はなくなります.

なお,ハードウェアがMesh ShaderをサポートしないGPUでも頂点シェーダへのフォールバックがあり,Meshletをもとにインデックスバッファへの変換がされるようです.

Mesh Shaderの起動にはC++側では DispatchMeshや従来からあるExecureIndirectで呼び出しができます. DispatchMeshの引数はスレッドグループ数になりますのでCompute Shaderとスレッドの考え方が近いです.

Amplification Shader は,Mesh Shaderの前に呼び出されるシェーダです。Amplification Shaderはオプションのため呼び出さないという選択もあり,Mesh Shaderだけ呼ぶということもできます. Amplification Shader はシェーダ内で DispatchMeshを呼び出すことができ,シェーダの中でスレッドグループを指定してMesh Shaderを呼び出すことができます.この時にGroup Shared Memoryを介して Amplification Shader からMesh Shaderにデータを送ることもできます. Group Shared Memory のためOn-ChipなためMesh Shaderからは高速にメモリアクセスができるという点が期待できます.

Amplification Shader の使用シナリオとしては,Meshlet単位でカリングをするなどが提案されています.カリングを通過したMeshletをMesh Shaderに処理させることになります.いわゆるGPU Driven RenderingにおけるCluster Cullingをやります.ジオメトリインスタンシングも Amplification Shader からMesh Shaderをインスタンス数に合わせてスレッド発行することになるんではないかと考えています.

Mesh Shaderの方がプリミティブ処理を行います.Hull ShaderにあったOutputTopologyがあり,このドキュメントを見ている感じでは三角形とラインの指定ができるようです.pointが使えない理由は不明です.

Mesh Shaderが実行されると出力をもとにラスタライザがラスタライズしますが,ラスタライザを起動しないこともでき,その場合はUAVへ計算結果を書きだすなどはできるようです.スキニングやブレンドシェイプみたいなものをキャッシュしておきたいみたいな用途ではラスタライザを起動しないことはありそうですね.

ラスタライザを起動しないMesh Shaderでは,ジオメトリシェーダのようなSteam outputはサポートしないようで可変長な出力には対応しないようです.ただ,将来的にUAVのAppend/Counsumeに対応する可能性について仕様ドキュメントには書かれています.

Mesh Shaderは,Direct3D11までの複雑になったジオメトリ処理をいったん2つのシェーダステージに整理したものになりますが, Amplification Shader はシェーダの中でMesh Shaderを起動することで動的にスレッドを立てるということができ,2段階のCompute Shaderを使ったアルゴリズムが実行できますので,単に統合された以上のことができることが期待できそうです.次の世代のハイエンドゲーム開発では4Kや8K対応などより解像度があがるため複雑なジオメトリを画面に高密度に出したいというニーズが高まることと思いますが,そこに対応するには頂点シェーダからの従来のシェーダからMesh Shaderへの切り替えが必要になるのではないかと思います.