blob: 4d883da31e06a29ebf922c1fe4a46b24f0bc3798 [file] [log] [blame]
Mark Lobodzinski2d589822016-12-12 09:44:34 -07001#!/usr/bin/python3
Mark Lobodzinskif19fef92016-10-11 15:23:51 -06002#
3# Copyright (c) 2013-2016 The Khronos Group Inc.
4#
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
20
21#
22# LoaderAndValidationLayer Generator Additions
23from threading_generator import ThreadGeneratorOptions, ThreadOutputGenerator
24from parameter_validation_generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
25from unique_objects_generator import UniqueObjectsGeneratorOptions, UniqueObjectsOutputGenerator
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -070026from dispatch_table_generator import DispatchTableOutputGenerator, DispatchTableOutputGeneratorOptions
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -070027from helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions
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 '/*',
69 '** Copyright (c) 2015-2016 The Khronos Group Inc.',
70 '**',
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
100 #
101 # LoaderAndValidationLayer Generators
102 # Options for threading layer
103 genOpts['thread_check.h'] = [
104 ThreadOutputGenerator,
105 ThreadGeneratorOptions(
106 filename = 'thread_check.h',
107 directory = directory,
108 apiname = 'vulkan',
109 profile = None,
110 versions = allVersions,
111 emitversions = allVersions,
112 defaultExtensions = 'vulkan',
113 addExtensions = addExtensions,
114 removeExtensions = removeExtensions,
115 prefixText = prefixStrings + vkPrefixStrings,
116 protectFeature = False,
117 apicall = 'VKAPI_ATTR ',
118 apientry = 'VKAPI_CALL ',
119 apientryp = 'VKAPI_PTR *',
120 alignFuncParam = 48)
121 ]
122
123 # Options for parameter validation layer
124 genOpts['parameter_validation.h'] = [
125 ParamCheckerOutputGenerator,
126 ParamCheckerGeneratorOptions(
127 filename = 'parameter_validation.h',
128 directory = directory,
129 apiname = 'vulkan',
130 profile = None,
131 versions = allVersions,
132 emitversions = allVersions,
133 defaultExtensions = 'vulkan',
134 addExtensions = addExtensions,
135 removeExtensions = removeExtensions,
136 prefixText = prefixStrings + vkPrefixStrings,
137 protectFeature = False,
138 apicall = 'VKAPI_ATTR ',
139 apientry = 'VKAPI_CALL ',
140 apientryp = 'VKAPI_PTR *',
141 alignFuncParam = 48)
142 ]
143
144 # Options for unique objects layer
145 genOpts['unique_objects_wrappers.h'] = [
146 UniqueObjectsOutputGenerator,
147 UniqueObjectsGeneratorOptions(
148 filename = 'unique_objects_wrappers.h',
149 directory = directory,
150 apiname = 'vulkan',
151 profile = None,
152 versions = allVersions,
153 emitversions = allVersions,
154 defaultExtensions = 'vulkan',
155 addExtensions = addExtensions,
156 removeExtensions = removeExtensions,
157 prefixText = prefixStrings + vkPrefixStrings,
158 protectFeature = False,
159 apicall = 'VKAPI_ATTR ',
160 apientry = 'VKAPI_CALL ',
161 apientryp = 'VKAPI_PTR *',
162 alignFuncParam = 48)
163 ]
164
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700165
166 # Options for dispatch table helper generator
167 genOpts['vk_dispatch_table_helper.h'] = [
168 DispatchTableOutputGenerator,
169 DispatchTableOutputGeneratorOptions(
170 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 Lobodzinski79839b72016-12-28 08:49:29 -0700187 # Helper file generator options for vk_enum_string_helper.h
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700188 genOpts['vk_enum_string_helper.h'] = [
189 HelperFileOutputGenerator,
190 HelperFileOutputGeneratorOptions(
191 filename = 'vk_enum_string_helper.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 *',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700205 alignFuncParam = 48,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700206 helper_file_type = 'enum_string_header')
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700207 ]
208
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700209 # Helper file generator options for vk_struct_size_helper.h
210 genOpts['vk_struct_size_helper.h'] = [
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700211 HelperFileOutputGenerator,
212 HelperFileOutputGeneratorOptions(
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700213 filename = 'vk_struct_size_helper.h',
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700214 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,
Mark Lobodzinski46d388f2016-12-28 10:46:26 -0700228 helper_file_type = 'struct_size_header')
229 ]
230
231 # Helper file generator options for vk_struct_size_helper.c
232 genOpts['vk_struct_size_helper.c'] = [
233 HelperFileOutputGenerator,
234 HelperFileOutputGeneratorOptions(
235 filename = 'vk_struct_size_helper.c',
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 helper_file_type = 'struct_size_source')
Mark Lobodzinski79839b72016-12-28 08:49:29 -0700251 ]
Mark Lobodzinski41d9bb32016-12-27 13:50:05 -0700252
Mark Lobodzinskiaf631782017-01-03 10:55:13 -0700253 # Helper file generator options for vk_safe_struct.h
254 genOpts['vk_safe_struct.h'] = [
255 HelperFileOutputGenerator,
256 HelperFileOutputGeneratorOptions(
257 filename = 'vk_safe_struct.h',
258 directory = directory,
259 apiname = 'vulkan',
260 profile = None,
261 versions = allVersions,
262 emitversions = allVersions,
263 defaultExtensions = 'vulkan',
264 addExtensions = addExtensions,
265 removeExtensions = removeExtensions,
266 prefixText = prefixStrings + vkPrefixStrings,
267 protectFeature = False,
268 apicall = 'VKAPI_ATTR ',
269 apientry = 'VKAPI_CALL ',
270 apientryp = 'VKAPI_PTR *',
271 alignFuncParam = 48,
272 helper_file_type = 'safe_struct_header')
273 ]
274
275 # Helper file generator options for vk_safe_struct.cpp
276 genOpts['vk_safe_struct.cpp'] = [
277 HelperFileOutputGenerator,
278 HelperFileOutputGeneratorOptions(
279 filename = 'vk_safe_struct.cpp',
280 directory = directory,
281 apiname = 'vulkan',
282 profile = None,
283 versions = allVersions,
284 emitversions = allVersions,
285 defaultExtensions = 'vulkan',
286 addExtensions = addExtensions,
287 removeExtensions = removeExtensions,
288 prefixText = prefixStrings + vkPrefixStrings,
289 protectFeature = False,
290 apicall = 'VKAPI_ATTR ',
291 apientry = 'VKAPI_CALL ',
292 apientryp = 'VKAPI_PTR *',
293 alignFuncParam = 48,
294 helper_file_type = 'safe_struct_source')
295 ]
296
Mark Lobodzinskieb0b5ef2016-12-06 11:30:50 -0700297
298
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600299# Generate a target based on the options in the matching genOpts{} object.
300# This is encapsulated in a function so it can be profiled and/or timed.
301# The args parameter is an parsed argument object containing the following
302# fields that are used:
303# target - target to generate
304# directory - directory to generate it in
305# protect - True if re-inclusion wrappers should be created
306# extensions - list of additional extensions to include in generated
307# interfaces
308def genTarget(args):
309 global genOpts
310
311 # Create generator options with specified parameters
312 makeGenOpts(extensions = args.extension,
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700313 removeExtensions = args.removeExtension,
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600314 protect = args.protect,
315 directory = args.directory)
316
317 if (args.target in genOpts.keys()):
318 createGenerator = genOpts[args.target][0]
319 options = genOpts[args.target][1]
320
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700321 if not args.quiet:
322 write('* Building', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600323
324 startTimer(args.time)
325 gen = createGenerator(errFile=errWarn,
326 warnFile=errWarn,
327 diagFile=diag)
328 reg.setGenerator(gen)
329 reg.apiGen(options)
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700330
331 if not args.quiet:
332 write('* Generated', options.filename, file=sys.stderr)
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600333 endTimer(args.time, '* Time to generate ' + options.filename + ' =')
334 else:
335 write('No generator options for unknown target:',
336 args.target, file=sys.stderr)
337
338# -extension name - may be a single extension name, a a space-separated list
339# of names, or a regular expression.
340if __name__ == '__main__':
341 parser = argparse.ArgumentParser()
342
343 parser.add_argument('-extension', action='append',
344 default=[],
345 help='Specify an extension or extensions to add to targets')
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700346 parser.add_argument('-removeExtension', action='append',
347 default=[],
348 help='Specify an extension or extensions to remove from targets')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600349 parser.add_argument('-debug', action='store_true',
350 help='Enable debugging')
351 parser.add_argument('-dump', action='store_true',
352 help='Enable dump to stderr')
353 parser.add_argument('-diagfile', action='store',
354 default=None,
355 help='Write diagnostics to specified file')
356 parser.add_argument('-errfile', action='store',
357 default=None,
358 help='Write errors and warnings to specified file instead of stderr')
359 parser.add_argument('-noprotect', dest='protect', action='store_false',
360 help='Disable inclusion protection in output headers')
361 parser.add_argument('-profile', action='store_true',
362 help='Enable profiling')
363 parser.add_argument('-registry', action='store',
364 default='vk.xml',
365 help='Use specified registry file instead of vk.xml')
366 parser.add_argument('-time', action='store_true',
367 help='Enable timing')
368 parser.add_argument('-validate', action='store_true',
369 help='Enable group validation')
370 parser.add_argument('-o', action='store', dest='directory',
371 default='.',
372 help='Create target and related files in specified directory')
373 parser.add_argument('target', metavar='target', nargs='?',
374 help='Specify target')
Mark Lobodzinskicbaa2cd2016-12-19 09:41:16 -0700375 parser.add_argument('-quiet', action='store_true', default=False,
376 help='Suppress script output during normal execution.')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600377
378 args = parser.parse_args()
379
380 # This splits arguments which are space-separated lists
381 args.extension = [name for arg in args.extension for name in arg.split()]
382
383 # Load & parse registry
384 reg = Registry()
385
386 startTimer(args.time)
387 tree = etree.parse(args.registry)
388 endTimer(args.time, '* Time to make ElementTree =')
389
390 startTimer(args.time)
391 reg.loadElementTree(tree)
392 endTimer(args.time, '* Time to parse ElementTree =')
393
394 if (args.validate):
395 reg.validateGroups()
396
397 if (args.dump):
398 write('* Dumping registry to regdump.txt', file=sys.stderr)
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700399 reg.dumpReg(filehandle = open('regdump.txt','w', encoding='utf-8'))
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600400
401 # create error/warning & diagnostic files
402 if (args.errfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700403 errWarn = open(args.errfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600404 else:
405 errWarn = sys.stderr
406
407 if (args.diagfile):
Mark Lobodzinski2d589822016-12-12 09:44:34 -0700408 diag = open(args.diagfile, 'w', encoding='utf-8')
Mark Lobodzinskif19fef92016-10-11 15:23:51 -0600409 else:
410 diag = None
411
412 if (args.debug):
413 pdb.run('genTarget(args)')
414 elif (args.profile):
415 import cProfile, pstats
416 cProfile.run('genTarget(args)', 'profile.txt')
417 p = pstats.Stats('profile.txt')
418 p.strip_dirs().sort_stats('time').print_stats(50)
419 else:
420 genTarget(args)