Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # |
Dustin Graves | 94f1914 | 2016-05-10 16:44:16 -0600 | [diff] [blame] | 3 | # Copyright (c) 2013-2016 The Khronos Group Inc. |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 4 | # |
Jon Ashburn | 3ebf125 | 2016-04-19 11:30:31 -0600 | [diff] [blame] | 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 |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 8 | # |
Jon Ashburn | 3ebf125 | 2016-04-19 11:30:31 -0600 | [diff] [blame] | 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 10 | # |
Jon Ashburn | 3ebf125 | 2016-04-19 11:30:31 -0600 | [diff] [blame] | 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. |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 16 | |
| 17 | import sys, time, pdb, string, cProfile |
| 18 | from reg import * |
Mike Stroyan | 845bdc4 | 2015-11-02 15:30:20 -0700 | [diff] [blame] | 19 | from generator import write, CGeneratorOptions, COutputGenerator, DocGeneratorOptions, DocOutputGenerator, PyOutputGenerator, ValidityOutputGenerator, HostSynchronizationOutputGenerator, ThreadGeneratorOptions, ThreadOutputGenerator |
Dustin Graves | dfa6acf | 2016-02-11 10:10:14 -0700 | [diff] [blame] | 20 | from generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator |
Mark Lobodzinski | dc3bd85 | 2016-09-06 16:12:23 -0600 | [diff] [blame] | 21 | from generator import UniqueObjectsGeneratorOptions, UniqueObjectsOutputGenerator |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 22 | |
| 23 | # debug - start header generation in debugger |
| 24 | # dump - dump registry after loading |
| 25 | # profile - enable Python profiling |
| 26 | # protect - whether to use #ifndef protections |
| 27 | # registry <filename> - use specified XML registry instead of gl.xml |
| 28 | # target - string name of target header, or all targets if None |
| 29 | # timeit - time length of registry loading & header generation |
| 30 | # validate - validate return & parameter group tags against <group> |
| 31 | debug = False |
| 32 | dump = False |
| 33 | profile = False |
| 34 | protect = True |
| 35 | target = None |
| 36 | timeit = False |
| 37 | validate= False |
| 38 | # Default input / log files |
| 39 | errFilename = None |
| 40 | diagFilename = 'diag.txt' |
| 41 | regFilename = 'vk.xml' |
Jamie Madill | e6f0893 | 2016-05-04 08:17:33 -0700 | [diff] [blame] | 42 | outDir = '.' |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 43 | |
| 44 | if __name__ == '__main__': |
| 45 | i = 1 |
| 46 | while (i < len(sys.argv)): |
| 47 | arg = sys.argv[i] |
| 48 | i = i + 1 |
| 49 | if (arg == '-debug'): |
| 50 | write('Enabling debug (-debug)', file=sys.stderr) |
| 51 | debug = True |
| 52 | elif (arg == '-dump'): |
| 53 | write('Enabling dump (-dump)', file=sys.stderr) |
| 54 | dump = True |
| 55 | elif (arg == '-noprotect'): |
| 56 | write('Disabling inclusion protection in output headers', file=sys.stderr) |
| 57 | protect = False |
| 58 | elif (arg == '-profile'): |
| 59 | write('Enabling profiling (-profile)', file=sys.stderr) |
| 60 | profile = True |
| 61 | elif (arg == '-registry'): |
| 62 | regFilename = sys.argv[i] |
| 63 | i = i+1 |
| 64 | write('Using registry ', regFilename, file=sys.stderr) |
| 65 | elif (arg == '-time'): |
| 66 | write('Enabling timing (-time)', file=sys.stderr) |
| 67 | timeit = True |
| 68 | elif (arg == '-validate'): |
| 69 | write('Enabling group validation (-validate)', file=sys.stderr) |
| 70 | validate = True |
Jamie Madill | e6f0893 | 2016-05-04 08:17:33 -0700 | [diff] [blame] | 71 | elif (arg == '-outdir'): |
| 72 | outDir = sys.argv[i] |
| 73 | i = i+1 |
| 74 | write('Using output directory ', outDir, file=sys.stderr) |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 75 | elif (arg[0:1] == '-'): |
| 76 | write('Unrecognized argument:', arg, file=sys.stderr) |
| 77 | exit(1) |
| 78 | else: |
| 79 | target = arg |
| 80 | write('Using target', target, file=sys.stderr) |
| 81 | |
| 82 | # Simple timer functions |
| 83 | startTime = None |
| 84 | def startTimer(): |
| 85 | global startTime |
| 86 | startTime = time.clock() |
| 87 | def endTimer(msg): |
| 88 | global startTime |
| 89 | endTime = time.clock() |
| 90 | if (timeit): |
| 91 | write(msg, endTime - startTime) |
| 92 | startTime = None |
| 93 | |
| 94 | # Load & parse registry |
| 95 | reg = Registry() |
| 96 | |
| 97 | startTimer() |
| 98 | tree = etree.parse(regFilename) |
| 99 | endTimer('Time to make ElementTree =') |
| 100 | |
| 101 | startTimer() |
| 102 | reg.loadElementTree(tree) |
| 103 | endTimer('Time to parse ElementTree =') |
| 104 | |
| 105 | if (validate): |
| 106 | reg.validateGroups() |
| 107 | |
| 108 | if (dump): |
| 109 | write('***************************************') |
| 110 | write('Performing Registry dump to regdump.txt') |
| 111 | write('***************************************') |
| 112 | reg.dumpReg(filehandle = open('regdump.txt','w')) |
| 113 | |
| 114 | # Turn a list of strings into a regexp string matching exactly those strings |
| 115 | def makeREstring(list): |
| 116 | return '^(' + '|'.join(list) + ')$' |
| 117 | |
| 118 | # Descriptive names for various regexp patterns used to select |
| 119 | # versions and extensions |
| 120 | allVersions = allExtensions = '.*' |
| 121 | noVersions = noExtensions = None |
| 122 | |
| 123 | # Copyright text prefixing all headers (list of strings). |
| 124 | prefixStrings = [ |
| 125 | '/*', |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 126 | '** Copyright (c) 2015-2016 The Khronos Group Inc.', |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 127 | '**', |
Jon Ashburn | 3ebf125 | 2016-04-19 11:30:31 -0600 | [diff] [blame] | 128 | '** Licensed under the Apache License, Version 2.0 (the "License");', |
| 129 | '** you may not use this file except in compliance with the License.', |
| 130 | '** You may obtain a copy of the License at', |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 131 | '**', |
Jon Ashburn | 3ebf125 | 2016-04-19 11:30:31 -0600 | [diff] [blame] | 132 | '** http://www.apache.org/licenses/LICENSE-2.0', |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 133 | '**', |
Jon Ashburn | 3ebf125 | 2016-04-19 11:30:31 -0600 | [diff] [blame] | 134 | '** Unless required by applicable law or agreed to in writing, software', |
| 135 | '** distributed under the License is distributed on an "AS IS" BASIS,', |
| 136 | '** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.', |
| 137 | '** See the License for the specific language governing permissions and', |
| 138 | '** limitations under the License.', |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 139 | '*/', |
| 140 | '' |
| 141 | ] |
| 142 | |
| 143 | # Text specific to Vulkan headers |
| 144 | vkPrefixStrings = [ |
| 145 | '/*', |
| 146 | '** This header is generated from the Khronos Vulkan XML API Registry.', |
| 147 | '**', |
| 148 | '*/', |
| 149 | '' |
| 150 | ] |
| 151 | |
| 152 | # Defaults for generating re-inclusion protection wrappers (or not) |
| 153 | protectFile = protect |
| 154 | protectFeature = protect |
| 155 | protectProto = protect |
| 156 | |
| 157 | buildList = [ |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 158 | # Vulkan 1.0 - header for core API + extensions. |
| 159 | # To generate just the core API, |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 160 | # change to 'defaultExtensions = None' below. |
| 161 | [ COutputGenerator, |
| 162 | CGeneratorOptions( |
Mike Stroyan | 845bdc4 | 2015-11-02 15:30:20 -0700 | [diff] [blame] | 163 | filename = 'include/vulkan/vulkan.h', |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 164 | apiname = 'vulkan', |
| 165 | profile = None, |
| 166 | versions = allVersions, |
| 167 | emitversions = allVersions, |
| 168 | defaultExtensions = 'vulkan', |
| 169 | addExtensions = None, |
| 170 | removeExtensions = None, |
| 171 | prefixText = prefixStrings + vkPrefixStrings, |
| 172 | genFuncPointers = True, |
| 173 | protectFile = protectFile, |
| 174 | protectFeature = False, |
| 175 | protectProto = '#ifndef', |
| 176 | protectProtoStr = 'VK_NO_PROTOTYPES', |
| 177 | apicall = 'VKAPI_ATTR ', |
| 178 | apientry = 'VKAPI_CALL ', |
| 179 | apientryp = 'VKAPI_PTR *', |
| 180 | alignFuncParam = 48) |
| 181 | ], |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 182 | # Vulkan 1.0 draft - API include files for spec and ref pages |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 183 | # Overwrites include subdirectories in spec source tree |
| 184 | # The generated include files do not include the calling convention |
| 185 | # macros (apientry etc.), unlike the header files. |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 186 | # Because the 1.0 core branch includes ref pages for extensions, |
| 187 | # all the extension interfaces need to be generated, even though |
| 188 | # none are used by the core spec itself. |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 189 | [ DocOutputGenerator, |
| 190 | DocGeneratorOptions( |
| 191 | filename = 'vulkan-docs', |
| 192 | apiname = 'vulkan', |
| 193 | profile = None, |
| 194 | versions = allVersions, |
| 195 | emitversions = allVersions, |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 196 | defaultExtensions = None, |
| 197 | addExtensions = |
| 198 | makeREstring([ |
| 199 | 'VK_KHR_sampler_mirror_clamp_to_edge', |
| 200 | ]), |
| 201 | removeExtensions = |
| 202 | makeREstring([ |
| 203 | ]), |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 204 | prefixText = prefixStrings + vkPrefixStrings, |
| 205 | apicall = '', |
| 206 | apientry = '', |
| 207 | apientryp = '*', |
| 208 | genDirectory = '../../doc/specs/vulkan', |
| 209 | alignFuncParam = 48, |
| 210 | expandEnumerants = False) |
| 211 | ], |
| 212 | # Vulkan 1.0 draft - API names to validate man/api spec includes & links |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 213 | [ PyOutputGenerator, |
| 214 | DocGeneratorOptions( |
| 215 | filename = '../../doc/specs/vulkan/vkapi.py', |
| 216 | apiname = 'vulkan', |
| 217 | profile = None, |
| 218 | versions = allVersions, |
| 219 | emitversions = allVersions, |
| 220 | defaultExtensions = None, |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 221 | addExtensions = |
| 222 | makeREstring([ |
| 223 | 'VK_KHR_sampler_mirror_clamp_to_edge', |
| 224 | ]), |
| 225 | removeExtensions = |
| 226 | makeREstring([ |
| 227 | ])) |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 228 | ], |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 229 | # Vulkan 1.0 draft - core API validity files for spec |
| 230 | # Overwrites validity subdirectories in spec source tree |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 231 | [ ValidityOutputGenerator, |
| 232 | DocGeneratorOptions( |
| 233 | filename = 'validity', |
| 234 | apiname = 'vulkan', |
| 235 | profile = None, |
| 236 | versions = allVersions, |
| 237 | emitversions = allVersions, |
| 238 | defaultExtensions = None, |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 239 | addExtensions = |
| 240 | makeREstring([ |
| 241 | 'VK_KHR_sampler_mirror_clamp_to_edge', |
| 242 | ]), |
| 243 | removeExtensions = |
| 244 | makeREstring([ |
| 245 | ]), |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 246 | genDirectory = '../../doc/specs/vulkan') |
| 247 | ], |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 248 | # Vulkan 1.0 draft - core API host sync table files for spec |
| 249 | # Overwrites subdirectory in spec source tree |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 250 | [ HostSynchronizationOutputGenerator, |
| 251 | DocGeneratorOptions( |
| 252 | filename = 'hostsynctable', |
| 253 | apiname = 'vulkan', |
| 254 | profile = None, |
| 255 | versions = allVersions, |
| 256 | emitversions = allVersions, |
| 257 | defaultExtensions = None, |
Dustin Graves | 3ff520c | 2016-03-28 16:17:38 -0600 | [diff] [blame] | 258 | addExtensions = |
| 259 | makeREstring([ |
| 260 | 'VK_KHR_sampler_mirror_clamp_to_edge', |
| 261 | ]), |
| 262 | removeExtensions = |
| 263 | makeREstring([ |
| 264 | ]), |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 265 | genDirectory = '../../doc/specs/vulkan') |
| 266 | ], |
Mike Stroyan | 845bdc4 | 2015-11-02 15:30:20 -0700 | [diff] [blame] | 267 | # Vulkan 1.0 draft - thread checking layer |
| 268 | [ ThreadOutputGenerator, |
| 269 | ThreadGeneratorOptions( |
| 270 | filename = 'thread_check.h', |
| 271 | apiname = 'vulkan', |
| 272 | profile = None, |
| 273 | versions = allVersions, |
| 274 | emitversions = allVersions, |
| 275 | defaultExtensions = 'vulkan', |
| 276 | addExtensions = None, |
| 277 | removeExtensions = None, |
| 278 | prefixText = prefixStrings + vkPrefixStrings, |
| 279 | genFuncPointers = True, |
| 280 | protectFile = protectFile, |
| 281 | protectFeature = False, |
| 282 | protectProto = True, |
| 283 | protectProtoStr = 'VK_PROTOTYPES', |
Chia-I Wu | ab46177 | 2016-05-16 11:48:11 +0800 | [diff] [blame] | 284 | apicall = 'VKAPI_ATTR ', |
Mike Stroyan | 845bdc4 | 2015-11-02 15:30:20 -0700 | [diff] [blame] | 285 | apientry = 'VKAPI_CALL ', |
| 286 | apientryp = 'VKAPI_PTR *', |
Jamie Madill | e6f0893 | 2016-05-04 08:17:33 -0700 | [diff] [blame] | 287 | alignFuncParam = 48, |
| 288 | genDirectory = outDir) |
Mike Stroyan | 845bdc4 | 2015-11-02 15:30:20 -0700 | [diff] [blame] | 289 | ], |
Dustin Graves | dfa6acf | 2016-02-11 10:10:14 -0700 | [diff] [blame] | 290 | [ ParamCheckerOutputGenerator, |
| 291 | ParamCheckerGeneratorOptions( |
Mark Lobodzinski | 739391a | 2016-03-17 15:08:18 -0600 | [diff] [blame] | 292 | filename = 'parameter_validation.h', |
Dustin Graves | dfa6acf | 2016-02-11 10:10:14 -0700 | [diff] [blame] | 293 | apiname = 'vulkan', |
| 294 | profile = None, |
| 295 | versions = allVersions, |
| 296 | emitversions = allVersions, |
| 297 | defaultExtensions = 'vulkan', |
| 298 | addExtensions = None, |
| 299 | removeExtensions = None, |
| 300 | prefixText = prefixStrings + vkPrefixStrings, |
| 301 | genFuncPointers = True, |
| 302 | protectFile = protectFile, |
| 303 | protectFeature = False, |
| 304 | protectProto = None, |
| 305 | protectProtoStr = 'VK_NO_PROTOTYPES', |
| 306 | apicall = 'VKAPI_ATTR ', |
| 307 | apientry = 'VKAPI_CALL ', |
| 308 | apientryp = 'VKAPI_PTR *', |
Jamie Madill | e6f0893 | 2016-05-04 08:17:33 -0700 | [diff] [blame] | 309 | alignFuncParam = 48, |
| 310 | genDirectory = outDir) |
Dustin Graves | dfa6acf | 2016-02-11 10:10:14 -0700 | [diff] [blame] | 311 | ], |
Mark Lobodzinski | dc3bd85 | 2016-09-06 16:12:23 -0600 | [diff] [blame] | 312 | [ UniqueObjectsOutputGenerator, |
| 313 | UniqueObjectsGeneratorOptions( |
| 314 | filename = 'unique_objects_wrappers.h', |
| 315 | apiname = 'vulkan', |
| 316 | profile = None, |
| 317 | versions = allVersions, |
| 318 | emitversions = allVersions, |
| 319 | defaultExtensions = 'vulkan', |
| 320 | addExtensions = None, |
| 321 | removeExtensions = None, |
| 322 | prefixText = prefixStrings + vkPrefixStrings, |
| 323 | genFuncPointers = True, |
| 324 | protectFile = False, |
| 325 | protectFeature = False, |
| 326 | protectProto = None, |
| 327 | protectProtoStr = 'VK_NO_PROTOTYPES', |
| 328 | apicall = 'VKAPI_ATTR ', |
| 329 | apientry = 'VKAPI_CALL ', |
| 330 | apientryp = 'VKAPI_PTR *', |
| 331 | alignFuncParam = 48, |
| 332 | genDirectory = outDir) |
| 333 | ], |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 334 | None |
| 335 | ] |
| 336 | |
| 337 | # create error/warning & diagnostic files |
| 338 | if (errFilename): |
| 339 | errWarn = open(errFilename,'w') |
| 340 | else: |
| 341 | errWarn = sys.stderr |
| 342 | diag = open(diagFilename, 'w') |
| 343 | |
Jamie Madill | e6f0893 | 2016-05-04 08:17:33 -0700 | [diff] [blame] | 344 | # check that output directory exists |
| 345 | if (not os.path.isdir(outDir)): |
| 346 | write('Output directory does not exist: ', outDir) |
| 347 | raise |
| 348 | |
Mike Stroyan | dee76ef | 2016-01-07 15:35:37 -0700 | [diff] [blame] | 349 | def genHeaders(): |
| 350 | # Loop over targets, building each |
| 351 | generated = 0 |
| 352 | for item in buildList: |
| 353 | if (item == None): |
| 354 | break |
| 355 | createGenerator = item[0] |
| 356 | genOpts = item[1] |
| 357 | if (target and target != genOpts.filename): |
| 358 | # write('*** Skipping', genOpts.filename) |
| 359 | continue |
| 360 | write('*** Building', genOpts.filename) |
| 361 | generated = generated + 1 |
| 362 | startTimer() |
| 363 | gen = createGenerator(errFile=errWarn, |
| 364 | warnFile=errWarn, |
| 365 | diagFile=diag) |
| 366 | reg.setGenerator(gen) |
| 367 | reg.apiGen(genOpts) |
| 368 | write('** Generated', genOpts.filename) |
| 369 | endTimer('Time to generate ' + genOpts.filename + ' =') |
| 370 | if (target and generated == 0): |
| 371 | write('Failed to generate target:', target) |
| 372 | |
| 373 | if (debug): |
| 374 | pdb.run('genHeaders()') |
| 375 | elif (profile): |
| 376 | import cProfile, pstats |
| 377 | cProfile.run('genHeaders()', 'profile.txt') |
| 378 | p = pstats.Stats('profile.txt') |
| 379 | p.strip_dirs().sort_stats('time').print_stats(50) |
| 380 | else: |
| 381 | genHeaders() |