我很难在DX12中尝试吞下多线程渲染的概念。
根据MSDN,必须将绘图命令写入直接命令列表(最好使用捆绑包),然后将这些列表提交到命令队列。 还有人说,直接命令列表可以有一个以上的命令队列。但我不清楚这样做的目的是什么。
我通过在并行线程中构建命令列表来充分利用多线程,不是吗?如果是这样,为什么我想要有多个与设备关联的命令队列?
我怀疑命令队列管理不当会导致渲染库开发后期的性能出现巨大问题。
答案 0 :(得分:1)
directx 12的主要好处是命令的执行几乎完全是异步的。这意味着当你调用void Render()
{
ID3D12GraphicsCommandList* cl = ...
cl->DrawObjectsInTheScene(...);
CommandQueue->Execute(cl); // Just send it to the gpu to start rendering all the objects in the scene
// And since we have started the gpu work on rendering the scene, we can move to render our post processing while the scene is being rendered on the gpu
ID3D12GraphicsCommandList* cl2 = ...
cl2->SetBloomPipelineState(...);
cl2->SetResources(...);
cl2->DrawOnScreenQuad();
}
时,它将启动传入的命令的工作。但这带来了另一点。一个常见的误解是渲染现在是多线程的,这根本不是真的。所有工作仍然在GPU上执行。但是命令列表记录是在多个线程上完成的,因为您将为需要它的每个线程创建一个ID3D12GraphicsCommandList对象。
一个例子:
{{1}}
这个例子是一个非常粗略的用例,但这是一般的想法。您可以在不同的线程上记录场景的对象,以消除记录命令的CPU开销。
另一个有用的事情是,通过此设置,您可以启动渲染任务并开始录制另一个。
一个例子
{{1}}
这里优于directx 11或opengl的优点是那些apis可能只是坐在那里进行记录和记录,并且可能在调用Present()之前不发送命令,这会强制cpu等待并产生开销