Opengl es 对YUV图像使用单个纹理还是多个纹理更好

Opengl es 对YUV图像使用单个纹理还是多个纹理更好,opengl-es,opengl-es-2.0,Opengl Es,Opengl Es 2.0,这个问题是针对OpenGL ES 2.0(Android上)的,但对于OpenGL来说可能更一般 归根结底,所有性能问题都取决于实现,但如果有人能够大体上或根据他们的经验回答这个问题,那将很有帮助。我也在写一些测试代码 我有一个YUV(12bpp)图像,我正在加载到片段着色器中的纹理和颜色转换中。一切正常,但我想看看在哪里可以提高性能(以每秒帧数计算) 目前,我正在为每个图像加载三个纹理-一个用于Y分量(类型为GL_亮度),一个用于U分量(类型为GL_亮度,当然是Y分量大小的1/4),一个用于V

这个问题是针对OpenGL ES 2.0(Android上)的,但对于OpenGL来说可能更一般

归根结底,所有性能问题都取决于实现,但如果有人能够大体上或根据他们的经验回答这个问题,那将很有帮助。我也在写一些测试代码

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

目前,我正在为每个图像加载三个纹理-一个用于Y分量(类型为GL_亮度),一个用于U分量(类型为GL_亮度,当然是Y分量大小的1/4),一个用于V分量(类型为GL_亮度,当然是Y分量大小的1/4)

假设我可以得到任何排列的YUV像素(例如,U和V在单独的平面或分散的平面中),将三个纹理合并为两个或一个会更好吗?显然,无论您如何操作,推送到GPU的字节数都是相同的,但如果纹理更少,则开销可能会更小。至少,它将使用更少的纹理单元。我的想法是:

  • 如果U和V像素相互交错,我可以将它们加载到具有两个组件的GL_亮度_ALPHA类型的单一纹理中
  • 我可以将整个YUV图像作为单个纹理加载(类型为GL_亮度,但大小为图像的3/2),然后在片段着色器中,我可以在同一纹理上调用texture2D()三次,做一些算术运算,计算出要传递到texture2D的正确坐标,以获得Y的正确纹理坐标,U和V组件

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

    • 设置绘图调用的状态更改更少
    • 碎片着色器中获取的纹理越少越好
    • 更少的上传时间
    • 来源:

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

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

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

    • “调用
      glTexSubImage
      glCopyTexSubImage
      函数的成本特别高”-上传操作必须暂停管道,直到上传纹理。将这些内容批量上传到一次上传中要比拦截一堆单独的时间要快


    • 你能详细说明/提供2的参考资料吗。谢谢你,贾斯汀。我的测试程序只显示了上传YUV纹理和查找texel的不同方式之间的最小差异,但这仅适用于我测试的特定操作系统/硬件。即使没有性能提升,最小化纹理总数(这样你就不会用完)的论点也是有效的。@DavidStone我想知道你是否可以将其推向极限(使用相同数据的5-6个纹理)以获得一个好的测试。还有,你在测试什么硬件??