6

我已经阅读了很多关于多线程渲染的内容。人们一直在提出各种奇怪而奇妙的方案来通过线程向 GPU 提交工作,以加快他们的帧速率并渲染更多的东西,但我对整个事情有一点概念上的问题,我以为我会在这里由大师运行它,看看您的想法。

据我所知,GPU 上的基本并发单位是 Warp。也就是说,它在像素级别下降,而不是在几何提交级别更高。因此,鉴于 GPU 上的并发单位是 warp,驱动程序必须使用互斥锁非常紧密地锁定,以防止多个线程搞砸彼此的提交。如果是这种情况,我看不出对 D3D 或 OpenGL 多线程原语进行编码的好处在哪里。

毫无疑问,在多线程场景中使用 GPU 的最有效方法是在更高的抽象级别上,在提交之前,您要收集成批的工作要做吗?我的意思是,与其随机交错来自多个线程的命令,我会认为单个块接受来自多个线程的工作,但在其中有一点智能,以确保在提交给渲染器之前对事物进行排序以获得更好的性能,将是如果您想使用多个线程,则会获得更大的收益。

那么,实际 API 中的 D3D/OpenGL 多线程渲染支持在哪里?

帮助我解决我的困惑!

4

2 回答 2

8

您的问题来自对“使他们的渲染器多线程”和“多线程渲染”之间的区别的误解。

“渲染器”,或者更准确地说是“渲染系统”,不仅仅是向 API 发出渲染命令。它必须对内存进行洗牌。它可能必须动态地将纹理加载到图形内存中或从图形内存中加载出来。在某些渲染过程之后,它可能必须读回数据。等等。

渲染器多线程的意思就是:让渲染系统使用多线程。这可能是线程场景图管理任务,例如构建要渲染的对象列表(平截头体剔除、BSP、门户等)。这可能是有一个专门用于纹理存储管理的线程,它根据需要交换纹理,从磁盘加载等。这可能与命令列表的 D3D11 案例中一样,您可以在其中构建一系列与其他任务并行的渲染命令。

渲染过程,即向API 提交实际渲染命令,不是线程化的。您通常有一个线程负责基本glDraw*::DrawIndexedPrimitive工作。D3D11 命令列表允许您构建这些命令的序列,但它们不会与其他渲染命令并行执行。负责实际发出命令列表的是渲染线程和主上下文;命令列表只是为了使将该列表放在一起对线程更友好。

于 2013-05-28T14:05:27.173 回答
1

在 Direct3D 11 中,您通常会创建延迟上下文,您可以从工作线程向其进行绘制调用。一旦工作完成并准备好渲染,就可以从每个延迟上下文中生成一个命令列表,并在直接(前线程)上下文中执行它。这允许在多个线程中组合绘制调用,同时保持绘制调用的正确顺序等。

于 2013-05-28T14:05:33.200 回答