2025年6月9日月曜日

Barrier

以前拡張バリアの対応を行った。

それまで結構バリア処理で悩んでいて複雑になったになってきたので、修正を機に全部リセットして作り直した。
その際、通常のバリア処理はなくして拡張バリアのみにし、その結果Agility SDKに対応している環境でしか動かなくなった。

というのが今までの状況。

そのうち一般公開されるだろうと思いながら待っていたけど一向にされない。
NvidiaのGPU環境では問題なく動く。
AMDのGPU環境では、Agility SDK対応ドライバを選択して入れてあれば動く。
IntelのGPU環境では、ドライバは対応されているようなことが書いてあるが、少なくとも自分の環境ではそのドライバをインストールに失敗し、拡張バリアはサポートされない状態。

個人的には問題ないんだけど、諸事情でいろいろな環境で動かす必要が出てきたのでAgility SDKなしでも動くようにする。


通常のバリア処理



拡張バリアサポートチェック



起動時に拡張バリアのサポートチェックをして、対応してなかった場合はそこで処理をストップしていた。通常バリアから拡張バリアに完全に切り替えたのでこれで問題なかったが、
これを拡張バリアに対応していない場合でも処理を継続し、両方の環境で動くようにする。

ID3D12Device10::CheckFeatureSupport関数でD3D12_FEATURE_D3D12_OPTIONS12をチェック。
D3D12_FEATURE_DATA_D3D12_OPTIONS12.EnhancedBarriersSupportedの値を保持して、処理を切り替えるようにする。


リソース作成



ID3D12Device10::CreatePlacedResource2でリソースを作っていたけど、通常バリアのモードの場合はID3D12Device::CreatePlacedResourceに切り替える。
D3D12_RESOURCE_DESC1とD3D12_BARRIER_LAYOUTが、D3D12_RESOURCE_DESCとD3D12_RESOURCE_STATESになる。

今のライブラリはCBV、バッファ利用、SRV、テクスチャ利用に分かれているが、CBV、バッファの方は、特に問題なく用意できそう。
昔利用していた時は、リソース種類別に初期のステータスや実行コマンド毎にステータス遷移の制御を行っていたが、バッファに関しては一切の制御を止めて、D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESSに任せることで単純になった。通常のバリアでもそれは同様で、初期ステータスはD3D12_RESOURCE_STATE_COMMONのまま、状態遷移は何もしないようにした。

問題はレンダーターゲットと深度バッファで、このリソースにはD3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESSが指定できないため、自分で制御する必要がある。


コピー時



レンダリングして、結果をテクスチャにコピーするような場合、COPY_SOURCEに遷移してコピー後に、RENDER_TARGETやDEPTH_WRITEに戻しているが、通常バリアでも同様に遷移させる。コピー先に関してはCOPY_DESTで作成するようにしているため遷移不要で、コピー後も拡張バリアではALLOW_SIMULTANEOUS_ACCESSのおかげで何もしなくて済んでいた。
通常バリアではALLOW_SIMULTANEOUS_ACCESSを指定していても多少制御が必要で、コピー後に、ALL_SHADER_RESOURCEに遷移させないとデバッグレイヤにエラーが出力され続ける。


ミップマップ作成時



1.UAV付のテクスチャを用意して、画像をコピー。
2.各ミップマップをCSで縮小コピー。
3.UAV無しのスタティックテクスチャにコピー。
という手順でミップマップを作成している。
ミップマップ作成過程で拡張バリアを使っている箇所で、通常バリアを指定して実行してみるとデバッグレイヤにエラーが表示される。
試行錯誤の結果、通常バリアの場合1から2、2から3の間に、状態遷移を挟む必要があった。
1から2の間には、D3D12_RESOURCE_STATE_COPY_DESTから、D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCEの状態遷移を設定。
2から3の間には、D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCEから、D3D12_RESOURCE_STATE_COPY_SOURCEの状態遷移を設定。
拡張バリアの場合はD3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESSの指定で、かなり自動になったけど、通常バリアの場合は若干制御が増える。






0 件のコメント:

コメントを投稿