D3D12_PIPELINE_STATE_STREAM_DESC structure (d3d12.h)

Describes a pipeline state stream.

Syntax

typedef struct D3D12_PIPELINE_STATE_STREAM_DESC {
  SIZE_T SizeInBytes;
  void   *pPipelineStateSubobjectStream;
} D3D12_PIPELINE_STATE_STREAM_DESC;

Members

SizeInBytes

SAL: In

Specifies the size of the opaque data structure pointed to by the pPipelineStateSubobjectStream member, in bytes.

pPipelineStateSubobjectStream

SAL: In_reads(Inexpressible("Dependentonsizeofsubobjects"))

Specifies the address of a data structure that describes as a bytestream an arbitrary pipeline state subobject.

Remarks

Use this structure with the ID3D12Device2::CreatePipelineState method to create pipeline state objects.

The format of the provided stream should consist of an alternating set of D3D12_PIPELINE_STATE_SUBOBJECT_TYPE, and the corresponding subobject types for them (for example, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER pairs with D3D12_RASTERIZER_DESC. In terms of alignment, the D3D12 runtime expects subobjects to be individual struct pairs of enum-struct, rather than a continuous set of fields. It also expects them to be aligned to the natural word alignment of the system. This can be achieved either using alignas(void*), or making a union of the enum + subobject and a void*.

Important

It isn't sufficient to simply union the D3D12_PIPELINE_STATE_SUBOBJECT_TYPE with a void*, because this will result in certain subobjects being misaligned. For example, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY is followed by a D3D12_PRIMITIVE_TOPOLOGY_TYPE enum. If the subobject type is unioned with a void*, then there will be additional padding between these 2 members, resulting in corruption of the stream. Because of this, you should union the entire subobject struct with a void*, when alignas is not available

An example of a suitable subobject for use with D3D12_RASTERIZER_DESC is shown here:

struct alignas(void*) StreamingRasterizerDesc
{
private:
  D3D12_PIPELINE_STATE_SUBOBJECT_TYPE Type = D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER;
public:
  D3D12_RASTERIZER_DESC Desc;
}

The runtime will determine the type of a pipeline stream (valid types being COMPUTE, GRAPHICS, and MESH), by which subobject type, out of VS (vertex shader), CS (compute shader), and MS (mesh shader), is found. If the runtime finds none of these shaders, it will fail pipeline creation. If it finds multiple of these shaders which are not null, it will also fail. This means it is legal to have both, for example, a CS and VS in your stream object, provided only one has a non-null pointer for the shader bytecode for any given call to ID3D12Device2::CreatePipelineState. Subobject types irrelevant to the pipeline (e.g a compute shader subobject in a graphics stream) will be ignored. If a subobject is not provided (excluding the above required subobjects), the runtime will provide a default value for it.

Consider using the d3dx12.h extensions for C++, which provide a set of helper structs for all pipeline subobjects (for example, the above struct is very similar to CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER). This header can be found under the DirectX-Headers repo on github.

Requirements

Requirement Value
Header d3d12.h

See also

Core Structures