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