blob: 49bf2cb9e2a308f808869a0baa18d572a7014a4d [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
23from parameter_validation_generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
24from 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
125 # Options for parameter validation layer
126 genOpts['parameter_validation.h'] = [
127 ParamCheckerOutputGenerator,
128 ParamCheckerGeneratorOptions(
129 filename = 'parameter_validation.h',
130 directory = directory,
131 apiname = 'vulkan',
132 profile = None,
133 versions = allVersions,
134 emitversions = allVersions,
135 defaultExtensions = 'vulkan',
136 addExtensions = addExtensions,
137 removeExtensions = removeExtensions,
138 prefixText = prefixStrings + vkPrefixStrings,
139 protectFeature = False,
140 apicall = 'VKAPI_ATTR ',
141 apientry = 'VKAPI_CALL ',
142 apientryp = 'VKAPI_PTR *',
143 alignFuncParam = 48)
144 ]
145
146 # Options for unique objects layer
147 genOpts['unique_objects_wrappers.h'] = [
148 UniqueObjectsOutputGenerator,
149 UniqueObjectsGeneratorOptions(
150 filename = 'unique_objects_wrappers.h',
151 directory = directory,
152 apiname = 'vulkan',
153 profile = None,
154 versions = allVersions,
155 emitversions = allVersions,
156 defaultExtensions = 'vulkan',
157 addExtensions = addExtensions,
158 removeExtensions = removeExtensions,
159 prefixText = prefixStrings + vkPrefixStrings,
160 protectFeature = False,
161 apicall = 'VKAPI_ATTR ',
162 apientry = 'VKAPI_CALL ',
163 apientryp = 'VKAPI_PTR *',
164 alignFuncParam = 48)
165 ]
166
Mark Lobodzinski0740bcf2017-07-18 13:49:05 -0600167 # Options for object_tracker layer
168 genOpts['object_tracker.cpp'] = [
169 ObjectTrackerOutputGenerator,
170 ObjectTrackerGeneratorOptions(
171 filename = 'object_tracker.cpp',
172 directory = directory,
173 apiname = 'vulkan',
174 profile = None,
175 versions = allVersions,
176 emitversions = allVersions,
177 defaultExtensions = 'vulkan',
178 addExtensions = addExtensions,
179 removeExtensions = removeExtensions,
180 prefixText = prefixStrings + vkPrefixStrings,
181 protectFeature = False,
182 apicall = 'VKAPI_ATTR ',
183 apientry = 'VKAPI_CALL ',
184 apientryp = 'VKAPI_PTR *',
185 alignFuncParam = 48)
186 ]
187
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700188 # Options for dispatch table helper generator
189 genOpts['vk_dispatch_table_helper.h'] = [
Mark Young0f183a82017-02-28 09:58:04 -0700190 DispatchTableHelperOutputGenerator,
191 DispatchTableHelperOutputGeneratorOptions(
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700192 filename = 'vk_dispatch_table_helper.h',
193 directory = directory,
194 apiname = 'vulkan',
195 profile = None,
196 versions = allVersions,
197 emitversions = allVersions,
198 defaultExtensions = 'vulkan',
199 addExtensions = addExtensions,
200 removeExtensions = removeExtensions,
201 prefixText = prefixStrings + vkPrefixStrings,
202 protectFeature = False,
203 apicall = 'VKAPI_ATTR ',
204 apientry = 'VKAPI_CALL ',
205 apientryp = 'VKAPI_PTR *',
206 alignFuncParam = 48)
207 ]
208
Mark Young0f183a82017-02-28 09:58:04 -0700209 # Options for Layer dispatch table generator
210 genOpts['vk_layer_dispatch_table.h'] = [
211 LoaderExtensionOutputGenerator,
212 LoaderExtensionGeneratorOptions(
213 filename = 'vk_layer_dispatch_table.h',
214 directory = directory,
215 apiname = 'vulkan',
216 profile = None,
217 versions = allVersions,
218 emitversions = allVersions,
219 defaultExtensions = 'vulkan',
220 addExtensions = addExtensions,
221 removeExtensions = removeExtensions,
222 prefixText = prefixStrings + vkPrefixStrings,
223 protectFeature = False,
224 apicall = 'VKAPI_ATTR ',
225 apientry = 'VKAPI_CALL ',
226 apientryp = 'VKAPI_PTR *',
227 alignFuncParam = 48)
228 ]
229
230 # Options for loader extension source generator
231 genOpts['vk_loader_extensions.h'] = [
232 LoaderExtensionOutputGenerator,
233 LoaderExtensionGeneratorOptions(
234 filename = 'vk_loader_extensions.h',
235 directory = directory,
236 apiname = 'vulkan',
237 profile = None,
238 versions = allVersions,
239 emitversions = allVersions,
240 defaultExtensions = 'vulkan',
241 addExtensions = addExtensions,
242 removeExtensions = removeExtensions,
243 prefixText = prefixStrings + vkPrefixStrings,
244 protectFeature = False,
245 apicall = 'VKAPI_ATTR ',
246 apientry = 'VKAPI_CALL ',
247 apientryp = 'VKAPI_PTR *',
248 alignFuncParam = 48)
249 ]
250
251 # Options for loader extension source generator
252 genOpts['vk_loader_extensions.c'] = [
253 LoaderExtensionOutputGenerator,
254 LoaderExtensionGeneratorOptions(
255 filename = 'vk_loader_extensions.c',
256 directory = directory,
257 apiname = 'vulkan',
258 profile = None,
259 versions = allVersions,
260 emitversions = allVersions,
261 defaultExtensions = 'vulkan',
262 addExtensions = addExtensions,
263 removeExtensions = removeExtensions,
264 prefixText = prefixStrings + vkPrefixStrings,
265 protectFeature = False,
266 apicall = 'VKAPI_ATTR ',
267 apientry = 'VKAPI_CALL ',
268 apientryp = 'VKAPI_PTR *',
269 alignFuncParam = 48)
270 ]
271
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700272 # Helper file generator options for vk_enum_string_helper.h
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700273 genOpts['vk_enum_string_helper.h'] = [
274 HelperFileOutputGenerator,
275 HelperFileOutputGeneratorOptions(
276 filename = 'vk_enum_string_helper.h',
277 directory = directory,
278 apiname = 'vulkan',
279 profile = None,
280 versions = allVersions,
281 emitversions = allVersions,
282 defaultExtensions = 'vulkan',
283 addExtensions = addExtensions,
284 removeExtensions = removeExtensions,
285 prefixText = prefixStrings + vkPrefixStrings,
286 protectFeature = False,
287 apicall = 'VKAPI_ATTR ',
288 apientry = 'VKAPI_CALL ',
289 apientryp = 'VKAPI_PTR *',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700290 alignFuncParam = 48,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700291 helper_file_type = 'enum_string_header')
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700292 ]
293
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700294 # Helper file generator options for vk_struct_size_helper.h
295 genOpts['vk_struct_size_helper.h'] = [
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700296 HelperFileOutputGenerator,
297 HelperFileOutputGeneratorOptions(
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700298 filename = 'vk_struct_size_helper.h',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700299 directory = directory,
300 apiname = 'vulkan',
301 profile = None,
302 versions = allVersions,
303 emitversions = allVersions,
304 defaultExtensions = 'vulkan',
305 addExtensions = addExtensions,
306 removeExtensions = removeExtensions,
307 prefixText = prefixStrings + vkPrefixStrings,
308 protectFeature = False,
309 apicall = 'VKAPI_ATTR ',
310 apientry = 'VKAPI_CALL ',
311 apientryp = 'VKAPI_PTR *',
312 alignFuncParam = 48,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700313 helper_file_type = 'struct_size_header')
314 ]
315
316 # Helper file generator options for vk_struct_size_helper.c
317 genOpts['vk_struct_size_helper.c'] = [
318 HelperFileOutputGenerator,
319 HelperFileOutputGeneratorOptions(
320 filename = 'vk_struct_size_helper.c',
321 directory = directory,
322 apiname = 'vulkan',
323 profile = None,
324 versions = allVersions,
325 emitversions = allVersions,
326 defaultExtensions = 'vulkan',
327 addExtensions = addExtensions,
328 removeExtensions = removeExtensions,
329 prefixText = prefixStrings + vkPrefixStrings,
330 protectFeature = False,
331 apicall = 'VKAPI_ATTR ',
332 apientry = 'VKAPI_CALL ',
333 apientryp = 'VKAPI_PTR *',
334 alignFuncParam = 48,
335 helper_file_type = 'struct_size_source')
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700336 ]
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700337
Mark Lobodzinskiaf631782017-01-03 10:55:13 -0700338 # Helper file generator options for vk_safe_struct.h
339 genOpts['vk_safe_struct.h'] = [
340 HelperFileOutputGenerator,
341 HelperFileOutputGeneratorOptions(
342 filename = 'vk_safe_struct.h',
343 directory = directory,
344 apiname = 'vulkan',
345 profile = None,
346 versions = allVersions,
347 emitversions = allVersions,
348 defaultExtensions = 'vulkan',
349 addExtensions = addExtensions,
350 removeExtensions = removeExtensions,
351 prefixText = prefixStrings + vkPrefixStrings,
352 protectFeature = False,
353 apicall = 'VKAPI_ATTR ',
354 apientry = 'VKAPI_CALL ',
355 apientryp = 'VKAPI_PTR *',
356 alignFuncParam = 48,
357 helper_file_type = 'safe_struct_header')
358 ]
359
360 # Helper file generator options for vk_safe_struct.cpp
361 genOpts['vk_safe_struct.cpp'] = [
362 HelperFileOutputGenerator,
363 HelperFileOutputGeneratorOptions(
364 filename = 'vk_safe_struct.cpp',
365 directory = directory,
366 apiname = 'vulkan',
367 profile = None,
368 versions = allVersions,
369 emitversions = allVersions,
370 defaultExtensions = 'vulkan',
371 addExtensions = addExtensions,
372 removeExtensions = removeExtensions,
373 prefixText = prefixStrings + vkPrefixStrings,
374 protectFeature = False,
375 apicall = 'VKAPI_ATTR ',
376 apientry = 'VKAPI_CALL ',
377 apientryp = 'VKAPI_PTR *',
378 alignFuncParam = 48,
379 helper_file_type = 'safe_struct_source')
380 ]
381
Mark Lobodzinski70972012017-04-03 16:59:15 -0600382 # Helper file generator options for vk_object_types.h
383 genOpts['vk_object_types.h'] = [
384 HelperFileOutputGenerator,
385 HelperFileOutputGeneratorOptions(
386 filename = 'vk_object_types.h',
387 directory = directory,
388 apiname = 'vulkan',
389 profile = None,
390 versions = allVersions,
391 emitversions = allVersions,
392 defaultExtensions = 'vulkan',
393 addExtensions = addExtensions,
394 removeExtensions = removeExtensions,
395 prefixText = prefixStrings + vkPrefixStrings,
396 protectFeature = False,
397 apicall = 'VKAPI_ATTR ',
398 apientry = 'VKAPI_CALL ',
399 apientryp = 'VKAPI_PTR *',
400 alignFuncParam = 48,
401 helper_file_type = 'object_types_header')
402 ]
403
Mark Lobodzinskib2a2aa02017-06-01 07:41:46 -0600404 # Helper file generator options for extension_helper.h
405 genOpts['vk_extension_helper.h'] = [
406 HelperFileOutputGenerator,
407 HelperFileOutputGeneratorOptions(
408 filename = 'vk_extension_helper.h',
409 directory = directory,
410 apiname = 'vulkan',
411 profile = None,
412 versions = allVersions,
413 emitversions = allVersions,
414 defaultExtensions = 'vulkan',
415 addExtensions = addExtensions,
416 removeExtensions = removeExtensions,
417 prefixText = prefixStrings + vkPrefixStrings,
418 protectFeature = False,
419 apicall = 'VKAPI_ATTR ',
420 apientry = 'VKAPI_CALL ',
421 apientryp = 'VKAPI_PTR *',
422 alignFuncParam = 48,
423 helper_file_type = 'extension_helper_header')
424 ]
425
Mark Lobodzinski70972012017-04-03 16:59:15 -0600426
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600427# Generate a target based on the options in the matching genOpts{} object.
428# This is encapsulated in a function so it can be profiled and/or timed.
429# The args parameter is an parsed argument object containing the following
430# fields that are used:
431# target - target to generate
432# directory - directory to generate it in
433# protect - True if re-inclusion wrappers should be created
434# extensions - list of additional extensions to include in generated
435# interfaces
436def genTarget(args):
437 global genOpts
438
439 # Create generator options with specified parameters
440 makeGenOpts(extensions = args.extension,
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700441 removeExtensions = args.removeExtension,
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600442 protect = args.protect,
443 directory = args.directory)
444
445 if (args.target in genOpts.keys()):
446 createGenerator = genOpts[args.target][0]
447 options = genOpts[args.target][1]
448
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700449 if not args.quiet:
450 write('* Building', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600451
452 startTimer(args.time)
453 gen = createGenerator(errFile=errWarn,
454 warnFile=errWarn,
455 diagFile=diag)
456 reg.setGenerator(gen)
457 reg.apiGen(options)
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700458
459 if not args.quiet:
460 write('* Generated', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600461 endTimer(args.time, '* Time to generate ' + options.filename + ' =')
462 else:
463 write('No generator options for unknown target:',
464 args.target, file=sys.stderr)
465
466# -extension name - may be a single extension name, a a space-separated list
467# of names, or a regular expression.
468if __name__ == '__main__':
469 parser = argparse.ArgumentParser()
470
471 parser.add_argument('-extension', action='append',
472 default=[],
473 help='Specify an extension or extensions to add to targets')
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700474 parser.add_argument('-removeExtension', action='append',
475 default=[],
476 help='Specify an extension or extensions to remove from targets')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600477 parser.add_argument('-debug', action='store_true',
478 help='Enable debugging')
479 parser.add_argument('-dump', action='store_true',
480 help='Enable dump to stderr')
481 parser.add_argument('-diagfile', action='store',
482 default=None,
483 help='Write diagnostics to specified file')
484 parser.add_argument('-errfile', action='store',
485 default=None,
486 help='Write errors and warnings to specified file instead of stderr')
487 parser.add_argument('-noprotect', dest='protect', action='store_false',
488 help='Disable inclusion protection in output headers')
489 parser.add_argument('-profile', action='store_true',
490 help='Enable profiling')
491 parser.add_argument('-registry', action='store',
492 default='vk.xml',
493 help='Use specified registry file instead of vk.xml')
494 parser.add_argument('-time', action='store_true',
495 help='Enable timing')
496 parser.add_argument('-validate', action='store_true',
497 help='Enable group validation')
498 parser.add_argument('-o', action='store', dest='directory',
499 default='.',
500 help='Create target and related files in specified directory')
501 parser.add_argument('target', metavar='target', nargs='?',
502 help='Specify target')
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700503 parser.add_argument('-quiet', action='store_true', default=False,
504 help='Suppress script output during normal execution.')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600505
506 args = parser.parse_args()
507
508 # This splits arguments which are space-separated lists
509 args.extension = [name for arg in args.extension for name in arg.split()]
510
511 # Load & parse registry
512 reg = Registry()
513
514 startTimer(args.time)
515 tree = etree.parse(args.registry)
516 endTimer(args.time, '* Time to make ElementTree =')
517
518 startTimer(args.time)
519 reg.loadElementTree(tree)
520 endTimer(args.time, '* Time to parse ElementTree =')
521
522 if (args.validate):
523 reg.validateGroups()
524
525 if (args.dump):
526 write('* Dumping registry to regdump.txt', file=sys.stderr)
Mark Lobodzinski36c33862017-02-13 10:15:53 -0700527 reg.dumpReg(filehandle = open('regdump.txt', 'w', encoding='utf-8'))
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600528
529 # create error/warning & diagnostic files
530 if (args.errfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700531 errWarn = open(args.errfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600532 else:
533 errWarn = sys.stderr
534
535 if (args.diagfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700536 diag = open(args.diagfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600537 else:
538 diag = None
539
540 if (args.debug):
541 pdb.run('genTarget(args)')
542 elif (args.profile):
543 import cProfile, pstats
544 cProfile.run('genTarget(args)', 'profile.txt')
545 p = pstats.Stats('profile.txt')
546 p.strip_dirs().sort_stats('time').print_stats(50)
547 else:
548 genTarget(args)