A blog which discusses various GPU applications including visualization, GPGPU and games.

Monday, January 5, 2009

D3D11 Types

Direct3D 11 introduces a number of new datatypes to HLSL.

New read-only types:
  • ByteAddressBuffer
  • StructuredBuffer
New read-write types:
  • RWByteAddressBuffer
  • RWStructuredBuffer
  • RWBuffer
  • RWTexture1D/RWTexture1DArray
  • RWTexture2D/RWTexture2DArray
  • RWTexture3D
New stream types:
  • AppendByteAddressBuffer/ConsumeByteAddressBuffer
  • AppendStructuredBuffer/ConsumeStructuredBuffer
The (RW)ByteAddressBuffer type is a buffer that is DWORD-aligned byte-addressable. What this means is that I can pack an arbitrary mix of scalar and struct types into a buffer, and then pull the data out with a cast.

The (RW)StructuredBuffer type is an extension to the Buffer type in that it allows arbitrary structures to be stored. For example, we might wish to store per-instance data in a structure for cleaner code:

struct Vert
{
float3 color1, color2;
float mixamount;
float3 deform;
};

StructuredBuffer<Vert> data;

PS_INPUT VS(VS_INPUT input)
{
Vert v = data[input.instanceid];
// Use v to compute vertex properties
}

The RWBuffer type is simply an extension to the Buffer type in that it allows reading and writing in pixel and compute shaders.

Next, we have the read-write texture types. These new types will have exciting new possibilities and will eliminate the need to ping-pong two textures in some cases. These types are pixel-addressable.

Finally, we have the stream data types. The stream types are meant for applications that deal with variable amounts of data that need not preserve ordering of records. For example, say we want to emit per-fragment data from the pixel shader, but not into a texture. We can define a structure that describes a fragment, and then we can emit the structures.

struct Fragment
{
float3 color;
float depth;
uint2 location;
};

AppendStructuredBuffer<Fragment> data;

void PS(...)
{
Fragment f;
f.color = ...;
f.depth = ...;
f.location = ...;
data.Append(f);
}

Now say we would like to process each fragment in a compute shader.

struct Fragment
{
float3 color;
float depth;
uint2 location;
};

ConsumeStructuredBuffer<Fragment> data;
RWTexture2D frame;

void CS(...)
{
Fragment f;
data.Consume(f);
// Compute result and write to texture
frame[f.location] = ...;
}

No comments:

Post a Comment

Followers