First, it seems that it is not possible to read from multi-component RWTexture* and RWBuffer objects due to a hardware limitation. However, it is possible to read-write the 32-bit RGBA type thanks to the way D3D handles views.
Create the texture with a
DXGI_FORMAT_R8G8B8A8_TYPELESSformat, then for the unordered access view cast it to
DXGI_FORMAT_R32_UINT. This allows for a common texture format to be read/written without ping ponging, which is great for in-place transformations.
There is another reason why this is not a major limitation. Consider applications whose requirements are reading and writing a texture, but also use shared memory to reduce texture fetching. This most likely means that there is overlapped texture fetching going on (e.g., for an image convolution), and so ping ponging two textures is necessary here anyway to prevent clobbering of data between shaders.
I have found the new structured buffer types to be much more flexible since they are independent of the texture subsystem. It is possible to read/write any structure and any element of a
RWStructuredBuffer. Any shader can read from structured buffers, and the compute and pixel shaders can write to them. According to John Rapp on the DX11 forum, this type also has beneficial performance characteristics.
It should be noted that a structured buffer cannot be bound to the input assembler (not that you'd want to since you can just read from it in a random access manner), and cannot be the output of a stream-out operation. I consider these limitations minimal, since really, the input assembler probably should be going away sometime soon. As for stream out, one can just stream out to a regular
Bufferand read from that.
The March 2009 SDK Direct3D 11 documentation mentions that the
ConsumeStructuredBuffertypes operate similar to a stack in that items are appended and consumed from the end of the buffer. If this is true, this is a very nice property to have. This means it is possible to append to a structured buffer in one pass, and bind it as a plain old
StructuredBufferin another pass (for example, indexed by
SV_InstanceIDin the vertex shader). Or, filling up a
RWStructuredBufferin one pass, then consuming from it in another pass.
I haven't played around too much with the
ByteAddressBuffertype. From my experiments, it seems that
StructuredBufferis the way to go for most things. It seems that these replace
Bufferfor me in most of my applications.