DarkBASIC Professional Help File

DX11 CREATE APPEND CONSUME BUFFER

Creates a structured append/consume buffer.
An append/consume buffer is a special type of structured buffer. It is mainly intended to be used as a writable resource on the GPU and implements a
stack-like behaviour where elements are either removed from the back and returned (“consumed”) or pushed to the back of the structure (“appended”).
This is just a different way of presenting the buffer to your shaders; it cannot grow beyond the number of elements you create it with but rather uses an
internal counter to indicate how many elements are currently in use.
This internal counter can be returned by calling DX11 GET APPEND CONSUME BUFFER ELEMENT COUNT, or set using DX11 SET APPEND CONSUME BUFFER ELEMENT COUNT. If you are filling out data to an
append/consume buffer from the CPU, remember that data is popped from the back by the GPU. Also take note that the buffer will not maintain any particular
element ordering so this should only be used where an element's position within the structure is irrelevant. One example is a particle system where a compute shader
consumes a single particle per thread from an input buffer, updates it and appends the updated version to an output buffer. It may also append more particles to the output
buffer or remove the input particle (by simply not appending it to the output at all) depending on the state of its own particle.
Append/consume buffers are available in both DX10- and DX11 mode.
A structured append/consume buffer is declared like so in HLSL:
`
AppendStructuredBuffer OutputBuffer : register(u0); // This defines an appendable structured buffer. The shader can only append to it, not simultaneously consume from it.
ConsumeStructuredBuffer InputBuffer : register(u1); // This defines an consumable structured buffer. The shader can only consume from it, not simultaneously append to it.
StructuredBuffer DataBuffer : register(t16); // An append/consume buffer that is bound as a read-only resource will appear as a normal structured buffer.
`
Take note that a buffer can only be either appended to or consumed from. This is to ensure there will be no conflicts caused by simultaneous insertions and reads in the multithreaded
shader environment. As such you will probably oftentimes want one input and one output buffer, which requires DX11 hardware. When using an input and an output buffer like this you can
switch them between invocations of the compute / pixel shader to ensure that the previous output buffer becomes the new input buffer, while the old input buffer (that will be considered "empty"
after you have consumed all of its elements) will now act as the output buffer instead.
Buffers can be used to share data between the CPU and GPU and can be bound to the shader pipeline using functions such as DX11 SET OBJECT BUFFER, DX11 SET SPRITE BUFFER, and so forth.
Buffers can be bound to everything that can also have textures bound. When accessed from your shader programs read-only buffers will be bound to registers t16 through t23 (registers t0 through t15 are
reserved for texture resources). Buffers can also be written to by pixel and compute shaders (the other shader stages can not have output resources). The nice thing about this is that you can
write anything to a buffer, at any position, which is different from for example writing to a render target where you will only be able to write to a single pre-defined position. You can also read from
any position within a writable buffer from your shader.
There are however some limitations; a buffer cannot be bound as a read-only resource at the same time as it is bound as a read-only resource. This means that if your pixel shader writes to a certain buffer
that buffer can not be accessed by any other shader stages within the same shader technique. Compute shaders are run in isolation so this limitation does not apply for them.
When using an output buffer with a pixel shader it should also be noted that it shares registers with render targets. In order to find out what register your writable resource will be bound to, all render
targets will be bound first, starting at register u0. After that any writable texture resources are set. Buffers will be bound to the slots after that.
There is also a hardware limitation on how many output resources that can be bound simultaneously; for DX11 this number is 8, meaning that your combined number of render targets, RWTextures and RWBuffers
must not exceed 8. On DX10 hardware you can only have a single output resource however. Since there is always a render target associated with a camera, this means that you cannot use output resources
with your pixel shaders in DX10 compatibility mode. You can still use them in compute shaders however.

Syntax

    Return Dword = DX11 CREATE APPEND CONSUME BUFFER(maxElementCount, elementSize)

Parameters

    maxElementCount

> Dword
> The maximum number of elements that the append/consume buffer can contain. Appending past this number of elements is not possible!.

    elementSize

> Dword
> The size in bytes of each element in the buffer; this should correspond to the byte size of your HLSL element struct.

Returns

The created append/consume buffer.

See also

DIRECTCOMPUTE Functions Menu
DX11 Function Categories