有没有办法检查程序使用哪些OpenGL / GLSL扩展



我想知道是否有一些工具可以检查您在程序或着色器中使用了哪些扩展(或者您必须检查的最小 GL 版本)。

类似于:"checkGL 目录"以获取目录中程序使用的扩展列表。

输出将如下所示:

GL_MIRRORED_REPEAT        - GL_VERSION_1_4 - GL_OES_texture_mirrored_repeat
glUseProgram              - GL_VERSION_2_0 - GL_ES_VERSION_2_0
glEnableVertexAttribArray - GL_VERSION_2_0 - GL_ES_VERSION_2_0

我从来没有以编程方式执行此操作,但是如果您依赖编译器错误并且具有解析 XML 文件的经验,那么它应该很简单。代替实际存在的工具(我不知道),这是您可以自己实现它的方式。

像往常一样构建程序,但注释掉与 GL 相关的所有包含(例如 #include <GL/gl.h>#include <GL/glew.h>),然后将编译器错误日志保存到文件中。给定此错误日志,您可以通过解析 OpenGL XML 注册表来跟踪缺少的函数和常量所需的 GL 扩展和/或核心版本。

我建议解析 GL 常量、类型和函数的编译器错误日志,而不是源代码,因为编译器将通过预处理器运行它,这将消除很多误报。您可以自己轻松地解析项目目录中的每个.c.cpp.h等文件,并查找以gl*GL_*开头的任何内容,但这会天真地包含非活动代码分支、注释等。


XML注册表是Khronos用来在其站点上生成标头的注册表,如果您知道如何解析它,则它具有每个API函数,枚举,typedef和扩展的非常详细的信息。

根据您的示例,您会发现:

<feature api="gl" name="GL_VERSION_1_4" number="1.4">
    <require>
        ...
        <enum name="GL_MIRRORED_REPEAT"/>
        ...
     </require>
</feature>
...
<feature api="gles2" name="GL_ES_VERSION_2_0" number="2.0">
    <require>
        ...
        <enum name="GL_MIRRORED_REPEAT"/>
        ...
     </require>
</feature>

这意味着在"gl"(桌面GL)中,GL_MIRRORED_REPEAT是版本1.4的核心,而在"gles2"(OpenGL ES 2.0+)中,它是版本2.0的核心。

注意不要过多地阅读标签"gles2"(这是OpenGL ES的一个分支,包含任何ES 2.0或更高版本,解析实际namenumber找出版本要求)。

如果您知道核心常量GL_MIRRORED_REPEAT的枚举值,则可以查找具有相同值的所有其他枚举,并将它们追溯到提升为核心的相应扩展。

交叉引用提供GL_MIRRORED_REPEAT (0x8370) 的所有扩展:

<enums namespace="GL" start="0x8370" end="0x837F" vendor="HP">
        <!-- NOTE: IBM is using values in this range, because of a
             bobble when an employee left DEC for IBM at the same
             time as they were assigned the range. their registry
             became inconsistent. It's unknown whether HP has any
             conflicts. They have never reported using any values in
             this range. Lesson: assigned ranges belong to vendors,
             not engineers! -->
    <enum value="0x8370" name="GL_MIRRORED_REPEAT"/>
    <enum value="0x8370" name="GL_MIRRORED_REPEAT_ARB"/>
    <enum value="0x8370" name="GL_MIRRORED_REPEAT_IBM"/>
    <enum value="0x8370" name="GL_MIRRORED_REPEAT_OES"/>
        <unused start="0x8371" end="0x837F" vendor="HP"/>
</enums>
...
<extension name="GL_ARB_texture_mirrored_repeat" supported="gl">
    <require>
        <enum name="GL_MIRRORED_REPEAT_ARB"/>
    </require>
</extension>
<extension name="GL_IBM_texture_mirrored_repeat" supported="gl">
    <require>
        <enum name="GL_MIRRORED_REPEAT_IBM"/>
    </require>
</extension>
<extension name="GL_OES_texture_mirrored_repeat" supported="gles1">
    <require>
        <enum name="GL_MIRRORED_REPEAT_OES"/>
    </require>
</extension>

在这种情况下,GL_MIRRORED_REPEAT由 GL 中的 GL_ARB_texture_mirrored_repeatGL_IBM_texture_mirrored_repeat 以及 GLES 1.x 中的 GL_OES_texture_mirrored_repeat 提供(它是 ES 2.0 中的核心)。


关于确定 GLSL 着色器的最低版本号,没有可以在那里解析的 XML 文件。唯一真正的节省是,如果将#version ...指令设置得太低,则大多数 GLSL 编译器会在着色器信息日志的错误/警告中包含所需的版本和/或扩展名。

最好的选择是使用 GLslang(OpenGL 参考编译器)来验证强制版本 110(桌面 GL)和 100(OpenGL ES)的着色器。它不像供应商的 GLSL 编译器那样完整,但无论您使用什么 GPU,它的输出始终是一致的,您应该能够为其编写解析器。


更新:

我在几个小时内拼凑了一个项目,大致可以满足您的需求,这是一些示例输出:

Enter OpenGL name to search for: GL_MIRRORED_REPEAT
--------------------------------
 >> Enum:   GL_MIRRORED_REPEAT is 0x8370
  * Core in                   GL_VERSION_1_4    (   gl 1.4)
  * Core in                GL_ES_VERSION_2_0    (gles2 2.0)
 >> Enum Alias: GL_MIRRORED_REPEAT_ARB <<
  * Provided by GL_ARB_texture_mirrored_repeat (gl)
 >> Enum Alias: GL_MIRRORED_REPEAT_IBM <<
  * Provided by GL_IBM_texture_mirrored_repeat (gl)
 >> Enum Alias: GL_MIRRORED_REPEAT_OES <<
  * Provided by GL_OES_texture_mirrored_repeat (gles1)

Enter OpenGL name to search for: glEnableVertexAttribArray
--------------------------------
 >> Command:  void glEnableVertexAttribArray (GLuint index)
  * Core in                   GL_VERSION_2_0    (   gl 2.0)
  * Core in                GL_ES_VERSION_2_0    (gles2 2.0)
 >> Command Alias: glEnableVertexAttribArrayARB <<
  * Provided by GL_ARB_vertex_program (gl)

该项目的源代码可在 GitHub 上找到 这里.

最新更新