Execute Indirect

Posted dydx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

对应上述功能
功能参数
参数类型
指定一组命令pCommandSignatureID3D12CommandSignature
指定命令参数pArgumentBufferID3D12Resource
指定次数pCountBufferID3D12Resource
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的主要内容,如果未能解决你的问题,请参考以下文章

execute和submit的区别与联系

[Python] Execute a Python Script

ExecutorService.execute()

ThreadPoolExecutor线程池execute和submit的区别

submit和execute的区别

ExecutorService中submit和execute区别