【问题标题】:What are the advantage of using indirect rendering in OpenGL?在 OpenGL 中使用间接渲染有什么好处?
【发布时间】:2013-10-23 06:24:03
【问题描述】:

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

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

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

【问题讨论】:

    标签: opengl opengl-es shader


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 好答案。添加到它以反映问题上的 [opengl-es] 标记:直到 3.0 为止,OpenGL ES 中没有间接绘制,所以现在至少你只能在桌面上执行此操作。 (ES 上也没有几何着色器,所以至少你知道有多少顶点来自你的变换反馈。)
    【解决方案2】:

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

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

    【讨论】:

    • 我的猜测是减少 CPU-GPU 同步点的数量比命令传输速度重要得多。
    • @BartekBanachewicz:确实如此。每个同步点都会导致和中断,这会迫使 CPU 进入(昂贵的)上下文切换。
    猜你喜欢
    • 1970-01-01
    • 2011-04-10
    • 2012-07-09
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多