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

Dav*_*one 6 opengl-es opengl-es-2.0

这个问题适用于OpenGL ES 2.0(在Android上),但可能更适用于OpenGL.

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

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

目前我实际上为每个图像加载了三个纹理 - 一个用于Y组件(类型为GL_LUMINANCE),一个用于U组件(类型为GL_LUMINANCE,当然为1/4大小为Y组件),另一个用于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组件的正确纹理坐标.

Jus*_*ers 4

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

  1. 设置绘制调用的状态更改更少。
  2. 片段着色器中获取的纹理越少越好。
  3. 更少的上传时间。

资料来源:

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

使用纹理数据的最佳实践

针对 Tegra 优化 OpenGL

优化重片段着色器的性能

  1. “绑定到纹理需要 OpenGL ES 处理时间。减少对 OpenGL ES 状态更改次数的应用程序性能会更好。”

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

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