1#!/usr/bin/env python 2# 3# Copyright (c) 2013-2017 The Khronos Group Inc. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import sys, time, pdb, string, cProfile 18from reg import * 19 20# debug - start header generation in debugger 21# dump - dump registry after loading 22# profile - enable Python profiling 23# protect - whether to use #ifndef protections 24# registry <filename> - use specified XML registry instead of gl.xml 25# target - string name of target header, or all targets if None 26# timeit - time length of registry loading & header generation 27# validate - validate return & parameter group tags against <group> 28debug = False 29dump = False 30profile = False 31protect = True 32target = None 33timeit = False 34validate= False 35# Default input / log files 36errFilename = None 37diagFilename = 'diag.txt' 38regFilename = 'gl.xml' 39 40if __name__ == '__main__': 41 i = 1 42 while (i < len(sys.argv)): 43 arg = sys.argv[i] 44 i = i + 1 45 if (arg == '-debug'): 46 write('Enabling debug (-debug)', file=sys.stderr) 47 debug = True 48 elif (arg == '-dump'): 49 write('Enabling dump (-dump)', file=sys.stderr) 50 dump = True 51 elif (arg == '-noprotect'): 52 write('Disabling inclusion protection in output headers', file=sys.stderr) 53 protect = False 54 elif (arg == '-profile'): 55 write('Enabling profiling (-profile)', file=sys.stderr) 56 profile = True 57 elif (arg == '-registry'): 58 regFilename = sys.argv[i] 59 i = i+1 60 write('Using registry ', regFilename, file=sys.stderr) 61 elif (arg == '-time'): 62 write('Enabling timing (-time)', file=sys.stderr) 63 timeit = True 64 elif (arg == '-validate'): 65 write('Enabling group validation (-validate)', file=sys.stderr) 66 validate = True 67 elif (arg[0:1] == '-'): 68 write('Unrecognized argument:', arg, file=sys.stderr) 69 exit(1) 70 else: 71 target = arg 72 write('Using target', target, file=sys.stderr) 73 74# Simple timer functions 75startTime = None 76def startTimer(): 77 global startTime 78 startTime = time.clock() 79def endTimer(msg): 80 global startTime 81 endTime = time.clock() 82 if (timeit): 83 write(msg, endTime - startTime) 84 startTime = None 85 86# Load & parse registry 87reg = Registry() 88 89startTimer() 90tree = etree.parse(regFilename) 91endTimer('Time to make ElementTree =') 92 93startTimer() 94reg.loadElementTree(tree) 95endTimer('Time to parse ElementTree =') 96 97if (validate): 98 reg.validateGroups() 99 100if (dump): 101 write('***************************************') 102 write('Performing Registry dump to regdump.txt') 103 write('***************************************') 104 reg.dumpReg(filehandle = open('regdump.txt','w')) 105 106# Turn a list of strings into a regexp string matching exactly those strings 107def makeREstring(list): 108 return '^(' + '|'.join(list) + ')$' 109 110# These are "mandatory" OpenGL ES 1 extensions, to 111# be included in the core GLES/gl.h header. 112es1CoreList = [ 113 'GL_OES_read_format', 114 'GL_OES_compressed_paletted_texture', 115 'GL_OES_point_size_array', 116 'GL_OES_point_sprite' 117] 118 119# Descriptive names for various regexp patterns used to select 120# versions and extensions 121 122allVersions = allExtensions = '.*' 123noVersions = noExtensions = None 124gl12andLaterPat = '1\.[2-9]|[234]\.[0-9]' 125gles2onlyPat = '2\.[0-9]' 126gles2through30Pat = '2\.[0-9]|3\.0' 127gles2through31Pat = '2\.[0-9]|3\.[01]' 128gles2through32Pat = '2\.[0-9]|3\.[012]' 129es1CorePat = makeREstring(es1CoreList) 130# Extensions in old glcorearb.h but not yet tagged accordingly in gl.xml 131glCoreARBPat = None 132glx13andLaterPat = '1\.[3-9]' 133 134# Copyright text prefixing all headers (list of strings). 135prefixStrings = [ 136 '/*', 137 '** Copyright (c) 2013-2017 The Khronos Group Inc.', 138 '**', 139 '** Permission is hereby granted, free of charge, to any person obtaining a', 140 '** copy of this software and/or associated documentation files (the', 141 '** "Materials"), to deal in the Materials without restriction, including', 142 '** without limitation the rights to use, copy, modify, merge, publish,', 143 '** distribute, sublicense, and/or sell copies of the Materials, and to', 144 '** permit persons to whom the Materials are furnished to do so, subject to', 145 '** the following conditions:', 146 '**', 147 '** The above copyright notice and this permission notice shall be included', 148 '** in all copies or substantial portions of the Materials.', 149 '**', 150 '** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,', 151 '** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF', 152 '** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.', 153 '** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY', 154 '** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,', 155 '** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE', 156 '** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.', 157 '*/', 158 '/*', 159 '** This header is generated from the Khronos OpenGL / OpenGL ES XML', 160 '** API Registry. The current version of the Registry, generator scripts', 161 '** used to make the header, and the header can be found at', 162 '** https://github.com/KhronosGroup/OpenGL-Registry', 163 '*/', 164 '' 165] 166 167# glext.h / glcorearb.h define calling conventions inline (no GL *platform.h) 168glExtPlatformStrings = [ 169 '#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)', 170 '#ifndef WIN32_LEAN_AND_MEAN', 171 '#define WIN32_LEAN_AND_MEAN 1', 172 '#endif', 173 '#include <windows.h>', 174 '#endif', 175 '', 176 '#ifndef APIENTRY', 177 '#define APIENTRY', 178 '#endif', 179 '#ifndef APIENTRYP', 180 '#define APIENTRYP APIENTRY *', 181 '#endif', 182 '#ifndef GLAPI', 183 '#define GLAPI extern', 184 '#endif', 185 '' 186] 187 188glCorearbPlatformStrings = glExtPlatformStrings + [ 189 '/* glcorearb.h is for use with OpenGL core profile implementations.', 190 '** It should should be placed in the same directory as gl.h and', 191 '** included as <GL/glcorearb.h>.', 192 '**', 193 '** glcorearb.h includes only APIs in the latest OpenGL core profile', 194 '** implementation together with APIs in newer ARB extensions which ', 195 '** can be supported by the core profile. It does not, and never will', 196 '** include functionality removed from the core profile, such as', 197 '** fixed-function vertex and fragment processing.', 198 '**', 199 '** Do not #include both <GL/glcorearb.h> and either of <GL/gl.h> or', 200 '** <GL/glext.h> in the same source file.', 201 '*/', 202 '' 203] 204 205# wglext.h needs Windows include 206wglPlatformStrings = [ 207 '#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)', 208 '#define WIN32_LEAN_AND_MEAN 1', 209 '#include <windows.h>', 210 '#endif', 211 '', 212] 213 214# Different APIs use different *platform.h files to define calling 215# conventions 216gles1PlatformStrings = [ '#include <GLES/glplatform.h>', '' ] 217gles2PlatformStrings = [ '#include <GLES2/gl2platform.h>', '' ] 218gles3PlatformStrings = [ '#include <GLES3/gl3platform.h>', '' ] 219glsc2PlatformStrings = [ '#include <GLSC2/gl2platform.h>', '' ] 220eglPlatformStrings = [ '#include <EGL/eglplatform.h>', '' ] 221 222# GLES headers have a small addition to calling convention headers for function pointer typedefs 223apiEntryPrefixStrings = [ 224 '#ifndef GL_APIENTRYP', 225 '#define GL_APIENTRYP GL_APIENTRY*', 226 '#endif', 227 '' 228] 229 230# GLES 2/3 core API headers use a different protection mechanism for 231# prototypes, per bug 14206. 232glesProtoPrefixStrings = [ 233 '#ifndef GL_GLES_PROTOTYPES', 234 '#define GL_GLES_PROTOTYPES 1', 235 '#endif', 236 '' 237] 238 239# Insert generation date in a comment for headers not having *GLEXT_VERSION macros 240genDateCommentString = [ 241 format('/* Generated on date %s */' % time.strftime('%Y%m%d')), 242 '' 243] 244 245# GL_GLEXT_VERSION is defined only in glext.h 246glextVersionStrings = [ 247 format('#define GL_GLEXT_VERSION %s' % time.strftime('%Y%m%d')), 248 '' 249] 250# WGL_WGLEXT_VERSION is defined only in wglext.h 251wglextVersionStrings = [ 252 format('#define WGL_WGLEXT_VERSION %s' % time.strftime('%Y%m%d')), 253 '' 254] 255# GLX_GLXEXT_VERSION is defined only in glxext.h 256glxextVersionStrings = [ 257 format('#define GLX_GLXEXT_VERSION %s' % time.strftime('%Y%m%d')), 258 '' 259] 260# EGL_EGLEXT_VERSION is defined only in eglext.h 261eglextVersionStrings = [ 262 format('#define EGL_EGLEXT_VERSION %s' % time.strftime('%Y%m%d')), 263 '' 264] 265 266# Defaults for generating re-inclusion protection wrappers (or not) 267protectFile = protect 268protectFeature = protect 269protectProto = protect 270 271buildList = [ 272 # GL API 1.2+ + extensions - GL/glext.h 273 CGeneratorOptions( 274 filename = '../api/GL/glext.h', 275 apiname = 'gl', 276 profile = 'compatibility', 277 versions = allVersions, 278 emitversions = gl12andLaterPat, 279 defaultExtensions = 'gl', # Default extensions for GL 280 addExtensions = None, 281 removeExtensions = None, 282 prefixText = prefixStrings + glExtPlatformStrings + glextVersionStrings, 283 genFuncPointers = True, 284 protectFile = protectFile, 285 protectFeature = protectFeature, 286 protectProto = protectProto, 287 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 288 apicall = 'GLAPI ', 289 apientry = 'APIENTRY ', 290 apientryp = 'APIENTRYP '), 291 # GL core profile + extensions - GL/glcorearb.h 292 CGeneratorOptions( 293 filename = '../api/GL/glcorearb.h', 294 apiname = 'gl', 295 profile = 'core', 296 versions = allVersions, 297 emitversions = allVersions, 298 defaultExtensions = 'glcore', # Default extensions for GL core profile (only) 299 addExtensions = glCoreARBPat, 300 removeExtensions = None, 301 prefixText = prefixStrings + glCorearbPlatformStrings, 302 genFuncPointers = True, 303 protectFile = protectFile, 304 protectFeature = protectFeature, 305 protectProto = protectProto, 306 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 307 apicall = 'GLAPI ', 308 apientry = 'APIENTRY ', 309 apientryp = 'APIENTRYP '), 310 # GLES 1.x API + mandatory extensions - GLES/gl.h (no function pointers) 311 CGeneratorOptions( 312 filename = '../api/GLES/gl.h', 313 apiname = 'gles1', 314 profile = 'common', 315 versions = allVersions, 316 emitversions = allVersions, 317 defaultExtensions = None, # No default extensions 318 addExtensions = es1CorePat, # Add mandatory ES1 extensions in GLES1/gl.h 319 removeExtensions = None, 320 prefixText = prefixStrings + gles1PlatformStrings + genDateCommentString, 321 genFuncPointers = False, 322 protectFile = protectFile, 323 protectFeature = protectFeature, 324 protectProto = False, # Core ES API functions are in the static link libraries 325 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 326 apicall = 'GL_API ', 327 apientry = 'GL_APIENTRY ', 328 apientryp = 'GL_APIENTRYP '), 329 # GLES 1.x extensions - GLES/glext.h 330 CGeneratorOptions( 331 filename = '../api/GLES/glext.h', 332 apiname = 'gles1', 333 profile = 'common', 334 versions = allVersions, 335 emitversions = noVersions, 336 defaultExtensions = 'gles1', # Default extensions for GLES 1 337 addExtensions = None, 338 removeExtensions = es1CorePat, # Remove mandatory ES1 extensions in GLES1/glext.h 339 prefixText = prefixStrings + apiEntryPrefixStrings + genDateCommentString, 340 genFuncPointers = True, 341 protectFile = protectFile, 342 protectFeature = protectFeature, 343 protectProto = protectProto, 344 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 345 apicall = 'GL_API ', 346 apientry = 'GL_APIENTRY ', 347 apientryp = 'GL_APIENTRYP '), 348 # GLES 2.0 API - GLES2/gl2.h (now with function pointers) 349 CGeneratorOptions( 350 filename = '../api/GLES2/gl2.h', 351 apiname = 'gles2', 352 profile = 'common', 353 versions = gles2onlyPat, 354 emitversions = allVersions, 355 defaultExtensions = None, # No default extensions 356 addExtensions = None, 357 removeExtensions = None, 358 prefixText = prefixStrings + gles2PlatformStrings + apiEntryPrefixStrings + glesProtoPrefixStrings + genDateCommentString, 359 genFuncPointers = True, 360 protectFile = protectFile, 361 protectFeature = protectFeature, 362 protectProto = 'nonzero', # Core ES API functions are in the static link libraries 363 protectProtoStr = 'GL_GLES_PROTOTYPES', 364 apicall = 'GL_APICALL ', 365 apientry = 'GL_APIENTRY ', 366 apientryp = 'GL_APIENTRYP '), 367 # GLES 3.1 / 3.0 / 2.0 extensions - GLES2/gl2ext.h 368 CGeneratorOptions( 369 filename = '../api/GLES2/gl2ext.h', 370 apiname = 'gles2', 371 profile = 'common', 372 versions = gles2onlyPat, 373 emitversions = None, 374 defaultExtensions = 'gles2', # Default extensions for GLES 2 375 addExtensions = None, 376 removeExtensions = None, 377 prefixText = prefixStrings + apiEntryPrefixStrings + genDateCommentString, 378 genFuncPointers = True, 379 protectFile = protectFile, 380 protectFeature = protectFeature, 381 protectProto = protectProto, 382 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 383 apicall = 'GL_APICALL ', 384 apientry = 'GL_APIENTRY ', 385 apientryp = 'GL_APIENTRYP '), 386 # GLES 3.2 API - GLES3/gl32.h (now with function pointers) 387 CGeneratorOptions( 388 filename = '../api/GLES3/gl32.h', 389 apiname = 'gles2', 390 profile = 'common', 391 versions = gles2through32Pat, 392 emitversions = allVersions, 393 defaultExtensions = None, # No default extensions 394 addExtensions = None, 395 removeExtensions = None, 396 prefixText = prefixStrings + gles3PlatformStrings + apiEntryPrefixStrings + glesProtoPrefixStrings + genDateCommentString, 397 genFuncPointers = True, 398 protectFile = protectFile, 399 protectFeature = protectFeature, 400 protectProto = 'nonzero', # Core ES API functions are in the static link libraries 401 protectProtoStr = 'GL_GLES_PROTOTYPES', 402 apicall = 'GL_APICALL ', 403 apientry = 'GL_APIENTRY ', 404 apientryp = 'GL_APIENTRYP '), 405 # GLES 3.1 API - GLES3/gl31.h (now with function pointers) 406 CGeneratorOptions( 407 filename = '../api/GLES3/gl31.h', 408 apiname = 'gles2', 409 profile = 'common', 410 versions = gles2through31Pat, 411 emitversions = allVersions, 412 defaultExtensions = None, # No default extensions 413 addExtensions = None, 414 removeExtensions = None, 415 prefixText = prefixStrings + gles3PlatformStrings + apiEntryPrefixStrings + glesProtoPrefixStrings + genDateCommentString, 416 genFuncPointers = True, 417 protectFile = protectFile, 418 protectFeature = protectFeature, 419 protectProto = 'nonzero', # Core ES API functions are in the static link libraries 420 protectProtoStr = 'GL_GLES_PROTOTYPES', 421 apicall = 'GL_APICALL ', 422 apientry = 'GL_APIENTRY ', 423 apientryp = 'GL_APIENTRYP '), 424 # GLES 3.0 API - GLES3/gl3.h (now with function pointers) 425 CGeneratorOptions( 426 filename = '../api/GLES3/gl3.h', 427 apiname = 'gles2', 428 profile = 'common', 429 versions = gles2through30Pat, 430 emitversions = allVersions, 431 defaultExtensions = None, # No default extensions 432 addExtensions = None, 433 removeExtensions = None, 434 prefixText = prefixStrings + gles3PlatformStrings + apiEntryPrefixStrings + glesProtoPrefixStrings + genDateCommentString, 435 genFuncPointers = True, 436 protectFile = protectFile, 437 protectFeature = protectFeature, 438 protectProto = 'nonzero', # Core ES API functions are in the static link libraries 439 protectProtoStr = 'GL_GLES_PROTOTYPES', 440 apicall = 'GL_APICALL ', 441 apientry = 'GL_APIENTRY ', 442 apientryp = 'GL_APIENTRYP '), 443 # GLSC 2.0 API - GLSC2/glsc2.h 444 CGeneratorOptions( 445 filename = '../api/GLSC2/glsc2.h', 446 apiname = 'glsc2', 447 profile = 'common', 448 versions = gles2onlyPat, 449 emitversions = allVersions, 450 defaultExtensions = None, # No default extensions 451 addExtensions = None, 452 removeExtensions = None, 453 prefixText = prefixStrings + glsc2PlatformStrings + apiEntryPrefixStrings + genDateCommentString, 454 genFuncPointers = False, 455 protectFile = protectFile, 456 protectFeature = protectFeature, 457 protectProto = False, 458 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 459 apicall = 'GL_APICALL ', 460 apientry = 'GL_APIENTRY ', 461 apientryp = 'GL_APIENTRYP '), 462 # GLSC 2.0 extensions - GLSC2/gl2ext.h 463 CGeneratorOptions( 464 filename = '../api/GLSC2/glsc2ext.h', 465 apiname = 'glsc2', 466 profile = 'common', 467 versions = gles2onlyPat, 468 emitversions = None, 469 defaultExtensions = 'glsc2', # Default extensions for GLSC 2 470 addExtensions = None, 471 removeExtensions = None, 472 prefixText = prefixStrings + apiEntryPrefixStrings + genDateCommentString, 473 genFuncPointers = False, 474 protectFile = protectFile, 475 protectFeature = protectFeature, 476 protectProto = False, 477 protectProtoStr = 'GL_GLEXT_PROTOTYPES', 478 apicall = 'GL_APICALL ', 479 apientry = 'GL_APIENTRY ', 480 apientryp = 'GL_APIENTRYP '), 481 # GLX 1.* API - GL/glx.h (experimental) 482 CGeneratorOptions( 483 filename = '../api/GL/glx.h', 484 apiname = 'glx', 485 profile = None, 486 versions = allVersions, 487 emitversions = allVersions, 488 defaultExtensions = None, # No default extensions 489 addExtensions = None, 490 removeExtensions = None, 491 # add glXPlatformStrings? 492 prefixText = prefixStrings + genDateCommentString, 493 genFuncPointers = True, 494 protectFile = protectFile, 495 protectFeature = protectFeature, 496 protectProto = protectProto, 497 protectProtoStr = 'GLX_GLXEXT_PROTOTYPES', 498 apicall = '', 499 apientry = '', 500 apientryp = ' *'), 501 # GLX 1.3+ API + extensions - GL/glxext.h (no function pointers, yet @@@) 502 CGeneratorOptions( 503 filename = '../api/GL/glxext.h', 504 apiname = 'glx', 505 profile = None, 506 versions = allVersions, 507 emitversions = glx13andLaterPat, 508 defaultExtensions = 'glx', # Default extensions for GLX 509 addExtensions = None, 510 removeExtensions = None, 511 # add glXPlatformStrings? 512 prefixText = prefixStrings + glxextVersionStrings, 513 genFuncPointers = True, 514 protectFile = protectFile, 515 protectFeature = protectFeature, 516 protectProto = protectProto, 517 protectProtoStr = 'GLX_GLXEXT_PROTOTYPES', 518 apicall = '', 519 apientry = '', 520 apientryp = ' *'), 521 # WGL API + extensions - GL/wgl.h (experimenta; no function pointers, yet @@@) 522 CGeneratorOptions( 523 filename = '../api/GL/wgl.h', 524 apiname = 'wgl', 525 profile = None, 526 versions = allVersions, 527 emitversions = allVersions, 528 defaultExtensions = 'wgl', # Default extensions for WGL 529 addExtensions = None, 530 removeExtensions = None, 531 prefixText = prefixStrings + wglPlatformStrings + genDateCommentString, 532 genFuncPointers = True, 533 protectFile = protectFile, 534 protectFeature = protectFeature, 535 protectProto = protectProto, 536 protectProtoStr = 'WGL_WGLEXT_PROTOTYPES', 537 apicall = '', 538 apientry = 'WINAPI ', 539 apientryp = 'WINAPI * '), 540 # WGL extensions - GL/wglext.h (no function pointers, yet @@@) 541 CGeneratorOptions( 542 filename = '../api/GL/wglext.h', 543 apiname = 'wgl', 544 profile = None, 545 versions = allVersions, 546 emitversions = None, 547 defaultExtensions = 'wgl', # Default extensions for WGL 548 addExtensions = None, 549 removeExtensions = None, 550 prefixText = prefixStrings + wglPlatformStrings + wglextVersionStrings, 551 genFuncPointers = True, 552 protectFile = protectFile, 553 protectFeature = protectFeature, 554 protectProto = protectProto, 555 protectProtoStr = 'WGL_WGLEXT_PROTOTYPES', 556 apicall = '', 557 apientry = 'WINAPI ', 558 apientryp = 'WINAPI * '), 559 # End of list 560 None 561] 562 563# create error/warning & diagnostic files 564if (errFilename): 565 errWarn = open(errFilename,'w') 566else: 567 errWarn = sys.stderr 568diag = open(diagFilename, 'w') 569 570def genHeaders(): 571 # Loop over targets, building each 572 generated = 0 573 for genOpts in buildList: 574 if (genOpts == None): 575 break 576 if (target and target != genOpts.filename): 577 # write('*** Skipping', genOpts.filename) 578 continue 579 write('*** Building', genOpts.filename) 580 generated = generated + 1 581 startTimer() 582 gen = COutputGenerator(errFile=errWarn, 583 warnFile=errWarn, 584 diagFile=diag) 585 reg.setGenerator(gen) 586 reg.apiGen(genOpts) 587 write('** Generated', genOpts.filename) 588 endTimer('Time to generate ' + genOpts.filename + ' =') 589 if (target and generated == 0): 590 write('Failed to generate target:', target) 591 592if (debug): 593 pdb.run('genHeaders()') 594elif (profile): 595 import cProfile, pstats 596 cProfile.run('genHeaders()', 'profile.txt') 597 p = pstats.Stats('profile.txt') 598 p.strip_dirs().sort_stats('time').print_stats(50) 599else: 600 genHeaders() 601