【发布时间】:2015-06-23 04:59:22
【问题描述】:
一般来说,仅在着色器中启用 OpenGL ES 扩展是否会降低性能?
我正在编写一些代码,将各种扩展的启用注入到所有着色器的着色器源代码中,无论特定着色器是否需要该扩展。这可能会导致性能损失吗?从概念上讲,它似乎不太可能。
我对 iOS 特别感兴趣。
【问题讨论】:
一般来说,仅在着色器中启用 OpenGL ES 扩展是否会降低性能?
我正在编写一些代码,将各种扩展的启用注入到所有着色器的着色器源代码中,无论特定着色器是否需要该扩展。这可能会导致性能损失吗?从概念上讲,它似乎不太可能。
我对 iOS 特别感兴趣。
【问题讨论】:
在着色器执行方面,仅仅需要扩展没有任何效果。着色器被编译成与 GPU 兼容的格式,#extension(作为预处理器令牌)不会对生成的输出产生任何影响。您可以验证生成的输出在其他 GLES 平台(例如 Android)上的等效性,其中 glGetProgramBinaryOES 可用,并将生成的着色器与没有 #extension 预处理器的着色器进行比较。
GLSL 解析器将有一些额外的工作来解析着色器。对于单个着色器来说,这不太可能需要大量的额外处理时间,但这确实取决于驱动程序的着色器编译器。如果你有大量的着色器,这个累积的额外工作可能会变得很重要。在这种情况下,当您的着色器实际上不需要 #extension 语句时,删除它们可能会有好处。
特别是对于 iOS,着色器编译是经过哈希处理的,因此二进制文件会自动存储以供着色器的后续编译使用,即使跨应用会话也是如此。这意味着您只需在应用程序的第一次运行时“支付”解析器的成本(除非您的着色器是动态的),从而减少了解析器的性能问题。在 Android 上情况并非如此,必须使用 glGetProgramBinaryOES 和 glProgramBinaryOES 显式存储和加载程序二进制文件才能获得相同的行为。
也就是说,需要扩展意味着您将使用它,这可能会对着色器产生很大影响,具体取决于它是哪个扩展以及您正在使用它做什么。 list of iOS GLES extensions 包括一些由#extension 语句启用的(EXT_draw_instanced、EXT_shader_texture_lod、EXT_shader_framebuffer_fetch,...)。很容易想象,使用 EXT_shader_framebuffer_fetch 扩展名对帧缓冲区进行采样的着色器将比不这样做的等效着色器花费更长的时间来执行。
【讨论】: