blob: 993477cd73445e5562974437aef8c5767537a1d1 [file] [log] [blame]
Mike Stroyandee76ef2016-01-07 15:35:37 -07001#!/usr/bin/env python
2#
Dustin Graves94f19142016-05-10 16:44:16 -06003# Copyright (c) 2013-2016 The Khronos Group Inc.
Mike Stroyandee76ef2016-01-07 15:35:37 -07004#
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'
Jamie Madille6f08932016-05-04 08:17:33 -070041outDir = '.'
Mike Stroyandee76ef2016-01-07 15:35:37 -070042
43if __name__ == '__main__':
44 i = 1
45 while (i < len(sys.argv)):
46 arg = sys.argv[i]
47 i = i + 1
48 if (arg == '-debug'):
49 write('Enabling debug (-debug)', file=sys.stderr)
50 debug = True
51 elif (arg == '-dump'):
52 write('Enabling dump (-dump)', file=sys.stderr)
53 dump = True
54 elif (arg == '-noprotect'):
55 write('Disabling inclusion protection in output headers', file=sys.stderr)
56 protect = False
57 elif (arg == '-profile'):
58 write('Enabling profiling (-profile)', file=sys.stderr)
59 profile = True
60 elif (arg == '-registry'):
61 regFilename = sys.argv[i]
62 i = i+1
63 write('Using registry ', regFilename, file=sys.stderr)
64 elif (arg == '-time'):
65 write('Enabling timing (-time)', file=sys.stderr)
66 timeit = True
67 elif (arg == '-validate'):
68 write('Enabling group validation (-validate)', file=sys.stderr)
69 validate = True
Jamie Madille6f08932016-05-04 08:17:33 -070070 elif (arg == '-outdir'):
71 outDir = sys.argv[i]
72 i = i+1
73 write('Using output directory ', outDir, file=sys.stderr)
Mike Stroyandee76ef2016-01-07 15:35:37 -070074 elif (arg[0:1] == '-'):
75 write('Unrecognized argument:', arg, file=sys.stderr)
76 exit(1)
77 else:
78 target = arg
79 write('Using target', target, file=sys.stderr)
80
81# Simple timer functions
82startTime = None
83def startTimer():
84 global startTime
85 startTime = time.clock()
86def endTimer(msg):
87 global startTime
88 endTime = time.clock()
89 if (timeit):
90 write(msg, endTime - startTime)
91 startTime = None
92
93# Load & parse registry
94reg = Registry()
95
96startTimer()
97tree = etree.parse(regFilename)
98endTimer('Time to make ElementTree =')
99
100startTimer()
101reg.loadElementTree(tree)
102endTimer('Time to parse ElementTree =')
103
104if (validate):
105 reg.validateGroups()
106
107if (dump):
108 write('***************************************')
109 write('Performing Registry dump to regdump.txt')
110 write('***************************************')
111 reg.dumpReg(filehandle = open('regdump.txt','w'))
112
113# Turn a list of strings into a regexp string matching exactly those strings
114def makeREstring(list):
115 return '^(' + '|'.join(list) + ')$'
116
117# Descriptive names for various regexp patterns used to select
118# versions and extensions
119allVersions = allExtensions = '.*'
120noVersions = noExtensions = None
121
122# Copyright text prefixing all headers (list of strings).
123prefixStrings = [
124 '/*',
Dustin Graves3ff520c2016-03-28 16:17:38 -0600125 '** Copyright (c) 2015-2016 The Khronos Group Inc.',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700126 '**',
Jon Ashburn3ebf1252016-04-19 11:30:31 -0600127 '** 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',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700130 '**',
Jon Ashburn3ebf1252016-04-19 11:30:31 -0600131 '** http://www.apache.org/licenses/LICENSE-2.0',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700132 '**',
Jon Ashburn3ebf1252016-04-19 11:30:31 -0600133 '** 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.',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700138 '*/',
139 ''
140]
141
142# Text specific to Vulkan headers
143vkPrefixStrings = [
144 '/*',
145 '** This header is generated from the Khronos Vulkan XML API Registry.',
146 '**',
147 '*/',
148 ''
149]
150
151# Defaults for generating re-inclusion protection wrappers (or not)
152protectFile = protect
153protectFeature = protect
154protectProto = protect
155
156buildList = [
Dustin Graves3ff520c2016-03-28 16:17:38 -0600157 # Vulkan 1.0 - header for core API + extensions.
158 # To generate just the core API,
Mike Stroyandee76ef2016-01-07 15:35:37 -0700159 # change to 'defaultExtensions = None' below.
160 [ COutputGenerator,
161 CGeneratorOptions(
Mike Stroyan845bdc42015-11-02 15:30:20 -0700162 filename = 'include/vulkan/vulkan.h',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700163 apiname = 'vulkan',
164 profile = None,
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 *',
179 alignFuncParam = 48)
180 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600181 # Vulkan 1.0 draft - API include files for spec and ref pages
Mike Stroyandee76ef2016-01-07 15:35:37 -0700182 # 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.
Dustin Graves3ff520c2016-03-28 16:17:38 -0600185 # 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.
Mike Stroyandee76ef2016-01-07 15:35:37 -0700188 [ DocOutputGenerator,
189 DocGeneratorOptions(
190 filename = 'vulkan-docs',
191 apiname = 'vulkan',
192 profile = None,
193 versions = allVersions,
194 emitversions = allVersions,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600195 defaultExtensions = None,
196 addExtensions =
197 makeREstring([
198 'VK_KHR_sampler_mirror_clamp_to_edge',
199 ]),
200 removeExtensions =
201 makeREstring([
202 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700203 prefixText = prefixStrings + vkPrefixStrings,
204 apicall = '',
205 apientry = '',
206 apientryp = '*',
207 genDirectory = '../../doc/specs/vulkan',
208 alignFuncParam = 48,
209 expandEnumerants = False)
210 ],
211 # Vulkan 1.0 draft - API names to validate man/api spec includes & links
Mike Stroyandee76ef2016-01-07 15:35:37 -0700212 [ PyOutputGenerator,
213 DocGeneratorOptions(
214 filename = '../../doc/specs/vulkan/vkapi.py',
215 apiname = 'vulkan',
216 profile = None,
217 versions = allVersions,
218 emitversions = allVersions,
219 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600220 addExtensions =
221 makeREstring([
222 'VK_KHR_sampler_mirror_clamp_to_edge',
223 ]),
224 removeExtensions =
225 makeREstring([
226 ]))
Mike Stroyandee76ef2016-01-07 15:35:37 -0700227 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600228 # Vulkan 1.0 draft - core API validity files for spec
229 # Overwrites validity subdirectories in spec source tree
Mike Stroyandee76ef2016-01-07 15:35:37 -0700230 [ ValidityOutputGenerator,
231 DocGeneratorOptions(
232 filename = 'validity',
233 apiname = 'vulkan',
234 profile = None,
235 versions = allVersions,
236 emitversions = allVersions,
237 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600238 addExtensions =
239 makeREstring([
240 'VK_KHR_sampler_mirror_clamp_to_edge',
241 ]),
242 removeExtensions =
243 makeREstring([
244 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700245 genDirectory = '../../doc/specs/vulkan')
246 ],
Dustin Graves3ff520c2016-03-28 16:17:38 -0600247 # Vulkan 1.0 draft - core API host sync table files for spec
248 # Overwrites subdirectory in spec source tree
Mike Stroyandee76ef2016-01-07 15:35:37 -0700249 [ HostSynchronizationOutputGenerator,
250 DocGeneratorOptions(
251 filename = 'hostsynctable',
252 apiname = 'vulkan',
253 profile = None,
254 versions = allVersions,
255 emitversions = allVersions,
256 defaultExtensions = None,
Dustin Graves3ff520c2016-03-28 16:17:38 -0600257 addExtensions =
258 makeREstring([
259 'VK_KHR_sampler_mirror_clamp_to_edge',
260 ]),
261 removeExtensions =
262 makeREstring([
263 ]),
Mike Stroyandee76ef2016-01-07 15:35:37 -0700264 genDirectory = '../../doc/specs/vulkan')
265 ],
Mike Stroyan845bdc42015-11-02 15:30:20 -0700266 # Vulkan 1.0 draft - thread checking layer
267 [ ThreadOutputGenerator,
268 ThreadGeneratorOptions(
269 filename = 'thread_check.h',
270 apiname = 'vulkan',
271 profile = None,
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,
281 protectProto = True,
282 protectProtoStr = 'VK_PROTOTYPES',
Chia-I Wuab461772016-05-16 11:48:11 +0800283 apicall = 'VKAPI_ATTR ',
Mike Stroyan845bdc42015-11-02 15:30:20 -0700284 apientry = 'VKAPI_CALL ',
285 apientryp = 'VKAPI_PTR *',
Jamie Madille6f08932016-05-04 08:17:33 -0700286 alignFuncParam = 48,
287 genDirectory = outDir)
Mike Stroyan845bdc42015-11-02 15:30:20 -0700288 ],
Dustin Gravesdfa6acf2016-02-11 10:10:14 -0700289 [ ParamCheckerOutputGenerator,
290 ParamCheckerGeneratorOptions(
Mark Lobodzinski739391a2016-03-17 15:08:18 -0600291 filename = 'parameter_validation.h',
Dustin Gravesdfa6acf2016-02-11 10:10:14 -0700292 apiname = 'vulkan',
293 profile = None,
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,
303 protectProto = None,
304 protectProtoStr = 'VK_NO_PROTOTYPES',
305 apicall = 'VKAPI_ATTR ',
306 apientry = 'VKAPI_CALL ',
307 apientryp = 'VKAPI_PTR *',
Jamie Madille6f08932016-05-04 08:17:33 -0700308 alignFuncParam = 48,
309 genDirectory = outDir)
Dustin Gravesdfa6acf2016-02-11 10:10:14 -0700310 ],
Mike Stroyandee76ef2016-01-07 15:35:37 -0700311 None
312]
313
314# create error/warning & diagnostic files
315if (errFilename):
316 errWarn = open(errFilename,'w')
317else:
318 errWarn = sys.stderr
319diag = open(diagFilename, 'w')
320
Jamie Madille6f08932016-05-04 08:17:33 -0700321# check that output directory exists
322if (not os.path.isdir(outDir)):
323 write('Output directory does not exist: ', outDir)
324 raise
325
Mike Stroyandee76ef2016-01-07 15:35:37 -0700326def genHeaders():
327 # Loop over targets, building each
328 generated = 0
329 for item in buildList:
330 if (item == None):
331 break
332 createGenerator = item[0]
333 genOpts = item[1]
334 if (target and target != genOpts.filename):
335 # write('*** Skipping', genOpts.filename)
336 continue
337 write('*** Building', genOpts.filename)
338 generated = generated + 1
339 startTimer()
340 gen = createGenerator(errFile=errWarn,
341 warnFile=errWarn,
342 diagFile=diag)
343 reg.setGenerator(gen)
344 reg.apiGen(genOpts)
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)
349
350if (debug):
351 pdb.run('genHeaders()')
352elif (profile):
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)
357else:
358 genHeaders()