blob: 194106e0921d28ae9063b6bc54eed1544e341867 [file] [log] [blame]
Mark Lobodzinski2d589822016-12-12 09:44:34 -07001#!/usr/bin/python3
Mark Lobodzinskif19fef92016-10-11 15:23:51 -06002#
Mark Lobodzinski733f7f42017-01-10 11:42:22 -07003# Copyright (c) 2013-2017 The Khronos Group Inc.
Mark Lobodzinskif19fef92016-10-11 15:23:51 -06004#
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 argparse, cProfile, pdb, string, sys, time
18from reg import *
19from generator import write
Mark Lobodzinski36c33862017-02-13 10:15:53 -070020from cgenerator import CGeneratorOptions, COutputGenerator
21# LoaderAndValidationLayer Generator Modifications
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060022from threading_generator import ThreadGeneratorOptions, ThreadOutputGenerator
Mark Lobodzinskid4950072017-08-01 13:02:20 -060023from parameter_validation_generator import ParameterValidationGeneratorOptions, ParameterValidationOutputGenerator
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060024from unique_objects_generator import UniqueObjectsGeneratorOptions, UniqueObjectsOutputGenerator
Mark Lobodzinski0740bcf2017-07-18 13:49:05 -060025from object_tracker_generator import ObjectTrackerGeneratorOptions, ObjectTrackerOutputGenerator
Mark Young0f183a82017-02-28 09:58:04 -070026from dispatch_table_helper_generator import DispatchTableHelperOutputGenerator, DispatchTableHelperOutputGeneratorOptions
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -070027from helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions
Mark Young0f183a82017-02-28 09:58:04 -070028from loader_extension_generator import LoaderExtensionOutputGenerator, LoaderExtensionGeneratorOptions
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060029
30# Simple timer functions
31startTime = None
32
33def startTimer(timeit):
34 global startTime
35 startTime = time.clock()
36
37def endTimer(timeit, msg):
38 global startTime
39 endTime = time.clock()
40 if (timeit):
41 write(msg, endTime - startTime, file=sys.stderr)
42 startTime = None
43
44# Turn a list of strings into a regexp string matching exactly those strings
45def makeREstring(list):
46 return '^(' + '|'.join(list) + ')$'
47
48# Returns a directory of [ generator function, generator options ] indexed
49# by specified short names. The generator options incorporate the following
50# parameters:
51#
52# extensions - list of extension names to include.
53# protect - True if re-inclusion protection should be added to headers
54# directory - path to directory in which to generate the target(s)
Mark Lobodzinski2d589822016-12-12 09:44:34 -070055def makeGenOpts(extensions = [], removeExtensions = [], protect = True, directory = '.'):
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060056 global genOpts
57 genOpts = {}
58
59 # Descriptive names for various regexp patterns used to select
60 # versions and extensions
61 allVersions = allExtensions = '.*'
62 noVersions = noExtensions = None
63
64 addExtensions = makeREstring(extensions)
Mark Lobodzinski2d589822016-12-12 09:44:34 -070065 removeExtensions = makeREstring(removeExtensions)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060066
67 # Copyright text prefixing all headers (list of strings).
68 prefixStrings = [
69 '/*',
Mark Lobodzinski36c33862017-02-13 10:15:53 -070070 '** Copyright (c) 2015-2017 The Khronos Group Inc.',
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060071 '**',
72 '** Licensed under the Apache License, Version 2.0 (the "License");',
73 '** you may not use this file except in compliance with the License.',
74 '** You may obtain a copy of the License at',
75 '**',
76 '** http://www.apache.org/licenses/LICENSE-2.0',
77 '**',
78 '** Unless required by applicable law or agreed to in writing, software',
79 '** distributed under the License is distributed on an "AS IS" BASIS,',
80 '** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
81 '** See the License for the specific language governing permissions and',
82 '** limitations under the License.',
83 '*/',
84 ''
85 ]
86
87 # Text specific to Vulkan headers
88 vkPrefixStrings = [
89 '/*',
90 '** This header is generated from the Khronos Vulkan XML API Registry.',
91 '**',
92 '*/',
93 ''
94 ]
95
96 # Defaults for generating re-inclusion protection wrappers (or not)
97 protectFile = protect
98 protectFeature = protect
99 protectProto = protect
100
Mark Lobodzinski36c33862017-02-13 10:15:53 -0700101
102 #
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600103 # LoaderAndValidationLayer Generators
104 # Options for threading layer
105 genOpts['thread_check.h'] = [
106 ThreadOutputGenerator,
107 ThreadGeneratorOptions(
108 filename = 'thread_check.h',
109 directory = directory,
110 apiname = 'vulkan',
111 profile = None,
112 versions = allVersions,
113 emitversions = allVersions,
114 defaultExtensions = 'vulkan',
115 addExtensions = addExtensions,
116 removeExtensions = removeExtensions,
117 prefixText = prefixStrings + vkPrefixStrings,
118 protectFeature = False,
119 apicall = 'VKAPI_ATTR ',
120 apientry = 'VKAPI_CALL ',
121 apientryp = 'VKAPI_PTR *',
122 alignFuncParam = 48)
123 ]
124
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600125
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600126 # Options for parameter validation layer
Mark Lobodzinskid4950072017-08-01 13:02:20 -0600127 genOpts['parameter_validation.cpp'] = [
128 ParameterValidationOutputGenerator,
129 ParameterValidationGeneratorOptions(
130 filename = 'parameter_validation.cpp',
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600131 directory = directory,
132 apiname = 'vulkan',
133 profile = None,
134 versions = allVersions,
135 emitversions = allVersions,
136 defaultExtensions = 'vulkan',
137 addExtensions = addExtensions,
138 removeExtensions = removeExtensions,
139 prefixText = prefixStrings + vkPrefixStrings,
140 protectFeature = False,
141 apicall = 'VKAPI_ATTR ',
142 apientry = 'VKAPI_CALL ',
143 apientryp = 'VKAPI_PTR *',
144 alignFuncParam = 48)
145 ]
146
147 # Options for unique objects layer
148 genOpts['unique_objects_wrappers.h'] = [
149 UniqueObjectsOutputGenerator,
150 UniqueObjectsGeneratorOptions(
151 filename = 'unique_objects_wrappers.h',
152 directory = directory,
153 apiname = 'vulkan',
154 profile = None,
155 versions = allVersions,
156 emitversions = allVersions,
157 defaultExtensions = 'vulkan',
158 addExtensions = addExtensions,
159 removeExtensions = removeExtensions,
160 prefixText = prefixStrings + vkPrefixStrings,
161 protectFeature = False,
162 apicall = 'VKAPI_ATTR ',
163 apientry = 'VKAPI_CALL ',
164 apientryp = 'VKAPI_PTR *',
165 alignFuncParam = 48)
166 ]
167
Mark Lobodzinski0740bcf2017-07-18 13:49:05 -0600168 # Options for object_tracker layer
169 genOpts['object_tracker.cpp'] = [
170 ObjectTrackerOutputGenerator,
171 ObjectTrackerGeneratorOptions(
172 filename = 'object_tracker.cpp',
173 directory = directory,
174 apiname = 'vulkan',
175 profile = None,
176 versions = allVersions,
177 emitversions = allVersions,
178 defaultExtensions = 'vulkan',
179 addExtensions = addExtensions,
180 removeExtensions = removeExtensions,
181 prefixText = prefixStrings + vkPrefixStrings,
182 protectFeature = False,
183 apicall = 'VKAPI_ATTR ',
184 apientry = 'VKAPI_CALL ',
185 apientryp = 'VKAPI_PTR *',
186 alignFuncParam = 48)
187 ]
188
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700189 # Options for dispatch table helper generator
190 genOpts['vk_dispatch_table_helper.h'] = [
Mark Young0f183a82017-02-28 09:58:04 -0700191 DispatchTableHelperOutputGenerator,
192 DispatchTableHelperOutputGeneratorOptions(
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700193 filename = 'vk_dispatch_table_helper.h',
194 directory = directory,
195 apiname = 'vulkan',
196 profile = None,
197 versions = allVersions,
198 emitversions = allVersions,
199 defaultExtensions = 'vulkan',
200 addExtensions = addExtensions,
201 removeExtensions = removeExtensions,
202 prefixText = prefixStrings + vkPrefixStrings,
203 protectFeature = False,
204 apicall = 'VKAPI_ATTR ',
205 apientry = 'VKAPI_CALL ',
206 apientryp = 'VKAPI_PTR *',
207 alignFuncParam = 48)
208 ]
209
Mark Young0f183a82017-02-28 09:58:04 -0700210 # Options for Layer dispatch table generator
211 genOpts['vk_layer_dispatch_table.h'] = [
212 LoaderExtensionOutputGenerator,
213 LoaderExtensionGeneratorOptions(
214 filename = 'vk_layer_dispatch_table.h',
215 directory = directory,
216 apiname = 'vulkan',
217 profile = None,
218 versions = allVersions,
219 emitversions = allVersions,
220 defaultExtensions = 'vulkan',
221 addExtensions = addExtensions,
222 removeExtensions = removeExtensions,
223 prefixText = prefixStrings + vkPrefixStrings,
224 protectFeature = False,
225 apicall = 'VKAPI_ATTR ',
226 apientry = 'VKAPI_CALL ',
227 apientryp = 'VKAPI_PTR *',
228 alignFuncParam = 48)
229 ]
230
231 # Options for loader extension source generator
232 genOpts['vk_loader_extensions.h'] = [
233 LoaderExtensionOutputGenerator,
234 LoaderExtensionGeneratorOptions(
235 filename = 'vk_loader_extensions.h',
236 directory = directory,
237 apiname = 'vulkan',
238 profile = None,
239 versions = allVersions,
240 emitversions = allVersions,
241 defaultExtensions = 'vulkan',
242 addExtensions = addExtensions,
243 removeExtensions = removeExtensions,
244 prefixText = prefixStrings + vkPrefixStrings,
245 protectFeature = False,
246 apicall = 'VKAPI_ATTR ',
247 apientry = 'VKAPI_CALL ',
248 apientryp = 'VKAPI_PTR *',
249 alignFuncParam = 48)
250 ]
251
252 # Options for loader extension source generator
253 genOpts['vk_loader_extensions.c'] = [
254 LoaderExtensionOutputGenerator,
255 LoaderExtensionGeneratorOptions(
256 filename = 'vk_loader_extensions.c',
257 directory = directory,
258 apiname = 'vulkan',
259 profile = None,
260 versions = allVersions,
261 emitversions = allVersions,
262 defaultExtensions = 'vulkan',
263 addExtensions = addExtensions,
264 removeExtensions = removeExtensions,
265 prefixText = prefixStrings + vkPrefixStrings,
266 protectFeature = False,
267 apicall = 'VKAPI_ATTR ',
268 apientry = 'VKAPI_CALL ',
269 apientryp = 'VKAPI_PTR *',
270 alignFuncParam = 48)
271 ]
272
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700273 # Helper file generator options for vk_enum_string_helper.h
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700274 genOpts['vk_enum_string_helper.h'] = [
275 HelperFileOutputGenerator,
276 HelperFileOutputGeneratorOptions(
277 filename = 'vk_enum_string_helper.h',
278 directory = directory,
279 apiname = 'vulkan',
280 profile = None,
281 versions = allVersions,
282 emitversions = allVersions,
283 defaultExtensions = 'vulkan',
284 addExtensions = addExtensions,
285 removeExtensions = removeExtensions,
286 prefixText = prefixStrings + vkPrefixStrings,
287 protectFeature = False,
288 apicall = 'VKAPI_ATTR ',
289 apientry = 'VKAPI_CALL ',
290 apientryp = 'VKAPI_PTR *',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700291 alignFuncParam = 48,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700292 helper_file_type = 'enum_string_header')
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700293 ]
294
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700295 # Helper file generator options for vk_struct_size_helper.h
296 genOpts['vk_struct_size_helper.h'] = [
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700297 HelperFileOutputGenerator,
298 HelperFileOutputGeneratorOptions(
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700299 filename = 'vk_struct_size_helper.h',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700300 directory = directory,
301 apiname = 'vulkan',
302 profile = None,
303 versions = allVersions,
304 emitversions = allVersions,
305 defaultExtensions = 'vulkan',
306 addExtensions = addExtensions,
307 removeExtensions = removeExtensions,
308 prefixText = prefixStrings + vkPrefixStrings,
309 protectFeature = False,
310 apicall = 'VKAPI_ATTR ',
311 apientry = 'VKAPI_CALL ',
312 apientryp = 'VKAPI_PTR *',
313 alignFuncParam = 48,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700314 helper_file_type = 'struct_size_header')
315 ]
316
317 # Helper file generator options for vk_struct_size_helper.c
318 genOpts['vk_struct_size_helper.c'] = [
319 HelperFileOutputGenerator,
320 HelperFileOutputGeneratorOptions(
321 filename = 'vk_struct_size_helper.c',
322 directory = directory,
323 apiname = 'vulkan',
324 profile = None,
325 versions = allVersions,
326 emitversions = allVersions,
327 defaultExtensions = 'vulkan',
328 addExtensions = addExtensions,
329 removeExtensions = removeExtensions,
330 prefixText = prefixStrings + vkPrefixStrings,
331 protectFeature = False,
332 apicall = 'VKAPI_ATTR ',
333 apientry = 'VKAPI_CALL ',
334 apientryp = 'VKAPI_PTR *',
335 alignFuncParam = 48,
336 helper_file_type = 'struct_size_source')
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700337 ]
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700338
Mark Lobodzinskiaf631782017-01-03 10:55:13 -0700339 # Helper file generator options for vk_safe_struct.h
340 genOpts['vk_safe_struct.h'] = [
341 HelperFileOutputGenerator,
342 HelperFileOutputGeneratorOptions(
343 filename = 'vk_safe_struct.h',
344 directory = directory,
345 apiname = 'vulkan',
346 profile = None,
347 versions = allVersions,
348 emitversions = allVersions,
349 defaultExtensions = 'vulkan',
350 addExtensions = addExtensions,
351 removeExtensions = removeExtensions,
352 prefixText = prefixStrings + vkPrefixStrings,
353 protectFeature = False,
354 apicall = 'VKAPI_ATTR ',
355 apientry = 'VKAPI_CALL ',
356 apientryp = 'VKAPI_PTR *',
357 alignFuncParam = 48,
358 helper_file_type = 'safe_struct_header')
359 ]
360
361 # Helper file generator options for vk_safe_struct.cpp
362 genOpts['vk_safe_struct.cpp'] = [
363 HelperFileOutputGenerator,
364 HelperFileOutputGeneratorOptions(
365 filename = 'vk_safe_struct.cpp',
366 directory = directory,
367 apiname = 'vulkan',
368 profile = None,
369 versions = allVersions,
370 emitversions = allVersions,
371 defaultExtensions = 'vulkan',
372 addExtensions = addExtensions,
373 removeExtensions = removeExtensions,
374 prefixText = prefixStrings + vkPrefixStrings,
375 protectFeature = False,
376 apicall = 'VKAPI_ATTR ',
377 apientry = 'VKAPI_CALL ',
378 apientryp = 'VKAPI_PTR *',
379 alignFuncParam = 48,
380 helper_file_type = 'safe_struct_source')
381 ]
382
Mark Lobodzinski70972012017-04-03 16:59:15 -0600383 # Helper file generator options for vk_object_types.h
384 genOpts['vk_object_types.h'] = [
385 HelperFileOutputGenerator,
386 HelperFileOutputGeneratorOptions(
387 filename = 'vk_object_types.h',
388 directory = directory,
389 apiname = 'vulkan',
390 profile = None,
391 versions = allVersions,
392 emitversions = allVersions,
393 defaultExtensions = 'vulkan',
394 addExtensions = addExtensions,
395 removeExtensions = removeExtensions,
396 prefixText = prefixStrings + vkPrefixStrings,
397 protectFeature = False,
398 apicall = 'VKAPI_ATTR ',
399 apientry = 'VKAPI_CALL ',
400 apientryp = 'VKAPI_PTR *',
401 alignFuncParam = 48,
402 helper_file_type = 'object_types_header')
403 ]
404
Mark Lobodzinskib2a2aa02017-06-01 07:41:46 -0600405 # Helper file generator options for extension_helper.h
406 genOpts['vk_extension_helper.h'] = [
407 HelperFileOutputGenerator,
408 HelperFileOutputGeneratorOptions(
409 filename = 'vk_extension_helper.h',
410 directory = directory,
411 apiname = 'vulkan',
412 profile = None,
413 versions = allVersions,
414 emitversions = allVersions,
415 defaultExtensions = 'vulkan',
416 addExtensions = addExtensions,
417 removeExtensions = removeExtensions,
418 prefixText = prefixStrings + vkPrefixStrings,
419 protectFeature = False,
420 apicall = 'VKAPI_ATTR ',
421 apientry = 'VKAPI_CALL ',
422 apientryp = 'VKAPI_PTR *',
423 alignFuncParam = 48,
424 helper_file_type = 'extension_helper_header')
425 ]
426
Mark Lobodzinski70972012017-04-03 16:59:15 -0600427
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600428# Generate a target based on the options in the matching genOpts{} object.
429# This is encapsulated in a function so it can be profiled and/or timed.
430# The args parameter is an parsed argument object containing the following
431# fields that are used:
432# target - target to generate
433# directory - directory to generate it in
434# protect - True if re-inclusion wrappers should be created
435# extensions - list of additional extensions to include in generated
436# interfaces
437def genTarget(args):
438 global genOpts
439
440 # Create generator options with specified parameters
441 makeGenOpts(extensions = args.extension,
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700442 removeExtensions = args.removeExtension,
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600443 protect = args.protect,
444 directory = args.directory)
445
446 if (args.target in genOpts.keys()):
447 createGenerator = genOpts[args.target][0]
448 options = genOpts[args.target][1]
449
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700450 if not args.quiet:
451 write('* Building', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600452
453 startTimer(args.time)
454 gen = createGenerator(errFile=errWarn,
455 warnFile=errWarn,
456 diagFile=diag)
457 reg.setGenerator(gen)
458 reg.apiGen(options)
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700459
460 if not args.quiet:
461 write('* Generated', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600462 endTimer(args.time, '* Time to generate ' + options.filename + ' =')
463 else:
464 write('No generator options for unknown target:',
465 args.target, file=sys.stderr)
466
467# -extension name - may be a single extension name, a a space-separated list
468# of names, or a regular expression.
469if __name__ == '__main__':
470 parser = argparse.ArgumentParser()
471
472 parser.add_argument('-extension', action='append',
473 default=[],
474 help='Specify an extension or extensions to add to targets')
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700475 parser.add_argument('-removeExtension', action='append',
476 default=[],
477 help='Specify an extension or extensions to remove from targets')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600478 parser.add_argument('-debug', action='store_true',
479 help='Enable debugging')
480 parser.add_argument('-dump', action='store_true',
481 help='Enable dump to stderr')
482 parser.add_argument('-diagfile', action='store',
483 default=None,
484 help='Write diagnostics to specified file')
485 parser.add_argument('-errfile', action='store',
486 default=None,
487 help='Write errors and warnings to specified file instead of stderr')
488 parser.add_argument('-noprotect', dest='protect', action='store_false',
489 help='Disable inclusion protection in output headers')
490 parser.add_argument('-profile', action='store_true',
491 help='Enable profiling')
492 parser.add_argument('-registry', action='store',
493 default='vk.xml',
494 help='Use specified registry file instead of vk.xml')
495 parser.add_argument('-time', action='store_true',
496 help='Enable timing')
497 parser.add_argument('-validate', action='store_true',
498 help='Enable group validation')
499 parser.add_argument('-o', action='store', dest='directory',
500 default='.',
501 help='Create target and related files in specified directory')
502 parser.add_argument('target', metavar='target', nargs='?',
503 help='Specify target')
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700504 parser.add_argument('-quiet', action='store_true', default=False,
505 help='Suppress script output during normal execution.')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600506
507 args = parser.parse_args()
508
509 # This splits arguments which are space-separated lists
510 args.extension = [name for arg in args.extension for name in arg.split()]
511
512 # Load & parse registry
513 reg = Registry()
514
515 startTimer(args.time)
516 tree = etree.parse(args.registry)
517 endTimer(args.time, '* Time to make ElementTree =')
518
519 startTimer(args.time)
520 reg.loadElementTree(tree)
521 endTimer(args.time, '* Time to parse ElementTree =')
522
523 if (args.validate):
524 reg.validateGroups()
525
526 if (args.dump):
527 write('* Dumping registry to regdump.txt', file=sys.stderr)
Mark Lobodzinski36c33862017-02-13 10:15:53 -0700528 reg.dumpReg(filehandle = open('regdump.txt', 'w', encoding='utf-8'))
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600529
530 # create error/warning & diagnostic files
531 if (args.errfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700532 errWarn = open(args.errfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600533 else:
534 errWarn = sys.stderr
535
536 if (args.diagfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700537 diag = open(args.diagfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600538 else:
539 diag = None
540
541 if (args.debug):
542 pdb.run('genTarget(args)')
543 elif (args.profile):
544 import cProfile, pstats
545 cProfile.run('genTarget(args)', 'profile.txt')
546 p = pstats.Stats('profile.txt')
547 p.strip_dirs().sort_stats('time').print_stats(50)
548 else:
549 genTarget(args)