blob: 986eb06ede9900c18288b2e2224470fd09604031 [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
Mike Stroyandee76ef2016-01-07 15:35:37 -070027
28# debug - start header generation in debugger
29# dump - dump registry after loading
30# profile - enable Python profiling
31# protect - whether to use #ifndef protections
32# registry <filename> - use specified XML registry instead of gl.xml
33# target - string name of target header, or all targets if None
34# timeit - time length of registry loading & header generation
35# validate - validate return & parameter group tags against <group>
36debug = False
37dump = False
38profile = False
39protect = True
40target = None
41timeit = False
42validate= False
43# Default input / log files
44errFilename = None
45diagFilename = 'diag.txt'
46regFilename = 'vk.xml'
47
48if __name__ == '__main__':
49 i = 1
50 while (i < len(sys.argv)):
51 arg = sys.argv[i]
52 i = i + 1
53 if (arg == '-debug'):
54 write('Enabling debug (-debug)', file=sys.stderr)
55 debug = True
56 elif (arg == '-dump'):
57 write('Enabling dump (-dump)', file=sys.stderr)
58 dump = True
59 elif (arg == '-noprotect'):
60 write('Disabling inclusion protection in output headers', file=sys.stderr)
61 protect = False
62 elif (arg == '-profile'):
63 write('Enabling profiling (-profile)', file=sys.stderr)
64 profile = True
65 elif (arg == '-registry'):
66 regFilename = sys.argv[i]
67 i = i+1
68 write('Using registry ', regFilename, file=sys.stderr)
69 elif (arg == '-time'):
70 write('Enabling timing (-time)', file=sys.stderr)
71 timeit = True
72 elif (arg == '-validate'):
73 write('Enabling group validation (-validate)', file=sys.stderr)
74 validate = True
75 elif (arg[0:1] == '-'):
76 write('Unrecognized argument:', arg, file=sys.stderr)
77 exit(1)
78 else:
79 target = arg
80 write('Using target', target, file=sys.stderr)
81
82# Simple timer functions
83startTime = None
84def startTimer():
85 global startTime
86 startTime = time.clock()
87def endTimer(msg):
88 global startTime
89 endTime = time.clock()
90 if (timeit):
91 write(msg, endTime - startTime)
92 startTime = None
93
94# Load & parse registry
95reg = Registry()
96
97startTimer()
98tree = etree.parse(regFilename)
99endTimer('Time to make ElementTree =')
100
101startTimer()
102reg.loadElementTree(tree)
103endTimer('Time to parse ElementTree =')
104
105if (validate):
106 reg.validateGroups()
107
108if (dump):
109 write('***************************************')
110 write('Performing Registry dump to regdump.txt')
111 write('***************************************')
112 reg.dumpReg(filehandle = open('regdump.txt','w'))
113
114# Turn a list of strings into a regexp string matching exactly those strings
115def makeREstring(list):
116 return '^(' + '|'.join(list) + ')$'
117
118# Descriptive names for various regexp patterns used to select
119# versions and extensions
120allVersions = allExtensions = '.*'
121noVersions = noExtensions = None
122
123# Copyright text prefixing all headers (list of strings).
124prefixStrings = [
125 '/*',
126 '** Copyright (c) 2015 The Khronos Group Inc.',
127 '**',
128 '** Permission is hereby granted, free of charge, to any person obtaining a',
129 '** copy of this software and/or associated documentation files (the',
130 '** "Materials"), to deal in the Materials without restriction, including',
131 '** without limitation the rights to use, copy, modify, merge, publish,',
132 '** distribute, sublicense, and/or sell copies of the Materials, and to',
133 '** permit persons to whom the Materials are furnished to do so, subject to',
134 '** the following conditions:',
135 '**',
136 '** The above copyright notice and this permission notice shall be included',
137 '** in all copies or substantial portions of the Materials.',
138 '**',
139 '** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,',
140 '** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF',
141 '** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.',
142 '** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY',
143 '** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,',
144 '** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE',
145 '** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.',
146 '*/',
147 ''
148]
149
150# Text specific to Vulkan headers
151vkPrefixStrings = [
152 '/*',
153 '** This header is generated from the Khronos Vulkan XML API Registry.',
154 '**',
155 '*/',
156 ''
157]
158
159# Defaults for generating re-inclusion protection wrappers (or not)
160protectFile = protect
161protectFeature = protect
162protectProto = protect
163
164buildList = [
165 # Vulkan 1.0 - core API + extensions. To generate just the core API,
166 # change to 'defaultExtensions = None' below.
167 [ COutputGenerator,
168 CGeneratorOptions(
Mike Stroyan845bdc42015-11-02 15:30:20 -0700169 filename = 'include/vulkan/vulkan.h',
Mike Stroyandee76ef2016-01-07 15:35:37 -0700170 apiname = 'vulkan',
171 profile = None,
172 versions = allVersions,
173 emitversions = allVersions,
174 defaultExtensions = 'vulkan',
175 addExtensions = None,
176 removeExtensions = None,
177 prefixText = prefixStrings + vkPrefixStrings,
178 genFuncPointers = True,
179 protectFile = protectFile,
180 protectFeature = False,
181 protectProto = '#ifndef',
182 protectProtoStr = 'VK_NO_PROTOTYPES',
183 apicall = 'VKAPI_ATTR ',
184 apientry = 'VKAPI_CALL ',
185 apientryp = 'VKAPI_PTR *',
186 alignFuncParam = 48)
187 ],
188 # Vulkan 1.0 draft - core API include files for spec
189 # Overwrites include subdirectories in spec source tree
190 # The generated include files do not include the calling convention
191 # macros (apientry etc.), unlike the header files.
192 [ DocOutputGenerator,
193 DocGeneratorOptions(
194 filename = 'vulkan-docs',
195 apiname = 'vulkan',
196 profile = None,
197 versions = allVersions,
198 emitversions = allVersions,
199 defaultExtensions = 'vulkan',
200 addExtensions = None,
201 removeExtensions = None,
202 prefixText = prefixStrings + vkPrefixStrings,
203 apicall = '',
204 apientry = '',
205 apientryp = '*',
206 genDirectory = '../../doc/specs/vulkan',
207 alignFuncParam = 48,
208 expandEnumerants = False)
209 ],
210 # Vulkan 1.0 draft - API names to validate man/api spec includes & links
211 # filename = 'vkapi.py',
212 [ 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,
220 addExtensions = None,
221 removeExtensions = None)
222 ],
223 # Vulkan 1.0 draft - core API include files for spec
224 # Overwrites include subdirectories in spec source tree
225 [ ValidityOutputGenerator,
226 DocGeneratorOptions(
227 filename = 'validity',
228 apiname = 'vulkan',
229 profile = None,
230 versions = allVersions,
231 emitversions = allVersions,
232 defaultExtensions = None,
233 addExtensions = None,
234 removeExtensions = None,
235 genDirectory = '../../doc/specs/vulkan')
236 ],
237 # Vulkan 1.0 draft - core API include files for spec
238 # Overwrites include subdirectories in spec source tree
239 [ HostSynchronizationOutputGenerator,
240 DocGeneratorOptions(
241 filename = 'hostsynctable',
242 apiname = 'vulkan',
243 profile = None,
244 versions = allVersions,
245 emitversions = allVersions,
246 defaultExtensions = None,
247 addExtensions = None,
248 removeExtensions = None,
249 genDirectory = '../../doc/specs/vulkan')
250 ],
Mike Stroyan845bdc42015-11-02 15:30:20 -0700251 # Vulkan 1.0 draft - thread checking layer
252 [ ThreadOutputGenerator,
253 ThreadGeneratorOptions(
254 filename = 'thread_check.h',
255 apiname = 'vulkan',
256 profile = None,
257 versions = allVersions,
258 emitversions = allVersions,
259 defaultExtensions = 'vulkan',
260 addExtensions = None,
261 removeExtensions = None,
262 prefixText = prefixStrings + vkPrefixStrings,
263 genFuncPointers = True,
264 protectFile = protectFile,
265 protectFeature = False,
266 protectProto = True,
267 protectProtoStr = 'VK_PROTOTYPES',
268 apicall = '',
269 apientry = 'VKAPI_CALL ',
270 apientryp = 'VKAPI_PTR *',
271 alignFuncParam = 48)
272 ],
Mike Stroyandee76ef2016-01-07 15:35:37 -0700273 None
274]
275
276# create error/warning & diagnostic files
277if (errFilename):
278 errWarn = open(errFilename,'w')
279else:
280 errWarn = sys.stderr
281diag = open(diagFilename, 'w')
282
283def genHeaders():
284 # Loop over targets, building each
285 generated = 0
286 for item in buildList:
287 if (item == None):
288 break
289 createGenerator = item[0]
290 genOpts = item[1]
291 if (target and target != genOpts.filename):
292 # write('*** Skipping', genOpts.filename)
293 continue
294 write('*** Building', genOpts.filename)
295 generated = generated + 1
296 startTimer()
297 gen = createGenerator(errFile=errWarn,
298 warnFile=errWarn,
299 diagFile=diag)
300 reg.setGenerator(gen)
301 reg.apiGen(genOpts)
302 write('** Generated', genOpts.filename)
303 endTimer('Time to generate ' + genOpts.filename + ' =')
304 if (target and generated == 0):
305 write('Failed to generate target:', target)
306
307if (debug):
308 pdb.run('genHeaders()')
309elif (profile):
310 import cProfile, pstats
311 cProfile.run('genHeaders()', 'profile.txt')
312 p = pstats.Stats('profile.txt')
313 p.strip_dirs().sort_stats('time').print_stats(50)
314else:
315 genHeaders()