DirectX12 - Command List(命令列表)

这里是SunshineBooming,GPU公司一枚小小的Driver工程师,主要工作是写DirectX12 Driver,我会持续更新这个DX12 Spec系列,可能比较冷门,但是都是干货和工作中的心得体会,有任何GPU相关的问题都可以在评论区互动,知无不言:

DirectX12 Spec 总目录

1. Command List

1.1 基本概念

  • What Command List?
    A command list is a set of commands which the GPU executes,展开说,就是DX12向GPU下发命令不是立即执行的,所有通过API给GPU下发的命令,都会缓存到Command List中,最后再通过API下发执行Command List这样一个命令,执行之前缓存的所有命令。
  • Why Command List
    答案是提升硬件效率,CPU将所有Command缓存起来集中发送到GPU,是优于DX10/11那种随时下发执行方式(Immediate Context)。

1.2 Direct Command List & Bundle

  • Direct Command List: A direct command list corresponds to a command buffer which the GPU can execute, and dose not inherit any GPU state. Aka transient command Lists(TCLs)
  • Bundle: A bundle can be executed only directly via a direct command list and inherit all GPU state. Aka persistent command lists(PCLs).
  • 怎么理解Bundle
    Direct Command List容易理解,就是可以普通的,GPU可以直接执行的Command列表
    Bundle其实也好理解,我们在重复渲染每一帧画面的时候,发现有一些基本命令是可以重复使用的,我们把这些重复使用的命令打包成一个Bundle,让编译器预编译成GPU可以直接执行的命令,这样可以提升硬件效率。

2. Command Allocator

  • Command allocator corresponds to the underlying allocations in which GPU commands are stored.
    前文提到了,Command需要缓存到Command List中的,这个缓存区域就是Command Allocator,这个其实对应于GPU Driver中的Command Pool,是事先分配好的一块GPU Memory(一般Size可以动态增长)。

3. Command Queue

  • A command queue corresponds to a queue of command lists which the GPU will execute.
    Command Queue类似于一个调度器,如果开发者有多个渲染任务(比如说那种双屏的对战游戏),那么我们可以创建1个Command Queue + 2个Command List,Command List对应2个渲染任务,将其都挂到同一个Command Queue下面进行调度。

4. 小结

  • 可以下图概括Command List、Command Allocator、Command Queue之间的关系。其实总结起来就是:Command List记录Command,Command Allocator分配GPU Memory,Command Queue调度Command List
    Command List&Allocator&Queue

5. API

5.1 Command Allocator

HRESULT CreateCommandAllocator(
  [in]  D3D12_COMMAND_LIST_TYPE type,
        REFIID                  riid,
  [out] void                    **ppCommandAllocator
);
  • 这里主要是用来创建Command Allocator,即存储Command所需要的GPU Memory,给到GPU Driver里面其实就是分配一块Command Buffer内存,一般是64KB对齐、动态增长的。
ID3D12CommandAllocator::Reset()
  • 重置Command Allocator对应的GPU Memory,需要注意的是,对应的Command List需要处于close状态,即结束Record Command过程,否则Reset Command Allocator会返回Runtime错误。

5.2 Command Queue

HRESULT CreateCommandQueue(
  const D3D12_COMMAND_QUEUE_DESC *pDesc,
  REFIID                         riid,
  void                           **ppCommandQueue
);
typedef struct D3D12_COMMAND_QUEUE_DESC {
  D3D12_COMMAND_LIST_TYPE   Type;
  INT                       Priority;
  D3D12_COMMAND_QUEUE_FLAGS Flags;
  UINT                      NodeMask;
} D3D12_COMMAND_QUEUE_DESC;
  • 这里要注意的点就是Command List&Queue&Allocator三者创建的时候,需要Type保持一致,要不然Command List与Command Allocator关联、Command Queue调度Command List时DX12 Runtime都会报错,当然报错的信息打印也都非常清晰。

5.3 Command List

HRESULT CreateCommandList(
  [in]           UINT                    nodeMask,
  [in]           D3D12_COMMAND_LIST_TYPE type,
  [in]           ID3D12CommandAllocator  *pCommandAllocator,
  [in, optional] ID3D12PipelineState     *pInitialState,
  [in]           REFIID                  riid,
  [out]          void                    **ppCommandList
);
  • 创建完Command Allocator后,可以创建Command List并与之关联。
  • 这里要注意的点就是Command List&Queue&Allocator三者创建的时候,需要Type保持一致,要不然Command List与Command Allocator关联、Command Queue调度Command List时DX12 Runtime都会报错。
ID3D12GraphicsCommandList::Close()
  • 结束Command List的Record状态,在进入到Close状态之后,Command List才能提交给Command Queue执行。
  • 需要注意的是,Command List不能进行Close->Close的重复设置,否则Runtime会报错。
ID3D12GraphicsCommandList::Reset()
(
  [in]           ID3D12CommandAllocator *pAllocator,
  [in, optional] ID3D12PipelineState    *pInitialState
);
  • 重置Command List到初始状态,一般Command List状态Init->Record->Close->Submit->Reset这样循环使用。
  • 需要注意的是,Command List在Reset之前必须要进入Close状态,否则Runtime会报错。

5.4 小结

  • 以上列出的都是Command List & Allocator & Queue的一些基本的API,还有更多的API太多了就没有一一列举了。
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值