extension ARB_depth_texture
+# Deprecated and not particularly useful
+ignore GL_DEPTH_TEXTURE_MODE_ARB
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
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
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
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
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
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
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
extension EXT_bgra
-backport none
extension EXT_blend_minmax
+# Prevent autodetection of ARB_imaging as backport extension
backport none
extension EXT_blend_subtract
+# Prevent autodetection of ARB_imaging as backport extension
backport none
extension EXT_framebuffer_blit
-backport ARB_framebuffer_object
extension EXT_framebuffer_multisample
-backport ARB_framebuffer_object
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
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
extension EXT_texture3D
-backport none
extension EXT_texture_array
-backport none
+# We use the version from ARB_shadow
+ignore GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT
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
-extension EXT_unpack_subimage
+extension gles2.EXT_unpack_subimage
extension MSP_texture1D
-core_version gl 1.1
-extension NV_non_square_matrices
+extension gles2.NV_non_square_matrices
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>
--- /dev/null
+<?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>
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
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 = {}
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")
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")
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 = {}
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):
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
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)
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)
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:
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)
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)
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 = []
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>
""")
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__
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:
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")
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):
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)
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):
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:
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"
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):
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_ext, things)
+ 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")
{
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,