比较multiDrawArrays,在性能方面使用原始重启和multiDrawElements?

时间:2015-03-07 15:22:18

标签: opengl glsl jogl

我想绘制一组具有不同形状的分支,每个分支由4个三角形条组成。 (使用OpenGL)

所以现在我正在考虑使用其中一个方法调用(multiDrawArrays,使用原始重启和multiDrawElements)。

我想知道哪一个更有效率。方法multiDrawArrays()在速度方面相当于几个drawArrays()吗?

当SSBO将这些信息存储在VRAM中时,VAO是否将顶点信息存储在RAM中?如果是这样,考虑到性能,使用SSBO而不是VAO会更好吗?

1 个答案:

答案 0 :(得分:2)

正如@derhass在评论中已经指出的那样,你的一些术语已经混淆了。 VAO(顶点数组对象)包含定义顶点数据如何与顶点属性相关联的状态。它是包含实际顶点数据的VBO(顶点缓冲区对象)。

我怀疑使用SSBO获取顶点数据会有所帮助。通常,缓冲区类型主要定义数据的使用方式。图形管道专门用于从VBO获取顶点数据,许多GPU具有专用的固定功能硬件,用于从VBO中提取数据并将其提供给顶点着色器。我看不出如何在顶点着色器中使用显式代码从SSBO中提取顶点数据会更有效。

数据是存储在VRAM还是SRAM中是一个不同的考虑因素。你唯一的控制就是glBufferData()的最后一个参数。它提供了您计划如何使用数据的提示。例如,如果您指定GL_STATIC_DRAW,则告诉驱动程序您不打算修改数据,这表明将其放在VRAM中可能是个好主意。然后,它是否真的将在VRAM中由驱动程序决定,并且它可以根据各种标准来决定。

从功能上讲,glMultiDrawArrays()相当于对glDrawArrays()的多次调用。但它肯定会更有效率。如果不出意外,它可以节省进行多个API调用的开销。每个API调用都有一定的开销,例如:

  • 它可能会通过几个软件层,导致额外的函数调用。
  • 需要从线程本地存储中获取当前上下文。
  • 需要进行错误检查。
  • 可能需要某种形式的锁定来处理多个线程中多个上下文的访问(绘制调用可能不需要)。
  • 需要检查待处理的状态更改。

引入了MultiDraw次调用以减少所需的API调用次数。

现在,无论glMultiDrawArrays()glDrawElements()原始重启是否更有效,一般都不可能这样说。如果你还没有使用索引缓冲区,我会有点犹豫要介绍一个只是为了你可以使用原始重启。所以我的直觉是:

  • 如果您正在使用索引缓冲区,请使用glDrawElements()和原始重启。
  • 如果您没有使用索引缓冲区,请使用glMultiDrawArrays()

一如既往,真正的答案只能通过基准测试来获得。它当然可以取决于平台/硬件。我的预测是,在大多数情况下你不会看到显着的差异,因为这两种情况都允许你通过单个API调用绘制大量的几何体,这应该避免在这个领域出现瓶颈。