Execute Indirect

功能与用法

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);

你可能感兴趣的:(Execute Indirect)