功能与用法
DX12 有一个函数,叫做ExecuteIndirect,功能是:
(1)将一组
由CPU指定的命令
(2)用
由GPU指定的参数
(3)执行
由GPU指定的次数
这个函数给予GPU定制命令的能力,利用它可以在GPU端实现视锥体剔除。
ID3D12GraphicsCommandList::ExecuteIndirect 的声明如下:
virtual void STDMETHODCALLTYPE ExecuteIndirect(
_In_ ID3D12CommandSignature *pCommandSignature,
_In_ UINT MaxCommandCount,
_In_ ID3D12Resource *pArgumentBuffer,
_In_ UINT64 ArgumentBufferOffset,
_In_opt_ ID3D12Resource *pCountBuffer,
_In_ UINT64 CountBufferOffset
对应上述功能
功能 | 参数 |
参数类型 |
指定一组命令 | pCommandSignature | ID3D12CommandSignature |
指定命令参数 | pArgumentBuffer | ID3D12Resource |
指定次数 | pCountBuffer | ID3D12Resource |
Argument Buffer 和 Count Buffer 都是普通的 buffer。通常的做法是,在compute shader把在视锥体里面的物体挑选出来,把对应的参数写入 argement buffer,物体个数写入 count buffer,再调用ExecuteIndirect一次过画出来。
Command Signature
Command Signature的作用是指定一组待重复执行
的命令,其在CPU中创建一次,不能被GPU修改。
创建Command Signature的方法是
m_device
->
CreateCommandSignature(&commandSignatureDesc, m_rootSignature.Get(),
IID_PPV_ARGS
(
&
m_commandSignature))
其中commandSignatureDesc指定
它的内部结构,它其实是
D3D12_INDIRECT_ARGUMENT_DESC
的数组,
数组的一个元素表示一条命令。
于
是,
D3D12_INDIRECT_ARGUMENT_DESC
自然就决定了一条命令是怎么指定的。
D3D12_INDIRECT_ARGUMENT_DESC
的数据包括
(1)命令类型
(2)固定参数(可变参数由GPU写入Argument Buffer)
以下是命令类型和对应应该指定的参数
命令
(统一有
D3D12_INDIRECT_ARGUMENT_TYPE_
前缀)
|
固定参数
|
可变参数(由Argument Buffer 指定)
|
对应CommandList函数
|
DRAW
|
|
UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation |
void DrawInstanced( UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation); |
DRAW_INDEXED
|
|
UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, INT BaseVertexLocation, UINT StartInstanceLocation |
void DrawIndexedInstanced( UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, INT BaseVertexLocation, UINT StartInstanceLocation); |
DISPATCH
|
|
UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ |
void Dispatch( UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ); |
VERTEX_BUFFER_VIEW
|
UINT Slot;
|
UINT NumViews, const D3D12_VERTEX_BUFFER_VIEW *pViews |
void IASetVertexBuffers( UINT StartSlot, UINT NumViews, const D3D12_VERTEX_BUFFER_VIEW *pViews); |
INDEX_BUFFER_VIEW
|
|
const D3D12_INDEX_BUFFER_VIEW *pView
|
void IASetIndexBuffer( const D3D12_INDEX_BUFFER_VIEW *pView); |
CONSTANT
|
UINT RootParameterIndex; UINT DestOffsetIn32BitValues; UINT Num32BitValuesToSet; |
void *pSrcData
|
void SetComputeRoot32BitConstants( UINT RootParameterIndex, UINT Num32BitValuesToSet, const void *pSrcData, UINT DestOffsetIn32BitValues); void SetGraphicsRoot32BitConstants( UINT RootParameterIndex, UINT Num32BitValuesToSet, const void *pSrcData, UINT DestOffsetIn32BitValues); |
CONSTANT_BUFFER_VIEW
|
UINT RootParameterIndex;
|
D3D12_GPU_VIRTUAL_ADDRESS BufferLocation
|
void SetComputeRootConstantBufferView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); void SetGraphicsRootConstantBufferView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); |
SHADER_RESOURCE_VIEW
|
UINT RootParameterIndex;
|
D3D12_GPU_VIRTUAL_ADDRESS BufferLocation
|
void SetComputeRootShaderResourceView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); void SetGraphicsRootShaderResourceView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); |
UNORDERED_ACCESS_VIEW
|
UINT RootParameterIndex;
|
D3D12_GPU_VIRTUAL_ADDRESS BufferLocation
|
void SetComputeRootUnorderedAccessView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); void SetGraphicsRootUnorderedAccessView( UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); |