25

我读到类似的 API 可以glDrawElementsIndirect帮助glDrawArraysIndirect我们进行间接渲染。间接渲染与直接渲染的不同之处在于,“顶点属性数”、“要绘制的实例数”、“缓冲区对象的起始顶点属性”等渲染参数由 GPU 本身在缓冲区对象中提供,而不是由 GPU 本身提供。由 CPU 在绘图调用中提供。

我明白。它还解释说,优点是渲染速度更快,因为不涉及 CPU 交互。但是等等,实际上进行渲染调用的不是 CPU 吗?它仍然指定渲染模式(GL_TRIANGLES等)。它还可能加载了顶点属性。

那么间接渲染中的所有性能增益是否都可以通过不必传递这些微小的变量来解释:“计数”、“原始计数”、“第一个顶点属性”、“实例计数”?这对我来说没有多大意义。(它也没有改变任何状态)

4

2 回答 2

27

性能提升通常不是因为传递了一些像“计数”或“实例计数”这样的小变量,而是因为知道这些。为了知道这些值,您必须对 CPU 进行一次往返,这只有在结果可用之后才有可能,即在服务器同步之后(加上它增加了总线的延迟)。

假设您正在使用带有几何着色器的变换反馈。这意味着无论你输入什么,你都不知道另一端会出现什么,无论如何,在批次完成并且你已经查询计数之前。
间接渲染解决了这个问题,你不需要知道,实际上你也不想知道。信息进入缓冲区对象,GPU 无需您干预即可访问它。

这类似于条件渲染。实际上,您可以跳过条件渲染的整个过程,不是吗。您可以运行遮挡查询并查看它是否通过,然后决定是否提交您要绘制的那些对象,而不是将命令提交到可能不会被执行的命令队列(多么低效!)。
但这意味着您必须等到查询(以及前一批)完成、同步并执行 PCIe 传输,然后才能做出此决定。在此期间,GPU 可能会停止,然后您仍然没有设置正确的缓冲区/纹理并提交命令。实际上,因此推测性地提交命令并让驱动程序/GPU 决定是否丢弃它们或是否绘制它们的效率要高得多。

这也是 背后的想法ARB_query_buffer_object,它可以让您将查询结果读入缓冲区对象。

编辑:
此外,间接渲染允许更有效地提交渲染命令批处理(尤其是与持久映射结合使用),这可以避免通常存在的大部分或全部服务器/客户端和 CPU/GPU 同步,并且可能来自另一个处理器核心和节省了每次绘制调用的固定开销。参见Cass Everitt 演讲的第 62 页。

于 2013-10-23T14:14:46.503 回答
11

在直接渲染中,CPU 忙于准备索引数据并将其从自己的内存中流出,并通过带宽有限的总线传输到 GPU。它必须检查 GPU 状态并与之同步。这些步骤中的每一个都非常耗时。

使用间接渲染,CPU 所做的只是发送一个简短的命令,启动大量绘图操作。这节省了总线带宽。由于 GPU 将工作更长的时间跨度,因此迫使 CPU 停止当前正在执行的任何操作的中断更少(上下文切换),这意味着复杂的数字任务(如物理模拟)将执行更高的性能。

于 2013-10-23T11:01:58.890 回答