blob: 5ffd5e44ead4c9dea199e44b538a3681be2737ce [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#
Jon Ashburn3ebf1252016-04-19 11:30:31 -06005# 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
Mike Stroyandee76ef2016-01-07 15:35:37 -07008#
Jon Ashburn3ebf1252016-04-19 11:30:31 -06009# http://www.apache.org/licenses/LICENSE-2.0
Mike Stroyandee76ef2016-01-07 15:35:37 -070010#
Jon Ashburn3ebf1252016-04-19 11:30:31 -060011# 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.
Mike Stroyandee76ef2016-01-07 15:35:37 -070016
17import sys, time, pdb, string, cProfile
18from reg import *
Mike Stroyan845bdc42015-11-02 15:30:20 -070019from generator import write, CGeneratorOptions, COutputGenerator, DocGeneratorOptions, DocOutputGenerator, PyOutputGenerator, ValidityOutputGenerator, HostSynchronizationOutputGenerator, ThreadGeneratorOptions, ThreadOutputGenerator
Dustin Gravesdfa6acf2016-02-11 10:10:14 -070020from generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
Mike Stroyandee76ef2016-01-07 15:35:37 -070021
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>
30debug = False
31dump = False
32profile = False
33protect = True
34target = None
35timeit = False
36validate= False
37# Default input / log files
38errFilename = None
39diagFilename = 'diag.txt'
40regFilename = 'vk.xml'
41
42if __name__ == '__main__':
43 i = 1
44 while (i < len(sys.argv)):
45 arg = sys.argv[i]
46 i = i + 1
47 if (arg == '-debug'):
48 write('Enabling debug (-debug)', file=sys.stderr)
49 debug = True
50 elif (arg == '-dump'):
51 write('Enabling dump (-dump)', file=sys.stderr)
52 dump = True
53 elif (arg == '-noprotect'):
54 write('Disabling inclusion protection in output headers', file=sys.stderr)
55 protect = False
56 elif (arg == '-profile'):
57 write('Enabling profiling (-profile)', file=sys.stderr)
58 profile = True
59 elif (arg == '-registry'):
60 regFilename = sys.argv[i]
61 i = i+1
62 write('Using registry ', regFilename, file=sys.stderr)
63 elif (arg == '-time'):
64 write('Enabling timing (-time)', file=sys.stderr)
65 timeit = True
66 elif (arg == '-validate'):
67 write('Enabling group validation (-validate)', file=sys.stderr)
68 validate = True
69 elif (arg[0:1] == '-'):
70 write('Unrecognized argument:', arg, file=sys.stderr)
71 exit(1)
72 else:
73 target = arg
74 write('Using target', target, file=sys.stderr)
75
76# Simple timer functions
77startTime = None
78def startTimer():
79 global startTime
80 startTime = time.clock()
81def endTimer(msg):
82 global startTime
83 endTime = time.clock()
84 if (timeit):
85 write(msg, endTime - startTime)
86 startTime = None
87
88# Load & parse registry
89reg = Registry()
90
91startTimer()
92tree = etree.parse(regFilename)
93endTimer('Time to make ElementTree =')
94
95startTimer()
96reg.loadElementTree(tree)
97endTimer('Time to parse ElementTree =')
98
99if (validate):
100 reg.validateGroups()
101
102if (dump):
103 write('***************************************')
104 write('Performing Registry dump to regdump.txt')
105 write('***************************************')
106 reg.dumpReg(filehandle = open('regdump.txt','w'))
107
108# Turn a list of strings into a regexp string matching exactly those strings
109def makeREstring(list):
110 return '^(' + '|'.join(list) + ')$'
111
112# Descriptive names for various regexp patterns used to select
113# versions and extensions
114allVersions = allExtensions = '.*'
115noVersions = noExtensions = None
116
117# Copyright text prefixing all headers (list of strings).
118prefixStrings = [
119 '/*',
Dustin Graves3ff520c2016-03-28 16:17:38 -0600120 '** Copyright (c) 2015-2016 The Khronos Group Inc.',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700121 '**',
Jon Ashburn3ebf1252016-04-19 11:30:31 -0600122 '** Licensed under the Apache License, Version 2.0 (the "License");',
123 '** you may not use this file except in compliance with the License.',
124 '** You may obtain a copy of the License at',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700125 '**',
Jon Ashburn3ebf1252016-04-19 11:30:31 -0600126 '** http://www.apache.org/licenses/LICENSE-2.0',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700127 '**',
Jon Ashburn3ebf1252016-04-19 11:30:31 -0600128 '** Unless required by applicable law or agreed to in writing, software',
129 '** distributed under the License is distributed on an "AS IS" BASIS,',
130 '** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
131 '** See the License for the specific language governing permissions and',
132 '** limitations under the License.',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700133 '*/',
134 ''
135]
136
137# Text specific to Vulkan headers
138vkPrefixStrings = [
139 '/*',
140 '** This header is generated from the Khronos Vulkan XML API Registry.',
141 '**',
142 '*/',
143 ''
144]
145
146# Defaults for generating re-inclusion protection wrappers (or not)
147protectFile = protect
148protectFeature = protect
149protectProto = protect
150
151buildList = [
Dustin Graves3ff520c2016-03-28 16:17:38 -0600152 # Vulkan 1.0 - header for core API + extensions.
153 # To generate just the core API,
Mike Stroyandee76ef2016-01-07 15:35:37 -0700154 # change to 'defaultExtensions = None' below.
155 [ COutputGenerator,
156 CGeneratorOptions(
Mike Stroyan845bdc42015-11-02 15:30:20 -0700157 filename = 'include/vulkan/vulkan.h',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700158 apiname = 'vulkan',
159 profile = None,
160 versions = allVersions,
161 emitversions = allVersions,
162 defaultExtensions = 'vulkan',
163 addExtensions = None,
164 removeExtensions = None,
165 prefixText = prefixStrings + vkPrefixStrings,
166 genFuncPointers = True,
167 protectFile = protectFile,
168 protectFeature = False,
169 protectProto = '#ifndef',
170 protectProtoStr = 'VK_NO_PROTOTYPES',
171 apicall = 'VKAPI_ATTR ',
172 apientry = 'VKAPI_CALL ',
173 apientryp = 'VKAPI_PTR *',
174 alignFuncParam = 48)
175 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600176 # Vulkan 1.0 draft - API include files for spec and ref pages
Mike Stroyandee76ef2016-01-07 15:35:37 -0700177 # Overwrites include subdirectories in spec source tree
178 # The generated include files do not include the calling convention
179 # macros (apientry etc.), unlike the header files.
Dustin Graves3ff520c2016-03-28 16:17:38 -0600180 # Because the 1.0 core branch includes ref pages for extensions,
181 # all the extension interfaces need to be generated, even though
182 # none are used by the core spec itself.
Mike Stroyandee76ef2016-01-07 15:35:37 -0700183 [ DocOutputGenerator,
184 DocGeneratorOptions(
185 filename = 'vulkan-docs',
186 apiname = 'vulkan',
187 profile = None,
188 versions = allVersions,
189 emitversions = allVersions,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600190 defaultExtensions = None,
191 addExtensions =
192 makeREstring([
193 'VK_KHR_sampler_mirror_clamp_to_edge',
194 ]),
195 removeExtensions =
196 makeREstring([
197 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700198 prefixText = prefixStrings + vkPrefixStrings,
199 apicall = '',
200 apientry = '',
201 apientryp = '*',
202 genDirectory = '../../doc/specs/vulkan',
203 alignFuncParam = 48,
204 expandEnumerants = False)
205 ],
206 # Vulkan 1.0 draft - API names to validate man/api spec includes & links
Mike Stroyandee76ef2016-01-07 15:35:37 -0700207 [ PyOutputGenerator,
208 DocGeneratorOptions(
209 filename = '../../doc/specs/vulkan/vkapi.py',
210 apiname = 'vulkan',
211 profile = None,
212 versions = allVersions,
213 emitversions = allVersions,
214 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600215 addExtensions =
216 makeREstring([
217 'VK_KHR_sampler_mirror_clamp_to_edge',
218 ]),
219 removeExtensions =
220 makeREstring([
221 ]))
Mike Stroyandee76ef2016-01-07 15:35:37 -0700222 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600223 # Vulkan 1.0 draft - core API validity files for spec
224 # Overwrites validity subdirectories in spec source tree
Mike Stroyandee76ef2016-01-07 15:35:37 -0700225 [ ValidityOutputGenerator,
226 DocGeneratorOptions(
227 filename = 'validity',
228 apiname = 'vulkan',
229 profile = None,
230 versions = allVersions,
231 emitversions = allVersions,
232 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600233 addExtensions =
234 makeREstring([
235 'VK_KHR_sampler_mirror_clamp_to_edge',
236 ]),
237 removeExtensions =
238 makeREstring([
239 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700240 genDirectory = '../../doc/specs/vulkan')
241 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600242 # Vulkan 1.0 draft - core API host sync table files for spec
243 # Overwrites subdirectory in spec source tree
Mike Stroyandee76ef2016-01-07 15:35:37 -0700244 [ HostSynchronizationOutputGenerator,
245 DocGeneratorOptions(
246 filename = 'hostsynctable',
247 apiname = 'vulkan',
248 profile = None,
249 versions = allVersions,
250 emitversions = allVersions,
251 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600252 addExtensions =
253 makeREstring([
254 'VK_KHR_sampler_mirror_clamp_to_edge',
255 ]),
256 removeExtensions =
257 makeREstring([
258 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700259 genDirectory = '../../doc/specs/vulkan')
260 ],
Mike Stroyan845bdc42015-11-02 15:30:20 -0700261 # Vulkan 1.0 draft - thread checking layer
262 [ ThreadOutputGenerator,
263 ThreadGeneratorOptions(
264 filename = 'thread_check.h',
265 apiname = 'vulkan',
266 profile = None,
267 versions = allVersions,
268 emitversions = allVersions,
269 defaultExtensions = 'vulkan',
270 addExtensions = None,
271 removeExtensions = None,
272 prefixText = prefixStrings + vkPrefixStrings,
273 genFuncPointers = True,
274 protectFile = protectFile,
275 protectFeature = False,
276 protectProto = True,
277 protectProtoStr = 'VK_PROTOTYPES',
278 apicall = '',
279 apientry = 'VKAPI_CALL ',
280 apientryp = 'VKAPI_PTR *',
281 alignFuncParam = 48)
282 ],
Dustin Gravesdfa6acf2016-02-11 10:10:14 -0700283 [ ParamCheckerOutputGenerator,
284 ParamCheckerGeneratorOptions(
Mark Lobodzinski739391a2016-03-17 15:08:18 -0600285 filename = 'parameter_validation.h',
Dustin Gravesdfa6acf2016-02-11 10:10:14 -0700286 apiname = 'vulkan',
287 profile = None,
288 versions = allVersions,
289 emitversions = allVersions,
290 defaultExtensions = 'vulkan',
291 addExtensions = None,
292 removeExtensions = None,
293 prefixText = prefixStrings + vkPrefixStrings,
294 genFuncPointers = True,
295 protectFile = protectFile,
296 protectFeature = False,
297 protectProto = None,
298 protectProtoStr = 'VK_NO_PROTOTYPES',
299 apicall = 'VKAPI_ATTR ',
300 apientry = 'VKAPI_CALL ',
301 apientryp = 'VKAPI_PTR *',
302 alignFuncParam = 48)
303 ],
Mike Stroyandee76ef2016-01-07 15:35:37 -0700304 None
305]
306
307# create error/warning & diagnostic files
308if (errFilename):
309 errWarn = open(errFilename,'w')
310else:
311 errWarn = sys.stderr
312diag = open(diagFilename, 'w')
313
314def genHeaders():
315 # Loop over targets, building each
316 generated = 0
317 for item in buildList:
318 if (item == None):
319 break
320 createGenerator = item[0]
321 genOpts = item[1]
322 if (target and target != genOpts.filename):
323 # write('*** Skipping', genOpts.filename)
324 continue
325 write('*** Building', genOpts.filename)
326 generated = generated + 1
327 startTimer()
328 gen = createGenerator(errFile=errWarn,
329 warnFile=errWarn,
330 diagFile=diag)
331 reg.setGenerator(gen)
332 reg.apiGen(genOpts)
333 write('** Generated', genOpts.filename)
334 endTimer('Time to generate ' + genOpts.filename + ' =')
335 if (target and generated == 0):
336 write('Failed to generate target:', target)
337
338if (debug):
339 pdb.run('genHeaders()')
340elif (profile):
341 import cProfile, pstats
342 cProfile.run('genHeaders()', 'profile.txt')
343 p = pstats.Stats('profile.txt')
344 p.strip_dirs().sort_stats('time').print_stats(50)
345else:
346 genHeaders()