header: Move vk.xml to version 1.0.29
[platform/upstream/Vulkan-LoaderAndValidationLayers.git] / genvk.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2013-2016 The Khronos Group Inc.
4 #
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
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 import sys, time, pdb, string, cProfile
18 from reg import *
19 from generator import write, CGeneratorOptions, COutputGenerator, DocGeneratorOptions, DocOutputGenerator, PyOutputGenerator, ValidityOutputGenerator, HostSynchronizationOutputGenerator, ThreadGeneratorOptions, ThreadOutputGenerator
20 from generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
21
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>
30 debug   = False
31 dump    = False
32 profile = False
33 protect = True
34 target  = None
35 timeit  = False
36 validate= False
37 # Default input / log files
38 errFilename = None
39 diagFilename = 'diag.txt'
40 regFilename = 'vk.xml'
41 outDir = '.'
42
43 if __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
70         elif (arg == '-outdir'):
71             outDir = sys.argv[i]
72             i = i+1
73             write('Using output directory ', outDir, file=sys.stderr)
74         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
82 startTime = None
83 def startTimer():
84     global startTime
85     startTime = time.clock()
86 def 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
94 reg = Registry()
95
96 startTimer()
97 tree = etree.parse(regFilename)
98 endTimer('Time to make ElementTree =')
99
100 startTimer()
101 reg.loadElementTree(tree)
102 endTimer('Time to parse ElementTree =')
103
104 if (validate):
105     reg.validateGroups()
106
107 if (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
114 def makeREstring(list):
115     return '^(' + '|'.join(list) + ')$'
116
117 # Descriptive names for various regexp patterns used to select
118 # versions and extensions
119 allVersions     = allExtensions = '.*'
120 noVersions      = noExtensions = None
121
122 # Copyright text prefixing all headers (list of strings).
123 prefixStrings = [
124     '/*',
125     '** Copyright (c) 2015-2016 The Khronos Group Inc.',
126     '**',
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',
130     '**',
131     '**     http://www.apache.org/licenses/LICENSE-2.0',
132     '**',
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.',
138     '*/',
139     ''
140 ]
141
142 # Text specific to Vulkan headers
143 vkPrefixStrings = [
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)
152 protectFile = protect
153 protectFeature = protect
154 protectProto = protect
155
156 buildList = [
157     # Vulkan 1.0 - header for core API + extensions.
158     # To generate just the core API,
159     # change to 'defaultExtensions = None' below.
160     [ COutputGenerator,
161       CGeneratorOptions(
162         filename          = 'include/vulkan/vulkan.h',
163         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     ],
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,
189       DocGeneratorOptions(
190         filename          = 'vulkan-docs',
191         apiname           = 'vulkan',
192         profile           = None,
193         versions          = allVersions,
194         emitversions      = allVersions,
195         defaultExtensions = None,
196         addExtensions     =
197             makeREstring([
198                 'VK_KHR_sampler_mirror_clamp_to_edge',
199             ]),
200         removeExtensions  =
201             makeREstring([
202             ]),
203         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
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     =
221             makeREstring([
222                 'VK_KHR_sampler_mirror_clamp_to_edge',
223             ]),
224         removeExtensions  =
225             makeREstring([
226             ]))
227     ],
228     # Vulkan 1.0 draft - core API validity files for spec
229     # Overwrites validity subdirectories in spec source tree
230     [ ValidityOutputGenerator,
231       DocGeneratorOptions(
232         filename          = 'validity',
233         apiname           = 'vulkan',
234         profile           = None,
235         versions          = allVersions,
236         emitversions      = allVersions,
237         defaultExtensions = None,
238         addExtensions     =
239             makeREstring([
240                 'VK_KHR_sampler_mirror_clamp_to_edge',
241             ]),
242         removeExtensions  =
243             makeREstring([
244             ]),
245         genDirectory      = '../../doc/specs/vulkan')
246     ],
247     # Vulkan 1.0 draft - core API host sync table files for spec
248     # Overwrites subdirectory in spec source tree
249     [ HostSynchronizationOutputGenerator,
250       DocGeneratorOptions(
251         filename          = 'hostsynctable',
252         apiname           = 'vulkan',
253         profile           = None,
254         versions          = allVersions,
255         emitversions      = allVersions,
256         defaultExtensions = None,
257         addExtensions     =
258             makeREstring([
259                 'VK_KHR_sampler_mirror_clamp_to_edge',
260             ]),
261         removeExtensions  =
262             makeREstring([
263             ]),
264         genDirectory      = '../../doc/specs/vulkan')
265     ],
266     # 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',
283         apicall           = 'VKAPI_ATTR ',
284         apientry          = 'VKAPI_CALL ',
285         apientryp         = 'VKAPI_PTR *',
286         alignFuncParam    = 48,
287         genDirectory      = outDir)
288     ],
289     [ ParamCheckerOutputGenerator,
290       ParamCheckerGeneratorOptions(
291         filename          = 'parameter_validation.h',
292         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 *',
308         alignFuncParam    = 48,
309         genDirectory      = outDir)
310     ],
311     None
312 ]
313
314 # create error/warning & diagnostic files
315 if (errFilename):
316     errWarn = open(errFilename,'w')
317 else:
318     errWarn = sys.stderr
319 diag = open(diagFilename, 'w')
320
321 # check that output directory exists
322 if (not os.path.isdir(outDir)):
323     write('Output directory does not exist: ', outDir)
324     raise
325
326 def 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
350 if (debug):
351     pdb.run('genHeaders()')
352 elif (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)
357 else:
358     genHeaders()