Training
Learning path
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Indirect drawing enables some scene-traversal and culling to be moved from the CPU to the GPU, which can improve performance. The command buffer can be generated by the CPU or GPU.
The command signature object (ID3D12CommandSignature) enables apps to specify indirect drawing, in particular setting the following:
At startup, an app creates a small set of command signatures. At runtime, the application fills a buffer with commands (via whatever means the app developer chooses). The commands optionally containing state to set for vertex buffer views, index buffer views, root constants and root descriptors (raw or structured SRV/UAV/CBVs). These argument layouts are not hardware specific so apps can generate the buffers directly. The command signature inherits the remaining state from the command list. Then the app calls ExecuteIndirect to instruct the GPU to interpret the contents of the indirect argument buffer according to the format defined by a particular command signature.
If the command signature changes any root arguments, then that's stored within the command signature as a subset of a root signature.
No command signature state leaks back to the command list after the execution is complete. But, after ExecuteIndirect, all bindings are reset to known values. In particular:
As an example of using command signatures: suppose an app developer wants a unique root constant to be specified per-draw call in the indirect argument buffer. The app would create a command signature that enables the indirect argument buffer to specify the following parameters per draw call:
The indirect argument buffer generated by the application would contain an array of fixed-size records. Each structure corresponds to one draw call. Each structure contains the drawing arguments, and the value of the root constant. The number of draw calls is specified in a separate GPU-visible buffer.
An example command buffer generated by the app follows:
The following structures define how particular arguments appear in an indirect argument buffer. These structures do not appear in any D3D12 API. Applications use these definitions when writing to an indirect argument buffer (with the CPU or GPU):
To create a command signature, use the following API items:
The ordering of arguments within an indirect argument buffer is defined to exactly match the order of arguments specified in the pArguments parameter of D3D12_COMMAND_SIGNATURE_DESC. All of the arguments for one draw (graphics)/dispatch (compute) call within an indirect argument buffer are tightly packed. However, applications are allowed to specify an arbitrary byte stride between draw/dispatch commands in an indirect argument buffer.
The root signature must be specified if and only if the command signature changes one of the root arguments.
For root SRV/UAV/CBV, the application specified size is in bytes. The debug layer will validate the following restrictions on the address:
A given command signature is either a draw or a compute command signature. If a command signature contains a drawing operation, then it is a graphics command signature. Otherwise, the command signature must contain a dispatch operation, and it is a compute command signature.
The following sections show some example command signatures.
In this example, the indirect argument buffer generated by the application holds an array of 36-byte structures. Each structure only contains the five parameters passed to DrawIndexedInstanced (plus padding).
The code to create the command signature description follows:
D3D12_INDIRECT_ARGUMENT_DESC Args[1];
Args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
D3D12_COMMAND_SIGNATURE_DESC ProgramDesc;
ProgramDesc.ByteStride = 36;
ProgramDesc.NumArgumentDescs = 1;
ProgramDesc.pArguments = Args;
The layout of a single structure within an indirect argument buffer is:
Bytes | Description |
---|---|
0:3 | IndexCountPerInstance |
4:7 | InstanceCount |
8:11 | StartIndexLocation |
12:15 | BaseVertexLocation |
16:19 | StartInstanceLocation |
20:35 | Padding |
In this example, each structure in an indirect argument buffer changes two root constants, changes one vertex buffer binding, and performs one drawing non-indexed operation. There is no padding between structures.
The code to create the command signature description is:
D3D12_INDIRECT_ARGUMENT_DESC Args[4];
Args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
Args[0].Constant.RootParameterIndex = 2;
Args[0].Constant.DestOffsetIn32BitValues = 0;
Args[0].Constant.Num32BitValuesToSet = 1;
Args[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
Args[1].Constant.RootParameterIndex = 6;
Args[1].Constant.DestOffsetIn32BitValues = 0;
Args[1].Constant.Num32BitValuesToSet = 1;
Args[2].Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW;
Args[2].VertexBuffer.Slot = 3;
Args[3].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
D3D12_COMMAND_SIGNATURE_DESC ProgramDesc;
ProgramDesc.ByteStride = 40;
ProgramDesc.NumArgumentDescs = 4;
ProgramDesc.pArguments = Args;
The layout of a single structure within the indirect argument buffer is the following:
Bytes | Description |
---|---|
0:3 | Data for root parameter index 2 |
4:7 | Data for root parameter index 6 |
8:15 | Virtual address of VB at slot 3 (64-bit) |
16:19 | VB size |
20:23 | VB stride |
24:27 | VertexCountPerInstance |
28:31 | InstanceCount |
32:35 | StartVertexLocation |
36:39 | StartInstanceLocation |
Training
Learning path
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization