DirectX12とは?
DirectX12とは主にゲームの開発で使用されるMicrosoftの開発したAPIです。
これまで紹介してきたDirectXとは違い正真正銘の最新バージョンです。
※2020年2月現在
DirectX12は11同様に描画(GPU)制御に特化しています。
以前より更に低レベルな制御を可能としたAPIのため、より高度な最適化が可能です。
業界でも徐々に移行が進んでいますが、開発ではまだDirectX11の使用も多い状況となります。
ただUnrealEngine4やUnityも既にDirectX12への移行が行われているので、今後は更に移行が加速すると思われます。
DirectX12の変更点
DirectX12はDirectX11よりも更に難度が上がっています。
難度が上がっている理由としては先述したように低レベルな制御を可能にしているためです。
DirectX12で大きく変わった所は下記の通りです。
CommandList
実はDirectX11でもCommandListの機能はありましたが、あまり有効活用されていませんでした。
DirectX12ではGPUで実行する命令は全てコマンドリストから行う形となります。
又、複数のコマンドリストを複数スレッドで同時に作成する機能やマルチGPUなどをサポートしています。
Descriptor
DirectX12で新しく入ったDescriptorという概念があります。
DescriptorはGPUとリソースの橋渡しを行う役割を持っています。
※正確には11までは隠蔽されていたが正しいかと思います
この概念にはDescriptor、DescriptorHeap、DescriptorTableと呼ばれる3つが存在します。
Descriptor | テクスチャーなどのリソースをGPUと紐付ける役割を持っています。 リソース作成時に作成することもできれば、描画のタイミングで作成することも可能です。 |
---|---|
DescriptorHeap | DescriptorHeapからDescriptorを作成することができます。 管理できるDescriptorの種類や数は事前に指定することとなります。 Heap上から確保するメモリの管理されないので、ユーザー側で管理を行う必要があります。 |
DescriptorTable | GPU上で使用するDescriptorの数や配置を制御する役割を持っています。 DescriptorHeap内の複数のリソースを使用する場合などもここで制御します。 ※DescripterTableは後述するRootSignatureで設定します。 |
RootSignature
DirectX12に追加された新しい概念のもう一つにRootSignatureというものがあります。
これは先述したDescriptorTableの設定やSamplerの設定を行う役割を持っています。
管理する設定は下記の通りです。
RootParameter | バインドするシェーダタイプやレジスタ、DescripterTable等の設定を行います。 ConstantBufferのレジスタ設定もあります。 |
---|---|
Sampler | DescripterTableで設定したテクスチャーのSampler設定が可能です。 内容についてはDirectX11等と似たような形になっています。 |
PipelineState
最後に大きな変更点としてPipelineStateと呼ばれるものがあります。
PipelineStateは名前の通り描画パイプライン流れを指定する機能となります。
主に下記の内容を管理しています。
Shader | 描画に使用する各種シェーダコードの設定 |
---|---|
RasterizerState | ラスタライズの設定 |
BlendState | ブレンド方法の設定 |
InputLayout | 頂点レイアウトの設定 |
RootSignature | 使用するRootSignatureの設定 |
DepthStencilState | デプスステンシルの設定 |
他にも細かい設定はありますが、描画の一連の流れを指定する機能となります。
DirectX12ではこれらを組み合わせることで一連の描画を行うことになります。
ResourceBarrier
DirectX12の難度を上げている機能の一つにResourceBarrierと呼ばれるものがあります。
ResourceBarrierとは、GPU側で扱うリソースの状況を同期する機能です。
DirectX12はマルチスレッドを前提とした動作をします。
その為、GPU側の動作も複数のアクセスが同時に行われる可能性があります。
そういった際にResourceBarrierを使ってアクセスされるリソースの同期を行ってアクセス順序を保証します。
この辺りは同期される必要のあるリソースが何かはある程度決まりがあるのですが、タイミングを考えないとDirectX11よりもパフォーマンスが悪化するので色々と調整していく必要があります。
この辺りは実際に開発しながらどう最適化していくかを検討する必要があります。