DirectX12を触ってみた(不完全)


DirectX12 (D3D12) を使って画面のクリアまでは簡単にやれるかなと思っていたのですが、そこまでたどり着けませんでした。先日のドキュメント参照しながらやっているだけでは不十分で、ちょっと試行錯誤&ヘッダの探索なども必要でした。

自分の現状ではこんなところですが、これからトライされる方々にちょっとでも参考になればと思って、いくらかメモを残しておこうと思います。以下の項目は自分がとても時間がかかってしまったポイントばかりです。

なお、正式な情報が見当たらないため、ここにある情報も正しいどころか間違っている可能性もとても高いのでその辺はご了承くださいませ。なお以下の話はすべて Win32Application で C++ のみでやってます。

GetDefaultCommandQueue は無い

ドキュメントでは ID3D12Device から GetDefaultCommandQueue なる API があるように書かれていますが、実際のところは存在しません。
これについては、 D3D12_COMMAND_QUEUE_DESC に値をセットして自分で明示的に ID3D12CommandQueue を作成して対処しました。

SwapChainの作成

ドキュメントの方では ID3D12Device から QueryInterface で IDXGIDevice2 インターフェイスを取得するようになっています。しかしながら手元の環境ではこのインターフェースを取得することが出来ませんでした。 WARP デバイスが悪いのかと思い、 GCN 世代のボードと換装してトライしましたが同様の結果でした。
結局のところは CreateDXGIFactory2 関数から IDXGIFactory2 をもらうことでスワップチェインの作成を行っています。

ID3D12CommandListについて

ID3D12CommandList ではなく、 ID3D12GraphicsCommandList を生成する必要があるようです。そうしないと、グラフィックス用のいろいろなメソッドが使用できませんでした。たとえば、 SetDescriptorHeaps, ClearRenderTargetView など。
また、直接はコマンドキューに積めないので、 CommandListCast というキャスト用関数を介してキューに積むようにしています。これもヘッダの中を探索していて発見した関数です。もしかしたらMSDN ドキュメントに記載があったかもしれませんが・・・。

以降は、さらに不確定さ怪しさが高いので、概要だけにしておきます。

ID3D12PipelineStateの生成が難しい

ここも難関でした。適当に D3D12_GRAPHICS_PIPELINE_STATE_DESC に値をセットして生成できるかと思いきや、 VertexShader のシェーダーバイナリが必要になったり、それにつられて InputLayout の情報が必要になったり。さらには ID3D12RootSignature が必要になったりと用意するものがたくさんでした。
もしかすると Descriptor で変な設定(余計な設定)にしてしまったがために、引き起こされたのかもしれません。このあたりの情報がよくわからなくて手こずっていた感もあります。

DescriptorHeapは2つほど用意

RenderTarget 用とシェーダーのリソース用とで2つの DescritprHeap を準備して対処しました。理由はコマンドを準備するときや、 CreateRenderTargetView などを実行したときにデバッグレイヤーから怒られたためです。両方を同時に満たすようなことが出来なかったため、2つの DescriptorHeap にしてしのいでいます。

まとめ

色々とやってみたのですが、画面のクリアまでたどり着けませんでした。 CommandList に積んで ExecuteCommandLists を実行してもエラーが発生しないところまでは到達できましたが、その後の swapChain の Present な部分で怒られてしまいました。
このときのメッセージが以下のようなものです。

まだステート設定の周りで足りてないようです。

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする