Opengl 禁用GLSL编译器优化

Opengl 禁用GLSL编译器优化,opengl,glsl,Opengl,Glsl,我正在使用OpenGL 4.2和GLSL 420。我需要防止GLSL编译器优化未使用的制服,因为它们用于偶尔的测试。 我试图提出: #version 420 #pragma optimize (off) ... ...... 但它似乎没有效果。编译器仍然会清理所有未使用的制服。我在Linux上运行NVidia驱动程序v319,使用GeForce 680GTX非活动制服确定是一种优化。这是未扩展的GLSL程序如何工作的结果,它们被编译,然后链接在一起,因为这种实现确切地知道哪些路径有助于实际的管

我正在使用OpenGL 4.2和GLSL 420。我需要防止GLSL编译器优化未使用的制服,因为它们用于偶尔的测试。 我试图提出:

#version 420
#pragma optimize (off)
...
......

但它似乎没有效果。编译器仍然会清理所有未使用的制服。我在Linux上运行NVidia驱动程序v319,使用GeForce 680GTX

非活动制服确定是一种优化。这是未扩展的GLSL程序如何工作的结果,它们被编译,然后链接在一起,因为这种实现确切地知道哪些路径有助于实际的管道输出。一些实现在这方面比其他实现更聪明,如果在片段着色器/变换反馈中不产生任何输出,则将消除程序每个阶段的代码路径(包括统一)

-7.6统一变量——第117页 7.6统一变量

着色器可以声明命名的统一变量,如OpenGL着色语言规范中所述。如果编译器和链接器确定在执行可执行代码时将实际访问统一,则统一被视为活动统一。如果编译器和链接器无法做出结论性决定,则统一将被视为有效

一个实现在多大程度上采用主动统一的定义可以被视为一种优化。。。但这样做的实际过程并非如此。我解释了NV对GLSL的实施如何有效地进行主动一致性确定

我提到了未扩展的GLSL程序,因为单独的着色器对象确实会使事情变得复杂。使用该扩展,每个程序可能正好代表管道的一个阶段,并且无法确定在一个阶段中使用的统一是否对最终输出有影响。按照主动统一的正式定义,当使用SSO时,实施必须假设如果在一个阶段中使用,那么它是主动的


底线是,更改优化级别不会改变此行为。

优化足够严格,可以确保如果有机会使用统一,则不会将其删除,只需在分配统一时测试-1即可。请尝试在运行时不要执行此类测试,因为这会减慢管道速度。但是,在更多的地方阅读,我发现布拉格语对任何人都不适用。你为什么需要这个?每次更改着色器时,都必须重新链接和重新编译,这允许更改任何统一位置。不用的制服也没什么坏处
glGetUniformLocation
对于任何未找到的(优化的)制服将返回-1,
glUniform(-1,…)
为无操作,不是错误。那么,你想解决的实际问题是什么?@ratchetfreak“在分配制服时只需测试-1”-即使这是不必要的。@ChristianRau我会解释。在我的框架中,我在生产中使用了严格的方法,即注意不存在“垃圾”或在发布版本期间对着色器程序发出伪调用。为此,我构造程序对象,使其仅保留对有效制服的引用。因此,尝试传递名称不包含在程序统一缓存中的统一数据会导致异常。但正如我所说,我也做各种各样的测试,而且我不会花太多时间去评论这些东西,所以它在不同的测试用例中都能正常工作……嗯,也许你是对的。此外,我使用单独的着色器对象