blob: 8aa9cc5f613f3b7f5f27aaa14df7edf6558d91b4 [file] [log] [blame]
Mike Stroyandee76ef2016-01-07 15:35:37 -07001#!/usr/bin/env python
2#
3# Copyright (c) 2013-2015 The Khronos Group Inc.
4#
5# Permission is hereby granted, free of charge, to any person obtaining a
6# copy of this software and/or associated documentation files (the
7# "Materials"), to deal in the Materials without restriction, including
8# without limitation the rights to use, copy, modify, merge, publish,
9# distribute, sublicense, and/or sell copies of the Materials, and to
10# permit persons to whom the Materials are furnished to do so, subject to
11# the following conditions:
12#
13# The above copyright notice and this permission notice shall be included
14# in all copies or substantial portions of the Materials.
15#
16# THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
23
24import sys, time, pdb, string, cProfile
25from reg import *
Mike Stroyan845bdc42015-11-02 15:30:20 -070026from generator import write, CGeneratorOptions, COutputGenerator, DocGeneratorOptions, DocOutputGenerator, PyOutputGenerator, ValidityOutputGenerator, HostSynchronizationOutputGenerator, ThreadGeneratorOptions, ThreadOutputGenerator
Dustin Gravesdfa6acf2016-02-11 10:10:14 -070027from generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
Mike Stroyandee76ef2016-01-07 15:35:37 -070028
29# debug - start header generation in debugger
30# dump - dump registry after loading
31# profile - enable Python profiling
32# protect - whether to use #ifndef protections
33# registry <filename> - use specified XML registry instead of gl.xml
34# target - string name of target header, or all targets if None
35# timeit - time length of registry loading & header generation
36# validate - validate return & parameter group tags against <group>
37debug = False
38dump = False
39profile = False
40protect = True
41target = None
42timeit = False
43validate= False
44# Default input / log files
45errFilename = None
46diagFilename = 'diag.txt'
47regFilename = 'vk.xml'
48
49if __name__ == '__main__':
50 i = 1
51 while (i < len(sys.argv)):
52 arg = sys.argv[i]
53 i = i + 1
54 if (arg == '-debug'):
55 write('Enabling debug (-debug)', file=sys.stderr)
56 debug = True
57 elif (arg == '-dump'):
58 write('Enabling dump (-dump)', file=sys.stderr)
59 dump = True
60 elif (arg == '-noprotect'):
61 write('Disabling inclusion protection in output headers', file=sys.stderr)
62 protect = False
63 elif (arg == '-profile'):
64 write('Enabling profiling (-profile)', file=sys.stderr)
65 profile = True
66 elif (arg == '-registry'):
67 regFilename = sys.argv[i]
68 i = i+1
69 write('Using registry ', regFilename, file=sys.stderr)
70 elif (arg == '-time'):
71 write('Enabling timing (-time)', file=sys.stderr)
72 timeit = True
73 elif (arg == '-validate'):
74 write('Enabling group validation (-validate)', file=sys.stderr)
75 validate = True
76 elif (arg[0:1] == '-'):
77 write('Unrecognized argument:', arg, file=sys.stderr)
78 exit(1)
79 else:
80 target = arg
81 write('Using target', target, file=sys.stderr)
82
83# Simple timer functions
84startTime = None
85def startTimer():
86 global startTime
87 startTime = time.clock()
88def endTimer(msg):
89 global startTime
90 endTime = time.clock()
91 if (timeit):
92 write(msg, endTime - startTime)
93 startTime = None
94
95# Load & parse registry
96reg = Registry()
97
98startTimer()
99tree = etree.parse(regFilename)
100endTimer('Time to make ElementTree =')
101
102startTimer()
103reg.loadElementTree(tree)
104endTimer('Time to parse ElementTree =')
105
106if (validate):
107 reg.validateGroups()
108
109if (dump):
110 write('***************************************')
111 write('Performing Registry dump to regdump.txt')
112 write('***************************************')
113 reg.dumpReg(filehandle = open('regdump.txt','w'))
114
115# Turn a list of strings into a regexp string matching exactly those strings
116def makeREstring(list):
117 return '^(' + '|'.join(list) + ')$'
118
119# Descriptive names for various regexp patterns used to select
120# versions and extensions
121allVersions = allExtensions = '.*'
122noVersions = noExtensions = None
123
124# Copyright text prefixing all headers (list of strings).
125prefixStrings = [
126 '/*',
Dustin Graves3ff520c2016-03-28 16:17:38 -0600127 '** Copyright (c) 2015-2016 The Khronos Group Inc.',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700128 '**',
129 '** Permission is hereby granted, free of charge, to any person obtaining a',
130 '** copy of this software and/or associated documentation files (the',
131 '** "Materials"), to deal in the Materials without restriction, including',
132 '** without limitation the rights to use, copy, modify, merge, publish,',
133 '** distribute, sublicense, and/or sell copies of the Materials, and to',
134 '** permit persons to whom the Materials are furnished to do so, subject to',
135 '** the following conditions:',
136 '**',
137 '** The above copyright notice and this permission notice shall be included',
138 '** in all copies or substantial portions of the Materials.',
139 '**',
140 '** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,',
141 '** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF',
142 '** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.',
143 '** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY',
144 '** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,',
145 '** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE',
146 '** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.',
147 '*/',
148 ''
149]
150
151# Text specific to Vulkan headers
152vkPrefixStrings = [
153 '/*',
154 '** This header is generated from the Khronos Vulkan XML API Registry.',
155 '**',
156 '*/',
157 ''
158]
159
160# Defaults for generating re-inclusion protection wrappers (or not)
161protectFile = protect
162protectFeature = protect
163protectProto = protect
164
165buildList = [
Dustin Graves3ff520c2016-03-28 16:17:38 -0600166 # Vulkan 1.0 - header for core API + extensions.
167 # To generate just the core API,
Mike Stroyandee76ef2016-01-07 15:35:37 -0700168 # change to 'defaultExtensions = None' below.
169 [ COutputGenerator,
170 CGeneratorOptions(
Mike Stroyan845bdc42015-11-02 15:30:20 -0700171 filename = 'include/vulkan/vulkan.h',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700172 apiname = 'vulkan',
173 profile = None,
174 versions = allVersions,
175 emitversions = allVersions,
176 defaultExtensions = 'vulkan',
177 addExtensions = None,
178 removeExtensions = None,
179 prefixText = prefixStrings + vkPrefixStrings,
180 genFuncPointers = True,
181 protectFile = protectFile,
182 protectFeature = False,
183 protectProto = '#ifndef',
184 protectProtoStr = 'VK_NO_PROTOTYPES',
185 apicall = 'VKAPI_ATTR ',
186 apientry = 'VKAPI_CALL ',
187 apientryp = 'VKAPI_PTR *',
188 alignFuncParam = 48)
189 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600190 # Vulkan 1.0 draft - API include files for spec and ref pages
Mike Stroyandee76ef2016-01-07 15:35:37 -0700191 # Overwrites include subdirectories in spec source tree
192 # The generated include files do not include the calling convention
193 # macros (apientry etc.), unlike the header files.
Dustin Graves3ff520c2016-03-28 16:17:38 -0600194 # Because the 1.0 core branch includes ref pages for extensions,
195 # all the extension interfaces need to be generated, even though
196 # none are used by the core spec itself.
Mike Stroyandee76ef2016-01-07 15:35:37 -0700197 [ DocOutputGenerator,
198 DocGeneratorOptions(
199 filename = 'vulkan-docs',
200 apiname = 'vulkan',
201 profile = None,
202 versions = allVersions,
203 emitversions = allVersions,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600204 defaultExtensions = None,
205 addExtensions =
206 makeREstring([
207 'VK_KHR_sampler_mirror_clamp_to_edge',
208 ]),
209 removeExtensions =
210 makeREstring([
211 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700212 prefixText = prefixStrings + vkPrefixStrings,
213 apicall = '',
214 apientry = '',
215 apientryp = '*',
216 genDirectory = '../../doc/specs/vulkan',
217 alignFuncParam = 48,
218 expandEnumerants = False)
219 ],
220 # Vulkan 1.0 draft - API names to validate man/api spec includes & links
Mike Stroyandee76ef2016-01-07 15:35:37 -0700221 [ PyOutputGenerator,
222 DocGeneratorOptions(
223 filename = '../../doc/specs/vulkan/vkapi.py',
224 apiname = 'vulkan',
225 profile = None,
226 versions = allVersions,
227 emitversions = allVersions,
228 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600229 addExtensions =
230 makeREstring([
231 'VK_KHR_sampler_mirror_clamp_to_edge',
232 ]),
233 removeExtensions =
234 makeREstring([
235 ]))
Mike Stroyandee76ef2016-01-07 15:35:37 -0700236 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600237 # Vulkan 1.0 draft - core API validity files for spec
238 # Overwrites validity subdirectories in spec source tree
Mike Stroyandee76ef2016-01-07 15:35:37 -0700239 [ ValidityOutputGenerator,
240 DocGeneratorOptions(
241 filename = 'validity',
242 apiname = 'vulkan',
243 profile = None,
244 versions = allVersions,
245 emitversions = allVersions,
246 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600247 addExtensions =
248 makeREstring([
249 'VK_KHR_sampler_mirror_clamp_to_edge',
250 ]),
251 removeExtensions =
252 makeREstring([
253 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700254 genDirectory = '../../doc/specs/vulkan')
255 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600256 # Vulkan 1.0 draft - core API host sync table files for spec
257 # Overwrites subdirectory in spec source tree
Mike Stroyandee76ef2016-01-07 15:35:37 -0700258 [ HostSynchronizationOutputGenerator,
259 DocGeneratorOptions(
260 filename = 'hostsynctable',
261 apiname = 'vulkan',
262 profile = None,
263 versions = allVersions,
264 emitversions = allVersions,
265 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600266 addExtensions =
267 makeREstring([
268 'VK_KHR_sampler_mirror_clamp_to_edge',
269 ]),
270 removeExtensions =
271 makeREstring([
272 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700273 genDirectory = '../../doc/specs/vulkan')
274 ],
Mike Stroyan845bdc42015-11-02 15:30:20 -0700275 # Vulkan 1.0 draft - thread checking layer
276 [ ThreadOutputGenerator,
277 ThreadGeneratorOptions(
278 filename = 'thread_check.h',
279 apiname = 'vulkan',
280 profile = None,
281 versions = allVersions,
282 emitversions = allVersions,
283 defaultExtensions = 'vulkan',
284 addExtensions = None,
285 removeExtensions = None,
286 prefixText = prefixStrings + vkPrefixStrings,
287 genFuncPointers = True,
288 protectFile = protectFile,
289 protectFeature = False,
290 protectProto = True,
291 protectProtoStr = 'VK_PROTOTYPES',
292 apicall = '',
293 apientry = 'VKAPI_CALL ',
294 apientryp = 'VKAPI_PTR *',
295 alignFuncParam = 48)
296 ],
Dustin Gravesdfa6acf2016-02-11 10:10:14 -0700297 [ ParamCheckerOutputGenerator,
298 ParamCheckerGeneratorOptions(
Mark Lobodzinski739391a2016-03-17 15:08:18 -0600299 filename = 'parameter_validation.h',
Dustin Gravesdfa6acf2016-02-11 10:10:14 -0700300 apiname = 'vulkan',
301 profile = None,
302 versions = allVersions,
303 emitversions = allVersions,
304 defaultExtensions = 'vulkan',
305 addExtensions = None,
306 removeExtensions = None,
307 prefixText = prefixStrings + vkPrefixStrings,
308 genFuncPointers = True,
309 protectFile = protectFile,
310 protectFeature = False,
311 protectProto = None,
312 protectProtoStr = 'VK_NO_PROTOTYPES',
313 apicall = 'VKAPI_ATTR ',
314 apientry = 'VKAPI_CALL ',
315 apientryp = 'VKAPI_PTR *',
316 alignFuncParam = 48)
317 ],
Mike Stroyandee76ef2016-01-07 15:35:37 -0700318 None
319]
320
321# create error/warning & diagnostic files
322if (errFilename):
323 errWarn = open(errFilename,'w')
324else:
325 errWarn = sys.stderr
326diag = open(diagFilename, 'w')
327
328def genHeaders():
329 # Loop over targets, building each
330 generated = 0
331 for item in buildList:
332 if (item == None):
333 break
334 createGenerator = item[0]
335 genOpts = item[1]
336 if (target and target != genOpts.filename):
337 # write('*** Skipping', genOpts.filename)
338 continue
339 write('*** Building', genOpts.filename)
340 generated = generated + 1
341 startTimer()
342 gen = createGenerator(errFile=errWarn,
343 warnFile=errWarn,
344 diagFile=diag)
345 reg.setGenerator(gen)
346 reg.apiGen(genOpts)
347 write('** Generated', genOpts.filename)
348 endTimer('Time to generate ' + genOpts.filename + ' =')
349 if (target and generated == 0):
350 write('Failed to generate target:', target)
351
352if (debug):
353 pdb.run('genHeaders()')
354elif (profile):
355 import cProfile, pstats
356 cProfile.run('genHeaders()', 'profile.txt')
357 p = pstats.Stats('profile.txt')
358 p.strip_dirs().sort_stats('time').print_stats(50)
359else:
360 genHeaders()