6

这个问题适用于 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 分量的正确纹理坐标。
4

1 回答 1

3

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

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

资料来源:

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

处理纹理数据的最佳实践

为 Tegra 优化 OpenGL

优化重片段着色器的性能

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

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

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

于 2013-08-08T03:16:21.160 回答