3 # Copyright (c) 2013-2016 The Khronos Group Inc.
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 import sys, time, pdb, string, cProfile
19 from generator import write, CGeneratorOptions, COutputGenerator, DocGeneratorOptions, DocOutputGenerator, PyOutputGenerator, ValidityOutputGenerator, HostSynchronizationOutputGenerator, ThreadGeneratorOptions, ThreadOutputGenerator
20 from generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
22 # debug - start header generation in debugger
23 # dump - dump registry after loading
24 # profile - enable Python profiling
25 # protect - whether to use #ifndef protections
26 # registry <filename> - use specified XML registry instead of gl.xml
27 # target - string name of target header, or all targets if None
28 # timeit - time length of registry loading & header generation
29 # validate - validate return & parameter group tags against <group>
37 # Default input / log files
39 diagFilename = 'diag.txt'
40 regFilename = 'vk.xml'
43 if __name__ == '__main__':
45 while (i < len(sys.argv)):
49 write('Enabling debug (-debug)', file=sys.stderr)
51 elif (arg == '-dump'):
52 write('Enabling dump (-dump)', file=sys.stderr)
54 elif (arg == '-noprotect'):
55 write('Disabling inclusion protection in output headers', file=sys.stderr)
57 elif (arg == '-profile'):
58 write('Enabling profiling (-profile)', file=sys.stderr)
60 elif (arg == '-registry'):
61 regFilename = sys.argv[i]
63 write('Using registry ', regFilename, file=sys.stderr)
64 elif (arg == '-time'):
65 write('Enabling timing (-time)', file=sys.stderr)
67 elif (arg == '-validate'):
68 write('Enabling group validation (-validate)', file=sys.stderr)
70 elif (arg == '-outdir'):
73 write('Using output directory ', outDir, file=sys.stderr)
74 elif (arg[0:1] == '-'):
75 write('Unrecognized argument:', arg, file=sys.stderr)
79 write('Using target', target, file=sys.stderr)
81 # Simple timer functions
85 startTime = time.clock()
88 endTime = time.clock()
90 write(msg, endTime - startTime)
93 # Load & parse registry
97 tree = etree.parse(regFilename)
98 endTimer('Time to make ElementTree =')
101 reg.loadElementTree(tree)
102 endTimer('Time to parse ElementTree =')
108 write('***************************************')
109 write('Performing Registry dump to regdump.txt')
110 write('***************************************')
111 reg.dumpReg(filehandle = open('regdump.txt','w'))
113 # Turn a list of strings into a regexp string matching exactly those strings
114 def makeREstring(list):
115 return '^(' + '|'.join(list) + ')$'
117 # Descriptive names for various regexp patterns used to select
118 # versions and extensions
119 allVersions = allExtensions = '.*'
120 noVersions = noExtensions = None
122 # Copyright text prefixing all headers (list of strings).
125 '** Copyright (c) 2015-2016 The Khronos Group Inc.',
127 '** Licensed under the Apache License, Version 2.0 (the "License");',
128 '** you may not use this file except in compliance with the License.',
129 '** You may obtain a copy of the License at',
131 '** http://www.apache.org/licenses/LICENSE-2.0',
133 '** Unless required by applicable law or agreed to in writing, software',
134 '** distributed under the License is distributed on an "AS IS" BASIS,',
135 '** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
136 '** See the License for the specific language governing permissions and',
137 '** limitations under the License.',
142 # Text specific to Vulkan headers
145 '** This header is generated from the Khronos Vulkan XML API Registry.',
151 # Defaults for generating re-inclusion protection wrappers (or not)
152 protectFile = protect
153 protectFeature = protect
154 protectProto = protect
157 # Vulkan 1.0 - header for core API + extensions.
158 # To generate just the core API,
159 # change to 'defaultExtensions = None' below.
162 filename = 'include/vulkan/vulkan.h',
165 versions = allVersions,
166 emitversions = allVersions,
167 defaultExtensions = 'vulkan',
168 addExtensions = None,
169 removeExtensions = None,
170 prefixText = prefixStrings + vkPrefixStrings,
171 genFuncPointers = True,
172 protectFile = protectFile,
173 protectFeature = False,
174 protectProto = '#ifndef',
175 protectProtoStr = 'VK_NO_PROTOTYPES',
176 apicall = 'VKAPI_ATTR ',
177 apientry = 'VKAPI_CALL ',
178 apientryp = 'VKAPI_PTR *',
181 # Vulkan 1.0 draft - API include files for spec and ref pages
182 # Overwrites include subdirectories in spec source tree
183 # The generated include files do not include the calling convention
184 # macros (apientry etc.), unlike the header files.
185 # Because the 1.0 core branch includes ref pages for extensions,
186 # all the extension interfaces need to be generated, even though
187 # none are used by the core spec itself.
188 [ DocOutputGenerator,
190 filename = 'vulkan-docs',
193 versions = allVersions,
194 emitversions = allVersions,
195 defaultExtensions = None,
198 'VK_KHR_sampler_mirror_clamp_to_edge',
203 prefixText = prefixStrings + vkPrefixStrings,
207 genDirectory = '../../doc/specs/vulkan',
209 expandEnumerants = False)
211 # Vulkan 1.0 draft - API names to validate man/api spec includes & links
214 filename = '../../doc/specs/vulkan/vkapi.py',
217 versions = allVersions,
218 emitversions = allVersions,
219 defaultExtensions = None,
222 'VK_KHR_sampler_mirror_clamp_to_edge',
228 # Vulkan 1.0 draft - core API validity files for spec
229 # Overwrites validity subdirectories in spec source tree
230 [ ValidityOutputGenerator,
232 filename = 'validity',
235 versions = allVersions,
236 emitversions = allVersions,
237 defaultExtensions = None,
240 'VK_KHR_sampler_mirror_clamp_to_edge',
245 genDirectory = '../../doc/specs/vulkan')
247 # Vulkan 1.0 draft - core API host sync table files for spec
248 # Overwrites subdirectory in spec source tree
249 [ HostSynchronizationOutputGenerator,
251 filename = 'hostsynctable',
254 versions = allVersions,
255 emitversions = allVersions,
256 defaultExtensions = None,
259 'VK_KHR_sampler_mirror_clamp_to_edge',
264 genDirectory = '../../doc/specs/vulkan')
266 # Vulkan 1.0 draft - thread checking layer
267 [ ThreadOutputGenerator,
268 ThreadGeneratorOptions(
269 filename = 'thread_check.h',
272 versions = allVersions,
273 emitversions = allVersions,
274 defaultExtensions = 'vulkan',
275 addExtensions = None,
276 removeExtensions = None,
277 prefixText = prefixStrings + vkPrefixStrings,
278 genFuncPointers = True,
279 protectFile = protectFile,
280 protectFeature = False,
282 protectProtoStr = 'VK_PROTOTYPES',
283 apicall = 'VKAPI_ATTR ',
284 apientry = 'VKAPI_CALL ',
285 apientryp = 'VKAPI_PTR *',
287 genDirectory = outDir)
289 [ ParamCheckerOutputGenerator,
290 ParamCheckerGeneratorOptions(
291 filename = 'parameter_validation.h',
294 versions = allVersions,
295 emitversions = allVersions,
296 defaultExtensions = 'vulkan',
297 addExtensions = None,
298 removeExtensions = None,
299 prefixText = prefixStrings + vkPrefixStrings,
300 genFuncPointers = True,
301 protectFile = protectFile,
302 protectFeature = False,
304 protectProtoStr = 'VK_NO_PROTOTYPES',
305 apicall = 'VKAPI_ATTR ',
306 apientry = 'VKAPI_CALL ',
307 apientryp = 'VKAPI_PTR *',
309 genDirectory = outDir)
314 # create error/warning & diagnostic files
316 errWarn = open(errFilename,'w')
319 diag = open(diagFilename, 'w')
321 # check that output directory exists
322 if (not os.path.isdir(outDir)):
323 write('Output directory does not exist: ', outDir)
327 # Loop over targets, building each
329 for item in buildList:
332 createGenerator = item[0]
334 if (target and target != genOpts.filename):
335 # write('*** Skipping', genOpts.filename)
337 write('*** Building', genOpts.filename)
338 generated = generated + 1
340 gen = createGenerator(errFile=errWarn,
343 reg.setGenerator(gen)
345 write('** Generated', genOpts.filename)
346 endTimer('Time to generate ' + genOpts.filename + ' =')
347 if (target and generated == 0):
348 write('Failed to generate target:', target)
351 pdb.run('genHeaders()')
353 import cProfile, pstats
354 cProfile.run('genHeaders()', 'profile.txt')
355 p = pstats.Stats('profile.txt')
356 p.strip_dirs().sort_stats('time').print_stats(50)