Be much more strict about extension support
authorMikko Rasa <tdb@tdb.fi>
Tue, 21 Nov 2017 20:13:23 +0000 (22:13 +0200)
committerMikko Rasa <tdb@tdb.fi>
Tue, 21 Nov 2017 20:13:23 +0000 (22:13 +0200)
OpenGL ES has added bits and pieces of full OpenGL functionality, an the
extension generator was thinking an extension was supported when really
only a few tokens from it were.  Now all tokens must be either supported
or explicitly marked as optional for the extension to be made available.

Some features may be temporarily unavailable on OpenGL ES builds as I go
over the extensions and decide how to fix them.

25 files changed:
extensions/arb_depth_texture.glext
extensions/arb_geometry_shader4.glext
extensions/arb_shader_objects.glext
extensions/arb_shadow.glext
extensions/arb_texture_cube_map.glext
extensions/arb_texture_float.glext
extensions/arb_vertex_buffer_object.glext
extensions/arb_vertex_shader.glext
extensions/ext_bgra.glext
extensions/ext_blend_minmax.glext
extensions/ext_blend_subtract.glext
extensions/ext_framebuffer_blit.glext
extensions/ext_framebuffer_multisample.glext
extensions/ext_framebuffer_object.glext
extensions/ext_gpu_shader4.glext
extensions/ext_texture3d.glext
extensions/ext_texture_array.glext
extensions/ext_texture_srgb.glext
extensions/ext_unpack_subimage.glext
extensions/msp_texture1d.glext
extensions/nv_non_square_matrices.glext
gl.fixes.xml
gl.msp.xml [new file with mode: 0644]
scripts/extgen.py
source/framebuffer.h

index 03a9725aaddee37a029d82d0283a7c636bcdc7fa..8b72d00399d414e0d60c707448d139caff942503 100644 (file)
@@ -1 +1,3 @@
 extension ARB_depth_texture
+# Deprecated and not particularly useful
+ignore GL_DEPTH_TEXTURE_MODE_ARB
index 801f39b56b33cabfef457da5840af7651417087b..bc5bc77b2a003136b10fb7cf1856000dd9700846 100644 (file)
@@ -1,3 +1,13 @@
 extension ARB_geometry_shader4
-backport none
+# We use the version from EXT_texture_array
 ignore glFramebufferTextureLayerARB
+# Not promoted to core
+ignore glFramebufferTextureFaceARB
+ignore GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB
+ignore GL_MAX_VERTEX_VARYING_COMPONENTS_ARB
+# Not promoted but required to support the extension flavor of geometry shaders
+optional GL_GEOMETRY_INPUT_TYPE_ARB
+optional GL_GEOMETRY_OUTPUT_TYPE_ARB
+optional GL_GEOMETRY_VERTICES_OUT_ARB
+optional glProgramParameteriARB
+optional GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB
index 7d0ba6455e5a83726183ea3eb8afaefee83fb8a8..96d3fc283d8ea5608cc09f1dce8e4c2496c2165a 100644 (file)
@@ -1 +1,11 @@
 extension ARB_shader_objects
+# Not promoted to core
+ignore glGetHandleARB
+ignore glGetObjectParameterfvARB
+ignore GL_PROGRAM_OBJECT_ARB
+ignore GL_SHADER_OBJECT_ARB
+ignore GL_OBJECT_TYPE_ARB
+ignore GL_OBJECT_SUBTYPE_ARB
+# Rectangular textures have their own extension
+optional GL_SAMPLER_2D_RECT_ARB
+optional GL_SAMPLER_2D_RECT_SHADOW_ARB
index 24e32e2e09c7a76ba9a3a5f0ddf496ad330fe2af..477b7ba786cbc24f7e405f36861a7bc44ed30fb9 100644 (file)
@@ -1 +1,4 @@
 extension ARB_shadow
+# The name got changed in OpenGL 3.0; mark as optional to circumvent the
+# deprecation
+optional GL_COMPARE_R_TO_TEXTURE_ARB
index 892b83933dd31c68036eb72775c7c0ce96b8a349..5423ecfe243017f451c4683513b623afcecc6c8f 100644 (file)
@@ -1,2 +1,4 @@
 extension ARB_texture_cube_map
-backport none
+# Deprecated; related to texture coordinate generation which we don't use
+ignore GL_NORMAL_MAP_ARB
+ignore GL_REFLECTION_MAP_ARB
index 4eea1fc1626cf97b67b1bd245ad2a5062ddc0e0f..ddfb06e3e7f62db74bdb94e350abe068b8f2c046 100644 (file)
@@ -1,2 +1,12 @@
 extension ARB_texture_float
-backport none
+# Alpha, luminance and intensity formats were replaced with R and RG formats
+ignore GL_ALPHA16F_ARB
+ignore GL_LUMINANCE16F_ARB
+ignore GL_LUMINANCE_ALPHA16F_ARB
+ignore GL_INTENSITY16F_ARB
+ignore GL_ALPHA32F_ARB
+ignore GL_LUMINANCE32F_ARB
+ignore GL_LUMINANCE_ALPHA32F_ARB
+ignore GL_INTENSITY32F_ARB
+ignore GL_TEXTURE_LUMINANCE_TYPE_ARB
+ignore GL_TEXTURE_INTENSITY_TYPE_ARB
index e8962591ae42fdbd2195b35d60f62aec1a1c89f1..16d804f3c806e8b16d415217923661f1d836e250 100644 (file)
@@ -1,2 +1,11 @@
 extension ARB_vertex_buffer_object
-backport none
+# Fixed-function arrays are deprecated and we don't query the bindings
+ignore GL_COLOR_ARRAY_BUFFER_BINDING_ARB
+ignore GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB
+ignore GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB
+ignore GL_INDEX_ARRAY_BUFFER_BINDING_ARB
+ignore GL_NORMAL_ARRAY_BUFFER_BINDING_ARB
+ignore GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB
+ignore GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB
+ignore GL_VERTEX_ARRAY_BUFFER_BINDING_ARB
+ignore GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB
index 951fbaae61a1684061dde75fa201cebb8b2543b8..efd91b834c45391f9ce5fdfe7f0b1b403162cf2b 100644 (file)
@@ -1,3 +1,4 @@
 extension ARB_vertex_shader
-secondary ARB_vertex_program
-backport none
+# Deprecated fixed-function interop tokens
+ignore GL_MAX_TEXTURE_COORDS_ARB
+ignore GL_VERTEX_PROGRAM_TWO_SIDE_ARB
index bda98696f77c3420bbeefa15d13e2ebd5f88c2b0..b6f40edc1c95838813b6c13b4415e06ff2366392 100644 (file)
@@ -1,2 +1 @@
 extension EXT_bgra
-backport none
index 62606988a333beed797e56e16d163788605a9e07..4a2d1026769b96c7388df4bc08a7d2e1e5b3741a 100644 (file)
@@ -1,2 +1,3 @@
 extension EXT_blend_minmax
+# Prevent autodetection of ARB_imaging as backport extension
 backport none
index e8af79ad3b473ddb7ef7455f9f515b52e8fdd59d..bf6c282121bce0ff32911fc8315dad367e857de2 100644 (file)
@@ -1,2 +1,3 @@
 extension EXT_blend_subtract
+# Prevent autodetection of ARB_imaging as backport extension
 backport none
index cdc1801bd818e3c5e0de453c1d6a6b59e8ee6e12..4c78ba5188afdba538f9dc2f6dcf57853ac2f16f 100644 (file)
@@ -1,2 +1 @@
 extension EXT_framebuffer_blit
-backport ARB_framebuffer_object
index 272ca3ae7905ec5a0b513bec0a8fd315ff2d9437..91f26a7f02d1aaaebeb7f3a42d6892d2dbec6f4e 100644 (file)
@@ -1,2 +1 @@
 extension EXT_framebuffer_multisample
-backport ARB_framebuffer_object
index 6d5465dfc3c449bd24e35e1c4a25ab3dfa29d910..88f41cb1bb23b73bd3e13e7a68963f51ea4b6767 100644 (file)
@@ -1 +1,4 @@
 extension EXT_framebuffer_object
+# Not promoted; keep them around for more accurate error checking
+optional GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
+optional GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
index 54d1360e871b753692aacc1fd2063c2f6209f0d8..1587535996c56cef8aa4f09fbaa5c3c2e410ee39 100644 (file)
@@ -1 +1,8 @@
 extension EXT_gpu_shader4
+# Buffer textures have their own extension
+optional GL_SAMPLER_BUFFER_EXT
+optional GL_INT_SAMPLER_BUFFER_EXT
+optional GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT
+# Ditto for rectangular textures
+optional GL_INT_SAMPLER_2D_RECT_EXT
+optional GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT
index c1516184dd9801841fa874ef6a34e30bd2243434..e9bc90bb5cb2931d44811fa2e612aefa5267570e 100644 (file)
@@ -1,2 +1 @@
 extension EXT_texture3D
-backport none
index 7051d8ebfd27340d55cbae7d45dbd2f0f6f1c071..a70989aa47230256ebfee90b6031c0f7aedd5b35 100644 (file)
@@ -1,2 +1,3 @@
 extension EXT_texture_array
-backport none
+# We use the version from ARB_shadow
+ignore GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT
index 32fddfbd60d2d59bbb457f3c2730b97d8d6a6bb9..a592cdfa05da9190f2da55690c6752c43535304d 100644 (file)
@@ -1 +1,13 @@
 extension EXT_texture_sRGB
+# Specific compressed formats were not promoted to core
+ignore GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
+ignore GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
+ignore GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
+ignore GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
+# Luminance formats are deprecated
+ignore GL_COMPRESSED_SLUMINANCE_EXT
+ignore GL_COMPRESSED_SLUMINANCE_ALPHA_EXT
+optional GL_SLUMINANCE_EXT
+optional GL_SLUMINANCE_ALPHA_EXT
+optional GL_SLUMINANCE8_EXT
+optional GL_SLUMINANCE8_ALPHA8_EXT
index c366e60418ac5785a634f995753dd20e1233a91c..59318fac3527db6b499ceb80a965fcb78faf5d84 100644 (file)
@@ -1 +1 @@
-extension EXT_unpack_subimage
+extension gles2.EXT_unpack_subimage
index fd77cdc99247d3e75178045365986a44761628d4..00cd9120228ee3d23a516943979ec65bd2f5a767 100644 (file)
@@ -1,2 +1 @@
 extension MSP_texture1D
-core_version gl 1.1
index 9833f47d55065aa426e3efa930392af299909eac..c4f2aa1332cd6dfce556b74c871be462b7462ee1 100644 (file)
@@ -1 +1 @@
-extension NV_non_square_matrices
+extension gles2.NV_non_square_matrices
index a2271d302f44a69c332c84e5ca98e15eb90d573f..e6e14b38e400a8b2aa5caed85ba62d5085e27932 100644 (file)
@@ -9,29 +9,30 @@
         Since we use GL-generated names, it's safe to alias them. -->
         <command>
             <proto><name>glBindFramebufferEXT</name></proto>
-            <alias name="glBindFramebuffer" />
+            <alias name="glBindFramebuffer"/>
         </command>
         <command>
             <proto><name>glBindRenderbufferEXT</name></proto>
-            <alias name="glBindRenderbuffer" />
+            <alias name="glBindRenderbuffer"/>
         </command>
 
         <!-- ARB_shader_objects function names got changed when promoted to
-        core. -->
+        core.  The ARB versions can be used to operate on either shaders or
+        programs, but we use the core names so this is safe. -->
         <command>
             <proto><name>glDeleteObjectARB</name></proto>
-            <alias name="glDeleteShader" />
-            <alias name="glDeleteProgram" />
+            <alias name="glDeleteShader"/>
+            <alias name="glDeleteProgram"/>
         </command>
         <command>
             <proto><name>glGetInfoLogARB</name></proto>
-            <alias name="glGetShaderInfoLog" />
-            <alias name="glGetProgramInfoLog" />
+            <alias name="glGetShaderInfoLog"/>
+            <alias name="glGetProgramInfoLog"/>
         </command>
         <command>
             <proto><name>glGetObjectParameterivARB</name></proto>
-            <alias name="glGetShaderiv" />
-            <alias name="glGetProgramiv" />
+            <alias name="glGetShaderiv"/>
+            <alias name="glGetProgramiv"/>
         </command>
 
         <!-- This alias is missing because the ARB version returns GLhandleARB,
         64-bit macs with shaders only available through the extension. -->
         <command>
             <proto><name>glGetAttachedObjectsARB</name></proto>
-            <alias name="glGetAttachedShaders" />
+            <alias name="glGetAttachedShaders"/>
+        </command>
+
+        <!-- The APPLE version allows user-generated names. -->
+        <command>
+            <proto><name>glBindVertexArrayAPPLE</name></proto>
+            <alias name="glBindVertexArray"/>
         </command>
     </commands>
 
     <enums>
-        <!-- These error codes weren't promoted to core with the rest of
-        EXT_framebuffer_object.  There's no harm in taking them in since
-        they're not passed to GL at any point. -->
-        <enum value="0x8CD9" name="GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"/>
-        <enum value="0x8CDA" name="GL_FRAMEBUFFER_INCOMPLETE_FORMATS"/>
+        <!-- ARB_shader_objects enum names got changed when promoted to core. -->
+        <enum value="0x8B80" name="GL_OBJECT_DELETE_STATUS_ARB" alias="GL_DELETE_STATUS"/>
+        <enum value="0x8B81" name="GL_OBJECT_COMPILE_STATUS_ARB" alias="GL_COMPILE_STATUS"/>
+        <enum value="0x8B82" name="GL_OBJECT_LINK_STATUS_ARB" alias="GL_LINK_STATUS"/>
+        <enum value="0x8B83" name="GL_OBJECT_VALIDATE_STATUS_ARB" alias="GL_VALIDATE_STATUS"/>
+        <enum value="0x8B84" name="GL_OBJECT_INFO_LOG_LENGTH_ARB" alias="GL_INFO_LOG_LENGTH"/>
+        <enum value="0x8B85" name="GL_OBJECT_ATTACHED_OBJECTS_ARB" alias="GL_ATTACHED_SHADERS"/>
+        <enum value="0x8B86" name="GL_OBJECT_ACTIVE_UNIFORMS_ARB" alias="GL_ACTIVE_UNIFORMS"/>
+        <enum value="0x8B87" name="GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB" alias="GL_ACTIVE_UNIFORM_MAX_LENGTH"/>
+        <enum value="0x8B88" name="GL_OBJECT_SHADER_SOURCE_LENGTH_ARB" alias="GL_SHADER_SOURCE_LENGTH"/>
+        <enum value="0x8B89" name="GL_OBJECT_ACTIVE_ATTRIBUTES_ARB" alias="GL_ACTIVE_ATTRIBUTES"/>
+        <enum value="0x8B8A" name="GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB" alias="GL_ACTIVE_ATTRIBUTE_MAX_LENGTH"/>
+
+        <!-- The name got changed but as far as I can tell they mean the same
+        thing. -->
+        <enum value="0x8CD4" name="GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT" alias="GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER"/>
     </enums>
 
-    <feature api="gl" name="MSPGL">
-        <require>
-            <enum name="GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS" />
-            <enum name="GL_FRAMEBUFFER_INCOMPLETE_FORMATS" />
-        </require>
-    </feature>
-
-    <feature api="gles2" name="MSPGLES">
+    <feature api="gl" name="GL_VERSION_1_4" number="1.4">
         <require>
-            <enum name="GL_FRAMEBUFFER_INCOMPLETE_FORMATS" />
+            <!-- All evidence points to this being promoted but it's not marked
+            as such. -->
+            <enum name="GL_BLEND_EQUATION"/>
         </require>
     </feature>
 
-    <feature name="MSPGL_REMOVE">
-        <remove>
-            <!-- These have no counterparts in the core version of
-            ARB_shader_objects. -->
-            <command name="glGetHandleARB" />
-            <command name="glGetObjectParameterfvARB" />
-            <enum name="GL_PROGRAM_OBJECT_ARB" />
-            <enum name="GL_SHADER_OBJECT_ARB" />
-            <enum name="GL_OBJECT_TYPE_ARB" />
-
-            <!-- Ignore this, as it comes from ARB_vertex_program and I'm not
-            sure if it works with ARB_shader_objects. -->
-            <command name="glIsProgramARB" />
-
-            <!-- This was never promoted from ARB_geometry_shader4. -->
-            <command name="glFramebufferTextureFaceARB" />
-        </remove>
-    </feature>
-
     <extensions>
-        <!-- Some functions mentioned in ARB_uniform_buffer_object
-        specification are missing from gl.xml. -->
-        <extension name="GL_ARB_uniform_buffer_object" supported="gl|glcore">
-            <require>
-                <command name="glBindBufferRange" />
-                <command name="glBindBufferBase" />
-            </require>
-        </extension>
-
         <!-- Put GL_RED here for the benefit of OpenGL ES. -->
         <extension name="GL_ARB_texture_rg" supported="gl|glcore">
             <require>
-                <enum name="GL_RED" />
+                <enum name="GL_RED"/>
             </require>
         </extension>
 
         <!-- And the remaining color components here. -->
         <extension name="GL_ARB_texture_swizzle" supported="gl|glcore">
             <require>
-                <enum name="GL_GREEN" />
-                <enum name="GL_BLUE" />
-                <enum name="GL_ALPHA" />
-            </require>
-        </extension>
-
-        <extension name="GL_MSP_legacy_features" supported="gl">
-            <require>
-                <command name="glEnableClientState" />
-                <command name="glDisableClientState" />
-
-                <enum name="GL_QUADS" />
-                <enum name="GL_QUAD_STRIP" />
-                <enum name="GL_LUMINANCE8" />
-                <enum name="GL_LUMINANCE8_ALPHA8" />
-
-                <enum name="GL_AMBIENT" />
-                <enum name="GL_DIFFUSE" />
-                <enum name="GL_SPECULAR" />
-                <enum name="GL_EMISSION" />
-                <enum name="GL_SHININESS" />
-                <enum name="GL_LIGHTING" />
-                <enum name="GL_LIGHT_MODEL_AMBIENT" />
-                <enum name="GL_LIGHT0" />
-                <enum name="GL_MAX_LIGHTS" />
-                <enum name="GL_POSITION" />
-                <enum name="GL_SPOT_DIRECTION" />
-                <enum name="GL_SPOT_EXPONENT" />
-                <enum name="GL_SPOT_CUTOFF" />
-                <enum name="GL_CONSTANT_ATTENUATION" />
-                <enum name="GL_LINEAR_ATTENUATION" />
-                <enum name="GL_QUADRATIC_ATTENUATION" />
-                <command name="glLightModelfv" />
-                <command name="glLightf" />
-                <command name="glLightfv" />
-                <command name="glMaterialf" />
-                <command name="glMaterialfv" />
-
-                <enum name="GL_FOG" />
-                <enum name="GL_FOG_MODE" />
-                <enum name="GL_FOG_DENSITY" />
-                <enum name="GL_FOG_COLOR" />
-                <enum name="GL_EXP" />
-                <command name="glFogi" />
-                <command name="glFogf" />
-                <command name="glFogfv" />
-
-                <enum name="GL_MODELVIEW" />
-                <enum name="GL_PROJECTION" />
-                <command name="glMatrixMode" />
-                <command name="glLoadMatrixf" />
-
-                <!-- Can't reuse EXT_vertex_array for these, as the functions
-                defined there have different signatures. -->
-                <enum name="GL_VERTEX_ARRAY" />
-                <enum name="GL_NORMAL_ARRAY" />
-                <enum name="GL_COLOR_ARRAY" />
-                <enum name="GL_TEXTURE_COORD_ARRAY" />
-                <command name="glVertexPointer" />
-                <command name="glNormalPointer" />
-                <command name="glColorPointer" />
-                <command name="glTexCoordPointer" />
-
-                <command name="glClipPlane" />
-            </require>
-        </extension>
-
-        <!-- OpenGL ES does not have glDrawBuffer. -->
-        <extension name="GL_MSP_draw_buffer" supported="gl">
-            <require>
-                <command name="glDrawBuffer" />
-                <command name="glReadBuffer" />
-            </require>
-        </extension>
-
-        <!-- OpenGL ES does not have harwdare clipping. -->
-        <extension name="GL_MSP_clipping" supported="gl">
-            <require>
-                <enum name="GL_MAX_CLIP_PLANES" />
-                <enum name="GL_CLIP_PLANE0" />
-                <enum name="GL_CLIP_PLANE1" />
-                <enum name="GL_CLIP_PLANE2" />
-                <enum name="GL_CLIP_PLANE3" />
-                <enum name="GL_CLIP_PLANE4" />
-                <enum name="GL_CLIP_PLANE5" />
-            </require>
-        </extension>
-
-        <!-- Stereo rendering is not supported on OpenGL ES, but I'm not
-        certain enough of its uselessness to remove the constants outright. -->
-        <extension name="GL_MSP_stereo_rendering" supported="gl">
-            <require>
-                <enum name="GL_FRONT_LEFT" />
-                <enum name="GL_FRONT_RIGHT" />
-                <enum name="GL_BACK_LEFT" />
-                <enum name="GL_BACK_RIGHT" />
-                <enum name="GL_LEFT" />
-                <enum name="GL_RIGHT" />
-            </require>
-        </extension>
-
-        <!-- Sized internal formats were introduced in OpenGL ES 3.0, but are
-        not available as an extension. -->
-        <extension name="GL_MSP_sized_internal_formats" supported="gl|gles2">
-            <require>
-                <enum name="GL_RGB8" />
-                <enum name="GL_RGBA8" />
-            </require>
-        </extension>
-
-        <!-- 1D textures are not available in OpenGL ES, but could conceivably
-        be added at a later date. -->
-        <extension name="GL_MSP_texture1D" supported="gl">
-            <require>
-                <command name="glTexImage1D" />
-                <command name="glTexSubImage1D" />
-                <enum name="GL_TEXTURE_1D" />
-            </require>
-        </extension>
-
-        <!-- The core version of primitive restart has different semantics
-        from the NV extension but is not available as a backport extension. -->
-        <extension name="GL_MSP_primitive_restart" supported="gl">
-            <require>
-                <enum name="GL_PRIMITIVE_RESTART" />
-                <enum name="GL_PRIMITIVE_RESTART_INDEX" />
-                <command name="glPrimitiveRestartIndex" />
+                <enum name="GL_GREEN"/>
+                <enum name="GL_BLUE"/>
+                <enum name="GL_ALPHA"/>
             </require>
         </extension>
     </extensions>
diff --git a/gl.msp.xml b/gl.msp.xml
new file mode 100644 (file)
index 0000000..cea6395
--- /dev/null
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<registry>
+    <!-- This file defines several fake extensions to facilitate detection
+    of certain core functionalities for which there's no official backport
+    extension. -->
+
+    <extensions>
+        <extension name="GL_MSP_legacy_features" supported="gl">
+            <require>
+                <command name="glEnableClientState" />
+                <command name="glDisableClientState" />
+
+                <enum name="GL_QUADS" />
+                <enum name="GL_QUAD_STRIP" />
+                <enum name="GL_LUMINANCE8" />
+                <enum name="GL_LUMINANCE8_ALPHA8" />
+
+                <enum name="GL_AMBIENT" />
+                <enum name="GL_DIFFUSE" />
+                <enum name="GL_SPECULAR" />
+                <enum name="GL_EMISSION" />
+                <enum name="GL_SHININESS" />
+                <enum name="GL_LIGHTING" />
+                <enum name="GL_LIGHT_MODEL_AMBIENT" />
+                <enum name="GL_LIGHT0" />
+                <enum name="GL_MAX_LIGHTS" />
+                <enum name="GL_POSITION" />
+                <enum name="GL_SPOT_DIRECTION" />
+                <enum name="GL_SPOT_EXPONENT" />
+                <enum name="GL_SPOT_CUTOFF" />
+                <enum name="GL_CONSTANT_ATTENUATION" />
+                <enum name="GL_LINEAR_ATTENUATION" />
+                <enum name="GL_QUADRATIC_ATTENUATION" />
+                <command name="glLightModelfv" />
+                <command name="glLightf" />
+                <command name="glLightfv" />
+                <command name="glMaterialf" />
+                <command name="glMaterialfv" />
+
+                <enum name="GL_FOG" />
+                <enum name="GL_FOG_MODE" />
+                <enum name="GL_FOG_DENSITY" />
+                <enum name="GL_FOG_COLOR" />
+                <enum name="GL_EXP" />
+                <command name="glFogi" />
+                <command name="glFogf" />
+                <command name="glFogfv" />
+
+                <enum name="GL_MODELVIEW" />
+                <enum name="GL_PROJECTION" />
+                <command name="glMatrixMode" />
+                <command name="glLoadMatrixf" />
+
+                <!-- Can't reuse EXT_vertex_array for these, as the functions
+                defined there have different signatures. -->
+                <enum name="GL_VERTEX_ARRAY" />
+                <enum name="GL_NORMAL_ARRAY" />
+                <enum name="GL_COLOR_ARRAY" />
+                <enum name="GL_TEXTURE_COORD_ARRAY" />
+                <command name="glVertexPointer" />
+                <command name="glNormalPointer" />
+                <command name="glColorPointer" />
+                <command name="glTexCoordPointer" />
+
+                <command name="glClipPlane" />
+            </require>
+        </extension>
+
+        <!-- OpenGL ES does not have glDrawBuffer. -->
+        <extension name="GL_MSP_draw_buffer" supported="gl">
+            <require>
+                <command name="glDrawBuffer" />
+                <command name="glReadBuffer" />
+            </require>
+        </extension>
+
+        <!-- OpenGL ES does not have harwdare clipping. -->
+        <extension name="GL_MSP_clipping" supported="gl">
+            <require>
+                <enum name="GL_MAX_CLIP_PLANES" />
+                <enum name="GL_CLIP_PLANE0" />
+                <enum name="GL_CLIP_PLANE1" />
+                <enum name="GL_CLIP_PLANE2" />
+                <enum name="GL_CLIP_PLANE3" />
+                <enum name="GL_CLIP_PLANE4" />
+                <enum name="GL_CLIP_PLANE5" />
+            </require>
+        </extension>
+
+        <!-- Stereo rendering is not supported on OpenGL ES, but I'm not
+        certain enough of its uselessness to remove the constants outright. -->
+        <extension name="GL_MSP_stereo_rendering" supported="gl">
+            <require>
+                <enum name="GL_FRONT_LEFT" />
+                <enum name="GL_FRONT_RIGHT" />
+                <enum name="GL_BACK_LEFT" />
+                <enum name="GL_BACK_RIGHT" />
+                <enum name="GL_LEFT" />
+                <enum name="GL_RIGHT" />
+            </require>
+        </extension>
+
+        <!-- Sized internal formats were introduced in OpenGL ES 3.0, but are
+        not available as an extension. -->
+        <extension name="GL_MSP_sized_internal_formats" supported="gl|gles2">
+            <require>
+                <enum name="GL_RGB8" />
+                <enum name="GL_RGBA8" />
+            </require>
+        </extension>
+
+        <!-- 1D textures are not available in OpenGL ES, but could conceivably
+        be added at a later date. -->
+        <extension name="GL_MSP_texture1D" supported="gl">
+            <require>
+                <command name="glTexImage1D" />
+                <command name="glTexSubImage1D" />
+                <enum name="GL_TEXTURE_1D" />
+            </require>
+        </extension>
+
+        <!-- The core version of primitive restart has different semantics
+        from the NV extension but is not available as a backport extension. -->
+        <extension name="GL_MSP_primitive_restart" supported="gl">
+            <require>
+                <enum name="GL_PRIMITIVE_RESTART" />
+                <enum name="GL_PRIMITIVE_RESTART_INDEX" />
+                <command name="glPrimitiveRestartIndex" />
+            </require>
+        </extension>
+    </extensions>
+</registry>
index f5df83f21588ab0cbb71f94d8a94a8d05023af7a..4c3565e82cc0ac4ded23b39fbef6028d1978c27d 100755 (executable)
@@ -43,6 +43,12 @@ class Version:
                        return self.major>other.major
                return self.minor>other.minor
 
+       def __eq__(self, other):
+               if other is None:
+                       return False
+
+               return (self.major==other.major and self.minor==other.minor)
+
 
 class Thing:
        FUNCTION = 1
@@ -145,9 +151,7 @@ def get_or_create(map, name, type, *args):
 
 
 class GlXmlParser:
-       def __init__(self, host_api_name, target_ext_name):
-               self.host_api_name = host_api_name
-               self.target_ext_name = target_ext_name
+       def __init__(self):
                self.apis = {}
                self.things = {}
 
@@ -177,10 +181,12 @@ class GlXmlParser:
 
                enum.value = int(en.getAttribute("value"), 16)
 
+               alias = en.getAttribute("alias")
+               if alias:
+                       enum.aliases.append(alias)
+
        def parse_feature(self, feat):
                api_name = feat.getAttribute("api")
-               if not api_name:
-                       api_name = self.host_api_name
                api = get_or_create(self.apis, api_name, Api)
 
                version = feat.getAttribute("number")
@@ -204,7 +210,6 @@ class GlXmlParser:
 
                removes = get_nested_elements(feat, "remove")
                for rem in removes:
-                       profile = rem.getAttribute("profile")
                        commands = get_nested_elements(rem, "command")
                        enums = get_nested_elements(rem, "enum")
 
@@ -212,15 +217,8 @@ class GlXmlParser:
                                name = t.getAttribute("name")
                                thing = self.things.get(name)
                                if thing:
-                                       if profile!="core":
-                                               if thing.name in api.core_things:
-                                                       del api.core_things[thing.name]
-                                               for s in thing.api_support.itervalues():
-                                                       for e in s.extensions:
-                                                               del e.things[thing.name]
-                                       else:
-                                               supp = thing.get_or_create_api_support(api.name)
-                                               supp.deprecated_version = version
+                                       supp = thing.get_or_create_api_support(api.name)
+                                       supp.deprecated_version = version
 
        def parse_extension(self, ext):
                ext_things_by_api = {}
@@ -276,6 +274,9 @@ class GlXmlParser:
 
        def check_backport_extensions(self, api):
                for e in api.extensions.itervalues():
+                       if e.ext_type!="ARB":
+                               continue
+
                        e.backport = True
                        for t in e.things.itervalues():
                                if t.name.endswith(e.ext_type):
@@ -283,9 +284,6 @@ class GlXmlParser:
                                        break
 
        def resolve_enum_aliases(self, api):
-               core_enums = filter((lambda t: t.kind==Thing.ENUM), api.core_things.itervalues())
-               core_enums_by_value = dict((e.value, None) for e in core_enums)
-
                for e in api.extensions.itervalues():
                        ext_enums = filter((lambda t: t.kind==Thing.ENUM), e.things.itervalues())
                        enum_suffix = "_"+e.ext_type
@@ -297,13 +295,6 @@ class GlXmlParser:
                                if name.endswith(enum_suffix):
                                        name = name[:-len(enum_suffix)]
                                ce = api.core_things.get(name)
-                               if not ce and n.value in core_enums_by_value:
-                                       if core_enums_by_value[n.value] is None:
-                                               core_enums_by_value[n.value] = filter((lambda e: e.value==n.value), core_enums)
-                                       for c in core_enums_by_value[n.value]:
-                                               if c.bitmask==n.bitmask:
-                                                       ce = c
-                                                       break
                                if ce and ce.value==n.value and ce.name not in n.aliases:
                                        n.aliases.append(ce.name)
 
@@ -321,10 +312,6 @@ class GlXmlParser:
                                                        sources.append(t)
 
        def sort_extensions(self):
-               for a in self.apis.itervalues():
-                       e = a.extensions.get(self.target_ext_name)
-                       if e:
-                               e.preference = 3
                for t in self.things.itervalues():
                        for s in t.api_support.itervalues():
                                s.extensions.sort(key=(lambda e: e.preference), reverse=True)
@@ -338,22 +325,35 @@ class GlXmlParser:
 
 
 def detect_core_version(host_api, things):
-       candidates = {}
+       max_version = Version(1, 0)
+       max_count = 0
+       lower_count = 0
+       missing = []
        for t in things:
                supp = t.api_support.get(host_api.name)
                if supp and supp.core_version:
-                       candidates[supp.core_version] = candidates.get(supp.core_version, 0)+1
+                       if supp.core_version>max_version:
+                               max_version = supp.core_version
+                               lower_count += max_count
+                               max_count = 1
+                       elif supp.core_version==max_version:
+                               max_count += 1
+                       else:
+                               lower_count += 1
+               else:
+                       missing.append(t)
 
-       if candidates:
-               candidates = list((v, k) for k, v in candidates.items())
-               if len(candidates)>1:
-                       candidates.sort(reverse=True)
-                       if candidates[1][0]+1>=candidates[0][0]:
-                               print "Warning: multiple likely core version candidates: %s %s"%(candidates[0][1], candidates[1][1])
-               return candidates[0][1]
+       if lower_count>max_count or (missing and len(missing)*2<lower_count+max_count):
+               print "Warning: Inconsistent core version %s"%max_version
+
+       if missing:
+               return None
+
+       return max_version
 
 def detect_deprecated_version(host_api, things):
        min_version = None
+       deprecated = []
        for t in things:
                supp = t.api_support.get(host_api.name)
                if supp and supp.deprecated_version:
@@ -361,12 +361,14 @@ def detect_deprecated_version(host_api, things):
                                min_version = supp.deprecated_version
                        else:
                                min_version = min(min_version, supp.deprecated_version)
-               else:
-                       return None
+                       deprecated.append(t)
+
+       if min_version and len(deprecated)*2<len(things):
+               print "Warning: Inconsistent deprecation version %s"%min_version
 
        return min_version
 
-def detect_backport_extension(host_api, target_ext, things):
+def detect_backport_extension(host_api, things):
        candidates = []
        for t in things:
                supp = t.api_support.get(host_api.name)
@@ -375,15 +377,20 @@ def detect_backport_extension(host_api, target_ext, things):
                                if e.backport and e not in candidates:
                                        candidates.append(e)
 
-       if len(candidates)>1:
-               print "Warning: multiple backport extension candidates: %s"%(" ".join(e.name for e in candidates))
-
+       total_count = len(things)
+       best_ext = None
+       best_count = 0
        for e in candidates:
-               if e.base_name==target_ext.base_name:
+               things_in_ext = filter((lambda t: t.name in e.things), things)
+               count = len(things_in_ext)
+               if count==total_count:
                        return e
+               elif count>best_count:
+                       best_ext = e
+                       best_count = count
 
-       if len(candidates)==1:
-               print "Warning: potential backport extension has mismatched name: %s"%candidates[0].name
+       if best_count*2>=total_count:
+               print "Warning: Inconsistent backport extension %s"%best_ext.name
 
 def collect_extensions(thing, api, exts):
        supp = thing.api_support.get(api)
@@ -391,16 +398,13 @@ def collect_extensions(thing, api, exts):
                return
 
        for e in supp.extensions:
-               if not e.backport and e not in exts:
+               if not e.backport and e.ext_type!="MSP" and e not in exts:
                        exts.append(e)
 
        for s in supp.sources:
                collect_extensions(s, api, exts)
 
-def detect_source_extension(host_api, target_ext, things):
-       if target_ext.name in host_api.extensions:
-               return target_ext
-
+def detect_source_extension(host_api, things):
        things_by_ext = {}
        for t in things:
                exts = []
@@ -408,37 +412,63 @@ def detect_source_extension(host_api, target_ext, things):
                for e in exts:
                        things_by_ext.setdefault(e, []).append(t)
 
-       largest_ext = None
-       largest_count = 0
-       for e, t in things_by_ext.iteritems():
-               count = len(t)
-               if count>largest_count:
-                       largest_ext = e
-                       largest_count = count
+       extensions = []
+       missing = set(things)
+       while missing and things_by_ext:
+               largest_ext = None
+               largest_count = 0
+               for e, t in things_by_ext.iteritems():
+                       count = len(t)
+                       if count>largest_count:
+                               largest_ext = e
+                               largest_count = count
+                       elif count==largest_count and e.preference>largest_ext.preference:
+                               largest_ext = e
+
+               extensions.append(largest_ext)
+               for t in things_by_ext[largest_ext]:
+                       missing.remove(t)
+               if not missing:
+                       break
+
+               del things_by_ext[largest_ext]
+               for e in things_by_ext.keys():
+                       unseen = filter((lambda t: t in missing), things_by_ext[e])
+                       if unseen:
+                               things_by_ext[e] = unseen
+                       else:
+                               del things_by_ext[e]
+
+       if missing:
+               return None
 
-       return largest_ext
+       return extensions
 
 
 class SourceGenerator:
-       def __init__(self, host_api, target_ext, things):
+       def __init__(self, host_api, ext_name, things, optional_things):
                self.host_api = host_api
                self.api_prefix = "GL"
                if self.host_api.name=="gles2":
                        self.api_prefix = "GL_ES"
-               self.target_ext = target_ext
-               self.funcs = filter((lambda t: t.kind==Thing.FUNCTION), things)
+               self.ext_name = ext_name
+               all_things = things+optional_things
+               self.funcs = filter((lambda t: t.kind==Thing.FUNCTION), all_things)
                self.funcs.sort(key=(lambda f: f.name))
                self.func_typedefs = dict((f.name, "FPtr_"+f.name) for f in self.funcs)
-               self.enums = filter((lambda t: t.kind==Thing.ENUM), things)
+               self.enums = filter((lambda t: t.kind==Thing.ENUM), all_things)
                self.enums.sort(key=(lambda e: e.value))
                self.core_version = detect_core_version(host_api, things)
                self.deprecated_version = detect_deprecated_version(host_api, things)
-               self.backport_ext = detect_backport_extension(host_api, target_ext, things);
-               self.source_ext = detect_source_extension(host_api, target_ext, things)
+               self.backport_ext = detect_backport_extension(host_api, things);
+               self.source_exts = detect_source_extension(host_api, things)
+
+               if not self.core_version and not self.backport_ext and not self.source_exts:
+                       print "Warning: Not supportable on host API"
 
        def write_header_intro(self, out):
-               out.write("#ifndef MSP_GL_%s_\n"%self.target_ext.name.upper())
-               out.write("#define MSP_GL_%s_\n"%self.target_ext.name.upper())
+               out.write("#ifndef MSP_GL_%s_\n"%self.ext_name.upper())
+               out.write("#define MSP_GL_%s_\n"%self.ext_name.upper())
 
                out.write("""
 #include <msp/gl/extension.h>
@@ -486,7 +516,7 @@ namespace GL {
 """)
 
        def write_source_intro(self, out):
-               out.write("#include \"%s.h\"\n"%self.target_ext.name.lower())
+               out.write("#include \"%s.h\"\n"%self.ext_name.lower())
                if self.funcs:
                        out.write("""
 #ifdef __APPLE__
@@ -512,9 +542,9 @@ namespace GL {
                        out.write("%s %s = 0;\n"%(self.func_typedefs[f.name], f.name))
 
        def write_init_function(self, out):
-               out.write("\nExtension::SupportLevel init_%s()\n{\n"%self.target_ext.name.lower())
+               out.write("\nExtension::SupportLevel init_%s()\n{\n"%self.ext_name.lower())
                if self.core_version:
-                       out.write("\tif(is_disabled(\"GL_%s\"))\n\t\treturn Extension::UNSUPPORTED;\n"%self.target_ext.name)
+                       out.write("\tif(is_disabled(\"GL_%s\"))\n\t\treturn Extension::UNSUPPORTED;\n"%self.ext_name)
                        out.write("#if !defined(__APPLE__) || defined(%s_%s)\n"%(self.api_prefix, self.core_version.as_define()))
                        out.write("\tif(")
                        if self.backport_ext:
@@ -524,34 +554,32 @@ namespace GL {
                                out.write(", %r"%self.deprecated_version)
                        out.write("))\n\t{\n")
                        for f in self.funcs:
-                               supp = f.api_support.get(self.host_api.name)
-                               if supp:
-                                       gpa_suffix = ""
-                                       if supp.core_version is not None and supp.core_version<=Version(1, 1):
-                                               gpa_suffix = "_1_1"
-                                       out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS%s(%s));\n"%(f.name, self.func_typedefs[f.name], gpa_suffix, f.name))
+                               supp = f.api_support[self.host_api.name]
+                               gpa_suffix = ""
+                               if supp.core_version is not None and supp.core_version<=Version(1, 1):
+                                       gpa_suffix = "_1_1"
+                               out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS%s(%s));\n"%(f.name, self.func_typedefs[f.name], gpa_suffix, f.name))
                        out.write("\t\treturn Extension::CORE;\n")
                        out.write("\t}\n")
                        out.write("#endif\n")
-               if self.source_ext and self.source_ext!=self.backport_ext:
-                       out.write("#if !defined(__APPLE__) || defined(GL_%s)\n"%self.target_ext.name)
-                       out.write("\tif(is_supported(\"GL_%s\"))\n\t{\n"%(self.source_ext.name))
+               if self.source_exts:
+                       out.write("#if !defined(__APPLE__) || defined(GL_%s)\n"%self.ext_name)
+                       out.write("\tif(%s)\n\t{\n"%" && ".join("is_supported(\"GL_%s\")"%s.name for s in self.source_exts))
                        for f in self.funcs:
-                               supp = f.api_support.get(self.host_api.name)
-                               if supp and supp.sources:
+                               supp = f.api_support[self.host_api.name]
+                               if supp.sources:
                                        src = None
-                                       for s in supp.sources:
-                                               if s.name.endswith(self.source_ext.ext_type):
-                                                       src = s
+                                       for e in self.source_exts:
+                                               for s in supp.sources:
+                                                       if s.name in e.things:
+                                                               src = s
+                                                               break
+                                               if src:
                                                        break
-                                       if not src:
-                                               src = supp.sources[0]
                                else:
                                        src = f
 
-                               if self.host_api.name in src.api_support:
-                                       if not src.name.endswith(self.source_ext.ext_type):
-                                               print "Warning: %s does not match extension type %s"%(src.name, self.source_ext.ext_type)
+                               if src:
                                        out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS(%s));\n"%(f.name, self.func_typedefs[f.name], src.name))
                        out.write("\t\treturn Extension::EXTENSION;\n")
                        out.write("\t}\n")
@@ -570,7 +598,7 @@ namespace GL {
                self.write_header_intro(out)
                self.write_enum_definitions(out)
                self.write_function_pointer_declarations(out)
-               out.write("extern Extension %s;\n"%self.target_ext.name)
+               out.write("extern Extension %s;\n"%self.ext_name)
                self.write_header_outro(out)
 
        def write_source(self, fn):
@@ -578,8 +606,7 @@ namespace GL {
                self.write_source_intro(out)
                self.write_function_pointer_definitions(out)
                self.write_init_function(out)
-               ext_name = self.target_ext.name
-               out.write("\nExtension %s(\"GL_%s\", init_%s);\n"%(ext_name, ext_name, ext_name.lower()))
+               out.write("\nExtension %s(\"GL_%s\", init_%s);\n"%(self.ext_name, self.ext_name, self.ext_name.lower()))
                self.write_source_outro(out)
 
 
@@ -589,9 +616,9 @@ class ExtensionParser:
                self.target_ext = None
                self.core_version = None
                self.deprecated_version = None
-               self.secondary_exts = []
                self.backport_ext = None
                self.ignore_things = []
+               self.optional_things = []
 
        def parse(self, fn):
                for line in open(fn):
@@ -600,56 +627,64 @@ class ExtensionParser:
                                continue
 
                        parts = line.split()
+                       api = None
                        keyword = parts[0]
+                       if ":" in keyword:
+                               api, keyword = keyword.split(":")
+
+                       if api is not None and api!=self.host_api:
+                               continue
 
                        if keyword=="extension":
                                self.target_ext = parts[1]
                        elif keyword=="core_version":
-                               if parts[1]==self.host_api:
-                                       self.core_version = Version(*map(int, parts[2].split('.')))
+                               self.core_version = Version(*map(int, parts[1].split('.')))
                        elif keyword=="deprecated":
-                               if parts[1]==self.host_api:
-                                       self.deprecated_version = Version(*map(int, parts[2].split('.')))
-                       elif keyword=="secondary":
-                               self.secondary_exts.append(parts[1])
+                               self.deprecated_version = Version(*map(int, parts[1].split('.')))
                        elif keyword=="backport":
                                self.backport_ext = parts[1]
                        elif keyword=="ignore":
                                self.ignore_things.append(parts[1])
+                       elif keyword=="optional":
+                               self.optional_things.append(parts[1])
+                       else:
+                               print "Unknown keyword "+keyword
+                               return False
+
+               return True
 
 
 def get_extension(api_map, ext_name):
-       main_api = api_map["gl"]
-       ext = main_api.extensions.get(ext_name)
-       if ext:
-               return ext
+       if "." in ext_name:
+               ext_api_name, ext_name = ext_name.split(".")
+       else:
+               ext_api_name = "gl"
+
+       return api_map[ext_api_name].extensions[ext_name]
+
+def resolve_things(api, things):
+       rthings = []
+       for t in things:
+               ct = filter(None, map(api.core_things.get, t.aliases))
+               if ct:
+                       rthings += ct
+               else:
+                       rthings.append(t)
 
-       for a in api_map.itervalues():
-               ext = a.extensions.get(ext_name)
-               if ext:
-                       return ext
+       return rthings
 
-def collect_things(host_api, target_ext, secondary, ignore):
+def collect_extension_things(host_api, target_ext, ignore):
        ext_things = [t for n, t in target_ext.things.iteritems() if n not in ignore]
-       core_things = target_ext.api.core_things
+       return resolve_things(target_ext.api, ext_things)
 
+def collect_optional_things(target_ext, names):
        things = []
-       for t in ext_things:
-               found_in_core = False
-               for a in t.aliases:
-                       if a in core_things:
-                               things.append(core_things[a])
-                               found_in_core = True
-               if not found_in_core:
-                       things.append(t)
-
-       for s in secondary:
-               for t in s.things.itervalues():
-                       for a in t.aliases:
-                               if a in core_things and core_things[a] not in things:
-                                       things.append(core_things[a])
-
-       return things
+       for t in names:
+               if t in target_ext.things:
+                       things.append(target_ext.things[t])
+               else:
+                       things.append(target_ext.api.core_things[t])
+       return resolve_things(target_ext.api, things)
 
 def main():
        if len(sys.argv)<2:
@@ -660,7 +695,7 @@ Reads gl.xml and generates C++ source files to use an OpenGL extension
 described in <extfile>.  If <outfile> is absent, the extension's lowercased
 name is used.  Anything after the last dot in <outfile> is removed and
 replaced with cpp and h."""
-               sys.exit(0)
+               sys.exit(1)
 
        host_api_name = "gl"
 
@@ -670,7 +705,8 @@ replaced with cpp and h."""
                i += 1
 
        ext_parser = ExtensionParser(host_api_name)
-       ext_parser.parse(sys.argv[i])
+       if not ext_parser.parse(sys.argv[i]):
+               sys.exit(1)
        i += 1
 
        if i<len(sys.argv):
@@ -678,21 +714,27 @@ replaced with cpp and h."""
        else:
                out_base = ext_parser.target_ext.lower()
 
-       xml_parser = GlXmlParser(host_api_name, ext_parser.target_ext)
+       xml_parser = GlXmlParser()
        xml_parser.parse_file("gl.xml")
        xml_parser.parse_file("gl.fixes.xml")
+       xml_parser.parse_file("gl.msp.xml")
        xml_parser.finalize()
 
        host_api = xml_parser.apis[host_api_name]
        target_ext = get_extension(xml_parser.apis, ext_parser.target_ext)
-       secondary_exts = [get_extension(xml_parser.apis, s) for s in ext_parser.secondary_exts]
-       things = collect_things(host_api, target_ext, secondary_exts, ext_parser.ignore_things)
+       things = collect_extension_things(host_api, target_ext, ext_parser.ignore_things+ext_parser.optional_things)
+       optional_things = collect_optional_things(target_ext, ext_parser.optional_things)
 
-       generator = SourceGenerator(host_api, target_extthings)
+       generator = SourceGenerator(host_api, target_ext.name, things, optional_things)
        if ext_parser.core_version:
                generator.core_version = ext_parser.core_version
        if ext_parser.deprecated_version:
                generator.deprecated_version = ext_parser.deprecated_version
+       if ext_parser.backport_ext:
+               if ext_parser.backport_ext=="none":
+                       generator.backport_ext = None
+               else:
+                       generator.backport_ext = get_extension(xml_parser.apis, ext_parser.backport_ext)
        generator.write_header(out_base+".h")
        generator.write_source(out_base+".cpp")
 
index 9b0360fb9354a19e428b98b7fc652b3c8d0ed951..4fcfa9002c734ca6c05e1332a5775aea1e512633 100644 (file)
@@ -30,8 +30,8 @@ enum FramebufferStatus
 {
        FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
        FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
-       FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS,
-       FRAMEBUFFER_INCOMPLETE_FORMATS            = GL_FRAMEBUFFER_INCOMPLETE_FORMATS,
+       FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT,
+       FRAMEBUFFER_INCOMPLETE_FORMATS            = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT,
        FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
        FRAMEBUFFER_INCOMPLETE_READ_BUFFER        = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
        FRAMEBUFFER_UNSUPPORTED                   = GL_FRAMEBUFFER_UNSUPPORTED,