D3D12学习手记The Command Queue and Command Lists

Posted heben

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3D12学习手记The Command Queue and Command Lists相关的知识,希望对你有一定的参考价值。

GPU有一个命令队列,CPU通过Direct3D API将命令提交到队列里来使用命令列表(command lists),如下图。当一套命令(a set of commands)已经被提交到命令队列,他们不会被GPU立刻执行,理解这一点非常重要。由于GPU很可能忙着处理之前插入的命令,所以它们会待在队列里直到GPU准备好处理它们。

技术图片

如果命令队列空了,没有任何工作可做,GPU就会处于空闲状态;另一方面,如果命令队列太满,CPU在某个时刻必须停下来等着GPU追上来。这两种情况都不是我们希望看到的;对于高性能要求的应用,比如游戏,目标是同时保持CPU和GPU的处于繁忙状态以使得能够充分利用硬件资源的优势。

在Direct3D12中,命令队列由接口ID3D12CommandQueue来表示。它是通过填充D3D12_COMMAND_QUEUE_DESC结构来描述队列,然后调用ID3D12Device::CreateCommandQueue来创建的。在本书中,我们通过以下方式来创建我们的命令队列:

Microsoft::WRL::ComPtr<ID3D12CommandQueue> mCommandQueue;
D3D12_COMMAND_QUEUE_DESC queueDesc = ;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
ThrowIfFailed(md3dDevice->CreateCommandQueue(
  &queueDesc, IID_PPV_ARGS(&mCommandQueue)));

其中IID_PPV_ARGS这个帮助宏(helper macro)的定义如下

#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)

其中__uuidof(**(ppType))求值为(**(ppType))的COM接口ID,在上面的代码中是ID3D12CommandQueue。IID_PPV_ARGS_Helper函数实质上将ppType强制转换为void **。 我们在本书中使用了这个宏,这是因为许多Direct3D 12 API调用都要求有一个参数,即我们正在创建的接口的COM ID,并使用void **类型。

 

这个接口中的一个主要函数是ExecuteCommandLists方法,它将命令列表(command lists)中的命令(commands)添加到到命令队列(command queue):

void ID3D12CommandQueue::ExecuteCommandLists( 
  // Number of commands lists in the array
  UINT Count, 
  // Pointer to the first element in an array of command lists
  ID3D12CommandList *const *ppCommandLists);

命令列表(command lists)将会从ppCommandLists的第一个数组元素开始顺序执行

正如上面的方法声明所暗示的,图形的命令列表(a command list for graphics)由ID3D12GraphicsCommandList接口表示,该接口继承自ID3D12CommandList接口。 ID3D12GraphicsCommandList接口有许多方法可以将命令添加到命令列表中。 例如,以下代码添加了设置视口(set the viewport),清除渲染目标视图(clear the render target view)和发出绘制调用(issue a draw call)的命令:

// mCommandList pointer to ID3D12CommandList
mCommandList->RSSetViewports(1, &mScreenViewport);
mCommandList->ClearRenderTargetView(mBackBufferView, 
  Colors::LightSteelBlue, 0, nullptr);
mCommandList->DrawIndexedInstanced(36, 1, 0, 0, 0);

这些方法的名称暗示命令是立即执行的,但实际并不是。上面的代码只是将命令添加到命令列表中。 ExecuteCommandLists方法将命令添加到命令队列,GPU处理来自队列的命令。 在我们阅读本书的过程中,我们将了解ID3D12GraphicsCommandList支持的各种命令。 当我们完成向命令列表添加命令时,我们必须通过调用ID3D12GraphicsCommandList :: Close方法来表明我们已完成命令录制(finished recording commands)。

以上是关于D3D12学习手记The Command Queue and Command Lists的主要内容,如果未能解决你的问题,请参考以下文章

开发手记:JedisConnectionException: Could not get a resource from the pool

D3D12 不可避免的泄漏报告

vim手记

shell编程(手记)

DirectX12(D3D12)基础教程(十九)—— 多实例渲染

linux学习手记