blob: f4ef85ee10cd283ddd1d82c4ca1221b5188782f8 [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.
4# Copyright (c) 2015-2017 LunarG, Inc.
Mark Lobodzinskif19fef92016-10-11 15:23:51 -06005#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18import argparse, cProfile, pdb, string, sys, time
19from reg import *
20from generator import write
21
22#
23# LoaderAndValidationLayer Generator Additions
24from threading_generator import ThreadGeneratorOptions, ThreadOutputGenerator
25from parameter_validation_generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
26from unique_objects_generator import UniqueObjectsGeneratorOptions, UniqueObjectsOutputGenerator
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -070027from dispatch_table_generator import DispatchTableOutputGenerator, DispatchTableOutputGeneratorOptions
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -070028from helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions
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 '/*',
70 '** Copyright (c) 2015-2016 The Khronos Group Inc.',
71 '**',
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
101 #
102 # 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
167 # Options for dispatch table helper generator
168 genOpts['vk_dispatch_table_helper.h'] = [
169 DispatchTableOutputGenerator,
170 DispatchTableOutputGeneratorOptions(
171 filename = 'vk_dispatch_table_helper.h',
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 Lobodzinski79839b72016-12-28 08:49:29 -0700188 # Helper file generator options for vk_enum_string_helper.h
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700189 genOpts['vk_enum_string_helper.h'] = [
190 HelperFileOutputGenerator,
191 HelperFileOutputGeneratorOptions(
192 filename = 'vk_enum_string_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 *',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700206 alignFuncParam = 48,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700207 helper_file_type = 'enum_string_header')
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700208 ]
209
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700210 # Helper file generator options for vk_struct_size_helper.h
211 genOpts['vk_struct_size_helper.h'] = [
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700212 HelperFileOutputGenerator,
213 HelperFileOutputGeneratorOptions(
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700214 filename = 'vk_struct_size_helper.h',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700215 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,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700229 helper_file_type = 'struct_size_header')
230 ]
231
232 # Helper file generator options for vk_struct_size_helper.c
233 genOpts['vk_struct_size_helper.c'] = [
234 HelperFileOutputGenerator,
235 HelperFileOutputGeneratorOptions(
236 filename = 'vk_struct_size_helper.c',
237 directory = directory,
238 apiname = 'vulkan',
239 profile = None,
240 versions = allVersions,
241 emitversions = allVersions,
242 defaultExtensions = 'vulkan',
243 addExtensions = addExtensions,
244 removeExtensions = removeExtensions,
245 prefixText = prefixStrings + vkPrefixStrings,
246 protectFeature = False,
247 apicall = 'VKAPI_ATTR ',
248 apientry = 'VKAPI_CALL ',
249 apientryp = 'VKAPI_PTR *',
250 alignFuncParam = 48,
251 helper_file_type = 'struct_size_source')
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700252 ]
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700253
Mark Lobodzinskiaf631782017-01-03 10:55:13 -0700254 # Helper file generator options for vk_safe_struct.h
255 genOpts['vk_safe_struct.h'] = [
256 HelperFileOutputGenerator,
257 HelperFileOutputGeneratorOptions(
258 filename = 'vk_safe_struct.h',
259 directory = directory,
260 apiname = 'vulkan',
261 profile = None,
262 versions = allVersions,
263 emitversions = allVersions,
264 defaultExtensions = 'vulkan',
265 addExtensions = addExtensions,
266 removeExtensions = removeExtensions,
267 prefixText = prefixStrings + vkPrefixStrings,
268 protectFeature = False,
269 apicall = 'VKAPI_ATTR ',
270 apientry = 'VKAPI_CALL ',
271 apientryp = 'VKAPI_PTR *',
272 alignFuncParam = 48,
273 helper_file_type = 'safe_struct_header')
274 ]
275
276 # Helper file generator options for vk_safe_struct.cpp
277 genOpts['vk_safe_struct.cpp'] = [
278 HelperFileOutputGenerator,
279 HelperFileOutputGeneratorOptions(
280 filename = 'vk_safe_struct.cpp',
281 directory = directory,
282 apiname = 'vulkan',
283 profile = None,
284 versions = allVersions,
285 emitversions = allVersions,
286 defaultExtensions = 'vulkan',
287 addExtensions = addExtensions,
288 removeExtensions = removeExtensions,
289 prefixText = prefixStrings + vkPrefixStrings,
290 protectFeature = False,
291 apicall = 'VKAPI_ATTR ',
292 apientry = 'VKAPI_CALL ',
293 apientryp = 'VKAPI_PTR *',
294 alignFuncParam = 48,
295 helper_file_type = 'safe_struct_source')
296 ]
297
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700298
299
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600300# Generate a target based on the options in the matching genOpts{} object.
301# This is encapsulated in a function so it can be profiled and/or timed.
302# The args parameter is an parsed argument object containing the following
303# fields that are used:
304# target - target to generate
305# directory - directory to generate it in
306# protect - True if re-inclusion wrappers should be created
307# extensions - list of additional extensions to include in generated
308# interfaces
309def genTarget(args):
310 global genOpts
311
312 # Create generator options with specified parameters
313 makeGenOpts(extensions = args.extension,
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700314 removeExtensions = args.removeExtension,
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600315 protect = args.protect,
316 directory = args.directory)
317
318 if (args.target in genOpts.keys()):
319 createGenerator = genOpts[args.target][0]
320 options = genOpts[args.target][1]
321
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700322 if not args.quiet:
323 write('* Building', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600324
325 startTimer(args.time)
326 gen = createGenerator(errFile=errWarn,
327 warnFile=errWarn,
328 diagFile=diag)
329 reg.setGenerator(gen)
330 reg.apiGen(options)
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700331
332 if not args.quiet:
333 write('* Generated', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600334 endTimer(args.time, '* Time to generate ' + options.filename + ' =')
335 else:
336 write('No generator options for unknown target:',
337 args.target, file=sys.stderr)
338
339# -extension name - may be a single extension name, a a space-separated list
340# of names, or a regular expression.
341if __name__ == '__main__':
342 parser = argparse.ArgumentParser()
343
344 parser.add_argument('-extension', action='append',
345 default=[],
346 help='Specify an extension or extensions to add to targets')
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700347 parser.add_argument('-removeExtension', action='append',
348 default=[],
349 help='Specify an extension or extensions to remove from targets')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600350 parser.add_argument('-debug', action='store_true',
351 help='Enable debugging')
352 parser.add_argument('-dump', action='store_true',
353 help='Enable dump to stderr')
354 parser.add_argument('-diagfile', action='store',
355 default=None,
356 help='Write diagnostics to specified file')
357 parser.add_argument('-errfile', action='store',
358 default=None,
359 help='Write errors and warnings to specified file instead of stderr')
360 parser.add_argument('-noprotect', dest='protect', action='store_false',
361 help='Disable inclusion protection in output headers')
362 parser.add_argument('-profile', action='store_true',
363 help='Enable profiling')
364 parser.add_argument('-registry', action='store',
365 default='vk.xml',
366 help='Use specified registry file instead of vk.xml')
367 parser.add_argument('-time', action='store_true',
368 help='Enable timing')
369 parser.add_argument('-validate', action='store_true',
370 help='Enable group validation')
371 parser.add_argument('-o', action='store', dest='directory',
372 default='.',
373 help='Create target and related files in specified directory')
374 parser.add_argument('target', metavar='target', nargs='?',
375 help='Specify target')
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700376 parser.add_argument('-quiet', action='store_true', default=False,
377 help='Suppress script output during normal execution.')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600378
379 args = parser.parse_args()
380
381 # This splits arguments which are space-separated lists
382 args.extension = [name for arg in args.extension for name in arg.split()]
383
384 # Load & parse registry
385 reg = Registry()
386
387 startTimer(args.time)
388 tree = etree.parse(args.registry)
389 endTimer(args.time, '* Time to make ElementTree =')
390
391 startTimer(args.time)
392 reg.loadElementTree(tree)
393 endTimer(args.time, '* Time to parse ElementTree =')
394
395 if (args.validate):
396 reg.validateGroups()
397
398 if (args.dump):
399 write('* Dumping registry to regdump.txt', file=sys.stderr)
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700400 reg.dumpReg(filehandle = open('regdump.txt','w', encoding='utf-8'))
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600401
402 # create error/warning & diagnostic files
403 if (args.errfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700404 errWarn = open(args.errfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600405 else:
406 errWarn = sys.stderr
407
408 if (args.diagfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700409 diag = open(args.diagfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600410 else:
411 diag = None
412
413 if (args.debug):
414 pdb.run('genTarget(args)')
415 elif (args.profile):
416 import cProfile, pstats
417 cProfile.run('genTarget(args)', 'profile.txt')
418 p = pstats.Stats('profile.txt')
419 p.strip_dirs().sort_stats('time').print_stats(50)
420 else:
421 genTarget(args)