はかせのラボ

私の頭の中を書いていく雑記ブログです

DirectX12 なんか知らん子がたくさん出てきた(´・ω・`)

あいさつ

どうも、はかせです。
前回DirectX12の簡単な概要的なものを
読んでみました。

今回はより細かいところをということで
実際の実装を追ってみました。

そしたら知らんことがたくさん出てきて
前回言ったことを撤回したい気分になってきました(´・ω・`)

まぁ愚痴ってもしゃーないので
やっていきましょう。

今回は
デスクリプタヒープ
ルートシグネチャ
フェンス

以上の三本です。

デスクリプタヒープ

知らん子一号です。

GPUの中にあるデスクリプタなるものを
管理する配列的なサムシング
だそうです。

イメージとしてはこの図が一番わかりやすい気がしました。

f:id:hakase0274:20190927175351p:plain
引用:Direct3D* 12 Overview Part 4: Heaps and Tables | Intel® Software

この図の緑色のがデスクリプタで
中にテクスチャ情報だとかが入ってるそうです。

f:id:hakase0274:20190927175533p:plain
引用:Direct3D* 12 Overview Part 4: Heaps and Tables | Intel® Software

参考コードだとレンダーターゲットビューや深度バッファ作る前に
このデスクリプタヒープ作ってるので扱いは
DirectX11でのViewに相当するのかもしれませんね。

ルートシグネチャ

知らん子二号です。

こいつは何やってるかって言うと
描画リソースの対応付けを行っているそうです。

描画リソースってのは定数バッファやら
テクスチャやそのサンプラーとかですね。

DirectX11やってるときは
サンプラーとかどうやってシェーダに渡してるんだろうとか思ってましたが、
おそらくこいつが内部的にいて良しなにしてくれてたんでしょうね。

だったらそのまま中にいてくれやって感じですが高速化のためには
プログラマー側でうまいことメモリレイアウト弄りたくなるので
出てこざるを得なかったんでしょう。

フェンス

知らん子三号です。

前回描画の仕方で紹介したCommand三兄弟
hakase0274.hatenablog.com

こいつらを呼んだあと
Allocatorに登録されたコマンドの消化を待つ必要があるという話をしました。

フェンスはその待ちを行うものです。

内部的にカウンタを持っており
GPUがそのカウンタをインクリメントします。

CPUではカウンタの値を確認し、
その値が期待値以上になっていれば
コマンドが消化されたと判断し待ちを解除します。

あとがき

今回はDirectX12を勉強して
新しく登場した知らん子三兄弟を調べてみた話でした。

11に比べて12は
GPUに対してかけることができるアプローチが
格段に増えています。

その関係で今まで知らなくても良かったことや
意識しなくても良かったことが良くなくなってしまいました。

パフォーマンスを求めていくと
よりめんどくさくなっていくのはどのプログラムでも同じですね。

それにしてもフェンスは
あの仕組みで本当に大丈夫なのかってのが
イマイチ疑問ですね。

別にCommandQueueは一個しか作れないとかいう縛りはないので、
複数同時に走らせるなんてこともできるはずです。

その場合でもちゃんと意図したとおり
対象のコマンドの消化を検知できるんでしょうか?

先に別のコマンドが終わってカウントアップされて
誤検知とかありそうですけどなんか回避する仕組みがあるんですかね。

まぁその辺りはぶつかったらその時また解決すればいい話ですかね。

それでは今回はこの辺でノシ

参考

私が勉強するために落としているコード
github.com