DirectX12 の SRV と UAV の違い

SRV と UAV の使い方のお作法がたまに分からなくなる。使っていないと分からなくなりますね (ただの言い訳で初めからきちんと理解していない)

元々は Structured Buffer って Shader Resource View として register(#t) にバインド出来るんだっけ?という事が分からなかった。結論から言えば、Structured Buffer は #t でバインドして読み込まないといけない。

それと Structured Buffer のようなデータを #t で使わずに、同じようなデータを #b にして良いのでは?という思いもある。別に UAV 使わなければ CBV で良い。

UAV から SRV へ

あるバッファを SRV として作成する場合は、D3D12_RESOURCE_DESC の Flags には特に何も指定せず D3D12_RESOURCE_FLAG_NONE で作成する。これで HLSL のリソースとして register(#t) にバインド出来る。

UAV を作成する場合は、Flags に D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS を指定する。ただ UAV Flag をつけると、メモリレイアウトの問題で付けていない場合と比べてアクセス速度が低下するらしい (MS doc)。

ある Structured Bufferを Compute Shader で書き込み、それを Pixel Shader で読み込みたい場合などは RWStructuredBuffer : register(#u) で CS 上で書き込みを行い、読み込む場合は (RW無しの) StructuredBuffer : register(#t) で読み込める。

RW 系バッファと UAV

RWTexture2D や RWStructuredBuffer など、RW 系バッファは UAV として register(#u) にバインドする。これは、Pixel Shader でも Compute Shader でも一緒。読み込みを行わない Read Only の場合は SRV として register(#t) にバインドする。

Byte Address Buffer

Raw Buffer を直接扱えるバッファータイプ。生のメモリーに直接指定してアクセスって今はそうそう機会が無く、殆どの場合 StructuredBuffer でも代用できるのでそちらを使う事が多かったりする。

Buffer と ByteAddressBuffer の違い

って何だ? Buffer と ByteAdressBuffer は SRV として register(#t) でアクセス出来、RWBuffer と RWByteAddressBuffer は UAV として register(#u) でアクセス出来る。

ByteAddressBuffer は Byte のオフセットでメモリーにアクセス出来るが 4 バイト単位が必須。(Buffer の場合はインデックス値でアクセス) 返ってくるのは uint 型のみなので、自分で変換をかける必要がある。

ByteAddressBuffer には、Load4 メソッドがあるが、これは指定したアドレスから、uint 型4つ (16byte) ロードされるという認識で良いのかな。

Buffer の場合は宣言時に型指定が必要。データアクセスはインデックス値。int, float 単位でデータアクセスする場合は、Buffer で良い。

https://www.gamedev.net/forums/topic/678018-rwbuffer-vs-rwstructuredbuffer-or-rwbyteaddressbuffer/

コメントを残す

メールアドレスが公開されることはありません。