アヒルのある日

株式会社AHIRUの社員ブログです。毎週更新!社員が自由に思いついたことを書きます。

DirectX12の描画フロー(最適化編)

こんにちは、みにくい社長です。
前回は基礎編でしたが、今回は最適化編です。 DX11で開発していたフレームワークをDX12に切り替えると、大体パフォーマンスが悪くなってしまいます。
本来DX12の方が細かい調整ができるので、より高速化が可能なはずなのですが、その際には注意しなければならないこともあります。
ここでは負荷が高くなりがちな部分から改善点をご紹介します。

■RootSignatureの生成

前回の基礎編でも触れましたが、RootSignatureの生成は非常に重いです。 事前に必要なものを用意して切り替えるという方法は、ゲーム開発で必要なリソースのパターンが大量にあることを考えると現実的ではありません。 基礎編で解説した通り、RootSignatureは1種類だけ作成し、ディスクリプタヒープのインデックスをコピーすることで大幅に高速化が可能です。

■Samplerの生成

テクスチャはリソースして管理しているのが一般的ですが、SamplerはDX11まではその場で設定するのが一般的だったと思います。 しかし、DX12のSamplerの生成はまあまあ高負荷であるため、毎回生成しないようにすることが望ましいです。 事前にパターンを用意しておくのも現実的ではないので、一度生成したものをハッシュマップなどに登録しておき、同じものがあれば再利用することをオススメします。 同じものを検索する負荷が上がってしまうと本末転倒なので、ハッシュ値の計算やハッシュマップの検索方法には注意して実装しましょう。

■GraphicsPipelineStateの生成

こちらもSamplerと同じく、毎回生成するのは高負荷です。一度生成したら、同じものは再利用しましょう。 Samplerに比べると要素が多いのでハッシュ値の計算も煩雑になる可能性がありますが、全ての値が必要とも限らないので、無視できるパラメータはハッシュ値の計算に含めないようにすることで負荷を下げるようにしましょう。

■DebugLayerについて

以上の対策をすれば、DX12でそれなりの速度が出る状態になると思います。 CPUの処理が重い場合はプロファイラで比較的簡単に原因を特定できますが、GPUや見えない部分で負荷がかかっており、原因が特定し辛い場合もあります。 そんな時は、DebugLayerの警告も参考にしてみてください。 警告が出ていても描画はされますが、速度低下の要因を指摘する警告が出ている場合もありますので、警告もできるだけ出なくなるように対処しておきましょう。

目的がはっきりしていない汎用エンジンを作るとなると、最適化は簡単ではありません。 細かい所では他にも最適化すべきポイントはありますが、今回は主な要因を紹介させていただきました。 処理が重たい時は必ず改善できるはず。諦めずに挑戦することで、改善された時の喜びを感じて頂ければと思います。
では、またねー。