为YUV图像使用单个纹理或多个纹理是否更好?

时间:2013-08-07 21:05:00

标签: opengl-es opengl-es-2.0

这个问题适用于OpenGL ES 2.0(在Android上),但对OpenGL来说可能更为通用。

最终,所有性能问题都取决于实现,但是如果有人能够回答这个问题,或者根据他们的经验来回答这些问题会有所帮助。我也在写一些测试代码。

我有一个YUV(12bpp)图像我正在加载到片段着色器中的纹理和颜色转换中。一切正常,但我想看看我可以在哪里提高性能(就每秒帧数而言)。

目前我实际上为每个图像加载了三个纹理 - 一个用于Y组件(类型为GL_LUMINANCE),一个用于U组件(类型为GL_LUMINANCE,当然是Y组件大小的1/4),以及一个用于V组件(GL_LUMINANCE类型,当然是Y组件大小的1/4)。

假设我可以在任何排列中获得YUV像素(例如U和V在不同的平面中或散布),将三个纹理合并为仅两个还是仅一个?显然,无论你如何操作,推送到GPU的字节数都是相同的,但是纹理越少,开销越少。至少,它会使用更少的纹理单位。我的想法:

  • 如果U和V像素相互穿插,我可以将它们加载到GL_LUMINANCE_ALPHA类型的单个纹理中,该纹理有两个组件。
  • 我可以将整个YUV图像加载为单个纹理(类型为GL_LUMINANCE但是图像大小的3/2)然后在片段着色器中我可以在同一纹理上调用texture2D()三次,做一点算术计算出正确的坐标传递给texture2D以获得Y,U和V组件的正确纹理坐标。

1 个答案:

答案 0 :(得分:3)

我会将数据组合成尽可能少的纹理。由于一些原因,较少的纹理通常是更好的选择。

  1. 设置绘制调用的状态更改次数较少。
  2. 片段着色器中提取的纹理越少越好。
  3. 减少上传时间。
  4. <强>来源:

    据我所知,其中一些专注于更具体的硬件,但这些原则适用于大多数移动图形架构。

    Best Practices for Working with Texture Data

    Optimize OpenGL for Tegra

    Optimizing performance of a heavy fragment shader

    1. “绑定到纹理需要花费一些时间来处理OpenGL ES。减少他们对OpenGL ES状态所做的更改次数的应用程序表现更好。”

    2. “根据我的经验,移动GPU性能大致与texture2D来电的数量成正比。” “有两个纹理加载,因此纹理子单元的最小循环次数是两次。” (Tegra有一个纹理单元,必须运行一个循环来达到纹理读取)

    3. “调用glTexSubImageglCopyTexSubImage函数特别昂贵” - 上传操作必须停止管道直到纹理上传。将这些批量处理成单个上传比将阻止大量单独的时间更快。