gpt4 book ai didi

DirectX 12 中的多线程

转载 作者:行者123 更新时间:2023-12-03 12:59:46 27 4
gpt4 key购买 nike

我很难接受 DX12 中多线程渲染的概念。

根据 MSDN,必须将绘制命令写入直接命令列表(最好使用 bundle ),然后将这些列表提交到命令队列。也有人说,对于直接命令列表,可以有多个命令队列。但我不清楚这样做的目的是什么。

我通过在并行线程中构建命令列表来充分利用多线程,不是吗?如果是这样,我为什么要让多个命令队列与设备相关联?

我怀疑命令队列管理不当会导致渲染库开发后期的性能出现巨大问题。

最佳答案

directx 12 的主要好处是命令的执行几乎是完全异步的。这意味着当您调用 ID3D12CommandQueue::ExecuteCommandLists 时,它将启动传入命令的工作。然而,这带来了另一点。一个常见的误解是现在渲染在某种程度上是多线程的,而这根本不是真的。所有工作仍然在 GPU 上执行。然而,命令列表记录是在多个线程上完成的,因为您将为每个需要它的线程创建一个 ID3D12GraphicsCommandList 对象。

一个例子:

DrawObject DrawObjects[10];
ID3D12CommandQueue* GCommandQueue = ...

void RenderThread1()
{
ID3D12GraphicsCommandList* clForThread1 = ...
for (int i = 0; i < 5; i++)
clForThread1->RecordDraw(DrawObjects[i]);
}

void RenderThread2()
{
ID3D12GraphicsCommandList* clForThread2 = ...
for (int i = 5; i < 10; i++)
clForThread2->RecordDraw(DrawObjects[i]);
}

void ExecuteCommands()
{
ID3D12GraphicsCommandList* cl[2] = { clForThread1, clForThread2 };
GCommandQueue->ExecuteCommandLists(2, cl);
GCommandQueue->Signal(...)
}

这个例子是一个非常粗略的用例,但这是一般的想法。您可以在不同的线程上记录场景的对象,以消除记录命令的 CPU 开销。

然而,另一个有用的事情是,使用此设置,您可以启动渲染任务并开始录制另一个任务。

一个例子

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

与 directx 11 或 opengl 相比,这里的优势在于那些 api 可能只是坐在那里记录和记录,并且可能在调用 Present() 之前不发送它们的命令,这会迫使 cpu 等待,并产生开销.

关于DirectX 12 中的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38748203/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com