Search code examples
openglopengl-esglslglsles

Is there a way to check what OpenGL / GLSL extensions are used by a program?


I'm wondering if is there some tool that can check what extensions are you using in a program or in a shader (or what minimun GL version you must to check).

Something like: 'checkGL directory' to get the list of extensions used by a program in a directory.

The output would be something like:

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

Solution

  • I have never done this programatically, but it should be straight forward to do if you rely on compiler errors and have experience parsing XML files. In lieu of an actual existing tool (which I am unaware of), this is how you can implement it yourself.

    Build your program as you would normally, but comment out all includes related to GL (e.g. #include <GL/gl.h> or #include <GL/glew.h>) and then save the compiler error log to a file. Given this error log, you can track down which GL extension and/or core version of GL is required for the missing functions and constants by parsing the OpenGL XML registry.

    I suggest parsing the compiler error log for GL constants, types and functions rather than the source code because the compiler will run it through the pre-processor and this will eliminate a lot of false positives. You can just as easily parse every .c, .cpp, .h, etc. file in a project directory yourself and look for anything that begins with gl* or GL_*, but that will naively include inactive code branches, comments and so forth.


    The XML registry is what Khronos uses to generate the headers on their site and it has very detailed information for every API function, enumerant, typedef and extension if you know how to parse it.

    As-per your example, you will find:

    <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>
    

    This means that in "gl" (desktop GL), GL_MIRRORED_REPEAT is core in version 1.4 and in "gles2" (OpenGL ES 2.0+) it is core in version 2.0.

    Be careful not to read too much into the label "gles2" (this is a fork of OpenGL ES that includes anything ES 2.0 or newer, parse the actual name and number to find out version requirements).

    If you know the enum value of the core constant GL_MIRRORED_REPEAT, then you can lookup all other enums that have that same value and track them back to the respective extensions that were promoted to core.

    Cross reference all extensions that provide 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>
    

    In this case, GL_MIRRORED_REPEAT is provided by GL_ARB_texture_mirrored_repeat and GL_IBM_texture_mirrored_repeat in GL and by GL_OES_texture_mirrored_repeat in GLES 1.x (it is core in ES 2.0).


    Regarding determining minimum version numbers for GLSL shaders, there is no XML file you can parse there. The only real saving grace is that if you set the #version ... directive too low, most GLSL compilers include the required version and/or extension in an error/warning in the shader info log.

    Your best bet is going to be using GLslang (OpenGL Reference Compiler) to validate your shaders with a forced version of 110 (Desktop GL) and 100 (OpenGL ES). It is not as complete as the vendor GLSL compilers, but its output is always consistent regardless what GPU you are using and you should be able to write a parser for it.


    UPDATE:

    I threw together a project in a couple of hours that does roughly what you want, this is some sample output:

    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)
    

    Source code for this project is available on GitHub here.