blob: eab932ff17d07d6b67b26287528866441fb47892 [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 Young0f183a82017-02-28 09:58:04 -070025from dispatch_table_helper_generator import DispatchTableHelperOutputGenerator, DispatchTableHelperOutputGeneratorOptions
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -070026from helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions
Mark Young0f183a82017-02-28 09:58:04 -070027from loader_extension_generator import LoaderExtensionOutputGenerator, LoaderExtensionGeneratorOptions
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060028
29# Simple timer functions
30startTime = None
31
32def startTimer(timeit):
33 global startTime
34 startTime = time.clock()
35
36def endTimer(timeit, msg):
37 global startTime
38 endTime = time.clock()
39 if (timeit):
40 write(msg, endTime - startTime, file=sys.stderr)
41 startTime = None
42
43# Turn a list of strings into a regexp string matching exactly those strings
44def makeREstring(list):
45 return '^(' + '|'.join(list) + ')$'
46
47# Returns a directory of [ generator function, generator options ] indexed
48# by specified short names. The generator options incorporate the following
49# parameters:
50#
51# extensions - list of extension names to include.
52# protect - True if re-inclusion protection should be added to headers
53# directory - path to directory in which to generate the target(s)
Mark Lobodzinski2d589822016-12-12 09:44:34 -070054def makeGenOpts(extensions = [], removeExtensions = [], protect = True, directory = '.'):
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060055 global genOpts
56 genOpts = {}
57
58 # Descriptive names for various regexp patterns used to select
59 # versions and extensions
60 allVersions = allExtensions = '.*'
61 noVersions = noExtensions = None
62
63 addExtensions = makeREstring(extensions)
Mark Lobodzinski2d589822016-12-12 09:44:34 -070064 removeExtensions = makeREstring(removeExtensions)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060065
66 # Copyright text prefixing all headers (list of strings).
67 prefixStrings = [
68 '/*',
Mark Lobodzinski36c33862017-02-13 10:15:53 -070069 '** Copyright (c) 2015-2017 The Khronos Group Inc.',
Mark Lobodzinskif19fef92016-10-11 15:23:51 -060070 '**',
71 '** Licensed under the Apache License, Version 2.0 (the "License");',
72 '** you may not use this file except in compliance with the License.',
73 '** You may obtain a copy of the License at',
74 '**',
75 '** http://www.apache.org/licenses/LICENSE-2.0',
76 '**',
77 '** Unless required by applicable law or agreed to in writing, software',
78 '** distributed under the License is distributed on an "AS IS" BASIS,',
79 '** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
80 '** See the License for the specific language governing permissions and',
81 '** limitations under the License.',
82 '*/',
83 ''
84 ]
85
86 # Text specific to Vulkan headers
87 vkPrefixStrings = [
88 '/*',
89 '** This header is generated from the Khronos Vulkan XML API Registry.',
90 '**',
91 '*/',
92 ''
93 ]
94
95 # Defaults for generating re-inclusion protection wrappers (or not)
96 protectFile = protect
97 protectFeature = protect
98 protectProto = protect
99
Mark Lobodzinski36c33862017-02-13 10:15:53 -0700100
101 #
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600102 # LoaderAndValidationLayer Generators
103 # Options for threading layer
104 genOpts['thread_check.h'] = [
105 ThreadOutputGenerator,
106 ThreadGeneratorOptions(
107 filename = 'thread_check.h',
108 directory = directory,
109 apiname = 'vulkan',
110 profile = None,
111 versions = allVersions,
112 emitversions = allVersions,
113 defaultExtensions = 'vulkan',
114 addExtensions = addExtensions,
115 removeExtensions = removeExtensions,
116 prefixText = prefixStrings + vkPrefixStrings,
117 protectFeature = False,
118 apicall = 'VKAPI_ATTR ',
119 apientry = 'VKAPI_CALL ',
120 apientryp = 'VKAPI_PTR *',
121 alignFuncParam = 48)
122 ]
123
124 # Options for parameter validation layer
125 genOpts['parameter_validation.h'] = [
126 ParamCheckerOutputGenerator,
127 ParamCheckerGeneratorOptions(
128 filename = 'parameter_validation.h',
129 directory = directory,
130 apiname = 'vulkan',
131 profile = None,
132 versions = allVersions,
133 emitversions = allVersions,
134 defaultExtensions = 'vulkan',
135 addExtensions = addExtensions,
136 removeExtensions = removeExtensions,
137 prefixText = prefixStrings + vkPrefixStrings,
138 protectFeature = False,
139 apicall = 'VKAPI_ATTR ',
140 apientry = 'VKAPI_CALL ',
141 apientryp = 'VKAPI_PTR *',
142 alignFuncParam = 48)
143 ]
144
145 # Options for unique objects layer
146 genOpts['unique_objects_wrappers.h'] = [
147 UniqueObjectsOutputGenerator,
148 UniqueObjectsGeneratorOptions(
149 filename = 'unique_objects_wrappers.h',
150 directory = directory,
151 apiname = 'vulkan',
152 profile = None,
153 versions = allVersions,
154 emitversions = allVersions,
155 defaultExtensions = 'vulkan',
156 addExtensions = addExtensions,
157 removeExtensions = removeExtensions,
158 prefixText = prefixStrings + vkPrefixStrings,
159 protectFeature = False,
160 apicall = 'VKAPI_ATTR ',
161 apientry = 'VKAPI_CALL ',
162 apientryp = 'VKAPI_PTR *',
163 alignFuncParam = 48)
164 ]
165
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700166 # Options for dispatch table helper generator
167 genOpts['vk_dispatch_table_helper.h'] = [
Mark Young0f183a82017-02-28 09:58:04 -0700168 DispatchTableHelperOutputGenerator,
169 DispatchTableHelperOutputGeneratorOptions(
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700170 filename = 'vk_dispatch_table_helper.h',
171 directory = directory,
172 apiname = 'vulkan',
173 profile = None,
174 versions = allVersions,
175 emitversions = allVersions,
176 defaultExtensions = 'vulkan',
177 addExtensions = addExtensions,
178 removeExtensions = removeExtensions,
179 prefixText = prefixStrings + vkPrefixStrings,
180 protectFeature = False,
181 apicall = 'VKAPI_ATTR ',
182 apientry = 'VKAPI_CALL ',
183 apientryp = 'VKAPI_PTR *',
184 alignFuncParam = 48)
185 ]
186
Mark Young0f183a82017-02-28 09:58:04 -0700187 # Options for Layer dispatch table generator
188 genOpts['vk_layer_dispatch_table.h'] = [
189 LoaderExtensionOutputGenerator,
190 LoaderExtensionGeneratorOptions(
191 filename = 'vk_layer_dispatch_table.h',
192 directory = directory,
193 apiname = 'vulkan',
194 profile = None,
195 versions = allVersions,
196 emitversions = allVersions,
197 defaultExtensions = 'vulkan',
198 addExtensions = addExtensions,
199 removeExtensions = removeExtensions,
200 prefixText = prefixStrings + vkPrefixStrings,
201 protectFeature = False,
202 apicall = 'VKAPI_ATTR ',
203 apientry = 'VKAPI_CALL ',
204 apientryp = 'VKAPI_PTR *',
205 alignFuncParam = 48)
206 ]
207
208 # Options for loader extension source generator
209 genOpts['vk_loader_extensions.h'] = [
210 LoaderExtensionOutputGenerator,
211 LoaderExtensionGeneratorOptions(
212 filename = 'vk_loader_extensions.h',
213 directory = directory,
214 apiname = 'vulkan',
215 profile = None,
216 versions = allVersions,
217 emitversions = allVersions,
218 defaultExtensions = 'vulkan',
219 addExtensions = addExtensions,
220 removeExtensions = removeExtensions,
221 prefixText = prefixStrings + vkPrefixStrings,
222 protectFeature = False,
223 apicall = 'VKAPI_ATTR ',
224 apientry = 'VKAPI_CALL ',
225 apientryp = 'VKAPI_PTR *',
226 alignFuncParam = 48)
227 ]
228
229 # Options for loader extension source generator
230 genOpts['vk_loader_extensions.c'] = [
231 LoaderExtensionOutputGenerator,
232 LoaderExtensionGeneratorOptions(
233 filename = 'vk_loader_extensions.c',
234 directory = directory,
235 apiname = 'vulkan',
236 profile = None,
237 versions = allVersions,
238 emitversions = allVersions,
239 defaultExtensions = 'vulkan',
240 addExtensions = addExtensions,
241 removeExtensions = removeExtensions,
242 prefixText = prefixStrings + vkPrefixStrings,
243 protectFeature = False,
244 apicall = 'VKAPI_ATTR ',
245 apientry = 'VKAPI_CALL ',
246 apientryp = 'VKAPI_PTR *',
247 alignFuncParam = 48)
248 ]
249
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700250 # Helper file generator options for vk_enum_string_helper.h
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700251 genOpts['vk_enum_string_helper.h'] = [
252 HelperFileOutputGenerator,
253 HelperFileOutputGeneratorOptions(
254 filename = 'vk_enum_string_helper.h',
255 directory = directory,
256 apiname = 'vulkan',
257 profile = None,
258 versions = allVersions,
259 emitversions = allVersions,
260 defaultExtensions = 'vulkan',
261 addExtensions = addExtensions,
262 removeExtensions = removeExtensions,
263 prefixText = prefixStrings + vkPrefixStrings,
264 protectFeature = False,
265 apicall = 'VKAPI_ATTR ',
266 apientry = 'VKAPI_CALL ',
267 apientryp = 'VKAPI_PTR *',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700268 alignFuncParam = 48,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700269 helper_file_type = 'enum_string_header')
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700270 ]
271
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700272 # Helper file generator options for vk_struct_size_helper.h
273 genOpts['vk_struct_size_helper.h'] = [
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700274 HelperFileOutputGenerator,
275 HelperFileOutputGeneratorOptions(
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700276 filename = 'vk_struct_size_helper.h',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700277 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 *',
290 alignFuncParam = 48,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700291 helper_file_type = 'struct_size_header')
292 ]
293
294 # Helper file generator options for vk_struct_size_helper.c
295 genOpts['vk_struct_size_helper.c'] = [
296 HelperFileOutputGenerator,
297 HelperFileOutputGeneratorOptions(
298 filename = 'vk_struct_size_helper.c',
299 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,
313 helper_file_type = 'struct_size_source')
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700314 ]
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700315
Mark Lobodzinskiaf631782017-01-03 10:55:13 -0700316 # Helper file generator options for vk_safe_struct.h
317 genOpts['vk_safe_struct.h'] = [
318 HelperFileOutputGenerator,
319 HelperFileOutputGeneratorOptions(
320 filename = 'vk_safe_struct.h',
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 = 'safe_struct_header')
336 ]
337
338 # Helper file generator options for vk_safe_struct.cpp
339 genOpts['vk_safe_struct.cpp'] = [
340 HelperFileOutputGenerator,
341 HelperFileOutputGeneratorOptions(
342 filename = 'vk_safe_struct.cpp',
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_source')
358 ]
359
Mark Lobodzinski70972012017-04-03 16:59:15 -0600360 # Helper file generator options for vk_object_types.h
361 genOpts['vk_object_types.h'] = [
362 HelperFileOutputGenerator,
363 HelperFileOutputGeneratorOptions(
364 filename = 'vk_object_types.h',
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 = 'object_types_header')
380 ]
381
382
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600383# Generate a target based on the options in the matching genOpts{} object.
384# This is encapsulated in a function so it can be profiled and/or timed.
385# The args parameter is an parsed argument object containing the following
386# fields that are used:
387# target - target to generate
388# directory - directory to generate it in
389# protect - True if re-inclusion wrappers should be created
390# extensions - list of additional extensions to include in generated
391# interfaces
392def genTarget(args):
393 global genOpts
394
395 # Create generator options with specified parameters
396 makeGenOpts(extensions = args.extension,
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700397 removeExtensions = args.removeExtension,
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600398 protect = args.protect,
399 directory = args.directory)
400
401 if (args.target in genOpts.keys()):
402 createGenerator = genOpts[args.target][0]
403 options = genOpts[args.target][1]
404
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700405 if not args.quiet:
406 write('* Building', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600407
408 startTimer(args.time)
409 gen = createGenerator(errFile=errWarn,
410 warnFile=errWarn,
411 diagFile=diag)
412 reg.setGenerator(gen)
413 reg.apiGen(options)
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700414
415 if not args.quiet:
416 write('* Generated', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600417 endTimer(args.time, '* Time to generate ' + options.filename + ' =')
418 else:
419 write('No generator options for unknown target:',
420 args.target, file=sys.stderr)
421
422# -extension name - may be a single extension name, a a space-separated list
423# of names, or a regular expression.
424if __name__ == '__main__':
425 parser = argparse.ArgumentParser()
426
427 parser.add_argument('-extension', action='append',
428 default=[],
429 help='Specify an extension or extensions to add to targets')
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700430 parser.add_argument('-removeExtension', action='append',
431 default=[],
432 help='Specify an extension or extensions to remove from targets')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600433 parser.add_argument('-debug', action='store_true',
434 help='Enable debugging')
435 parser.add_argument('-dump', action='store_true',
436 help='Enable dump to stderr')
437 parser.add_argument('-diagfile', action='store',
438 default=None,
439 help='Write diagnostics to specified file')
440 parser.add_argument('-errfile', action='store',
441 default=None,
442 help='Write errors and warnings to specified file instead of stderr')
443 parser.add_argument('-noprotect', dest='protect', action='store_false',
444 help='Disable inclusion protection in output headers')
445 parser.add_argument('-profile', action='store_true',
446 help='Enable profiling')
447 parser.add_argument('-registry', action='store',
448 default='vk.xml',
449 help='Use specified registry file instead of vk.xml')
450 parser.add_argument('-time', action='store_true',
451 help='Enable timing')
452 parser.add_argument('-validate', action='store_true',
453 help='Enable group validation')
454 parser.add_argument('-o', action='store', dest='directory',
455 default='.',
456 help='Create target and related files in specified directory')
457 parser.add_argument('target', metavar='target', nargs='?',
458 help='Specify target')
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700459 parser.add_argument('-quiet', action='store_true', default=False,
460 help='Suppress script output during normal execution.')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600461
462 args = parser.parse_args()
463
464 # This splits arguments which are space-separated lists
465 args.extension = [name for arg in args.extension for name in arg.split()]
466
467 # Load & parse registry
468 reg = Registry()
469
470 startTimer(args.time)
471 tree = etree.parse(args.registry)
472 endTimer(args.time, '* Time to make ElementTree =')
473
474 startTimer(args.time)
475 reg.loadElementTree(tree)
476 endTimer(args.time, '* Time to parse ElementTree =')
477
478 if (args.validate):
479 reg.validateGroups()
480
481 if (args.dump):
482 write('* Dumping registry to regdump.txt', file=sys.stderr)
Mark Lobodzinski36c33862017-02-13 10:15:53 -0700483 reg.dumpReg(filehandle = open('regdump.txt', 'w', encoding='utf-8'))
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600484
485 # create error/warning & diagnostic files
486 if (args.errfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700487 errWarn = open(args.errfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600488 else:
489 errWarn = sys.stderr
490
491 if (args.diagfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700492 diag = open(args.diagfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600493 else:
494 diag = None
495
496 if (args.debug):
497 pdb.run('genTarget(args)')
498 elif (args.profile):
499 import cProfile, pstats
500 cProfile.run('genTarget(args)', 'profile.txt')
501 p = pstats.Stats('profile.txt')
502 p.strip_dirs().sort_stats('time').print_stats(50)
503 else:
504 genTarget(args)