• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# -*- coding: utf-8 -*-
2
3#-------------------------------------------------------------------------
4# drawElements Quality Program utilities
5# --------------------------------------
6#
7# Copyright 2018 The Android Open Source Project
8#
9# Licensed under the Apache License, Version 2.0 (the "License");
10# you may not use this file except in compliance with the License.
11# You may obtain a copy of the License at
12#
13#      http://www.apache.org/licenses/LICENSE-2.0
14#
15# Unless required by applicable law or agreed to in writing, software
16# distributed under the License is distributed on an "AS IS" BASIS,
17# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18# See the License for the specific language governing permissions and
19# limitations under the License.
20#
21#-------------------------------------------------------------------------
22
23import os
24import sys
25
26sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..", "scripts"))
27
28import khr_util.format
29from khr_util import registry
30from collections import defaultdict
31
32VK_INL_HEADER					= """\
33/* WARNING: This is auto-generated file. Do not modify, since changes will
34 * be lost! Modify the generating script instead.
35 */\
36
37"""
38
39def VK_MAKE_VERSION(major, minor, patch):
40	return (((major) << 22) | ((minor) << 12) | (patch))
41
42VK_EXT_NOT_PROMOTED				= 0xFFFFFFFF
43VK_EXT_TYPE_INSTANCE			= 0
44VK_EXT_TYPE_DEVICE				= 1
45VK_EXT_DEP_INSTANCE				= 'instanceExtensionDependencies'
46VK_EXT_DEP_DEVICE				= 'deviceExtensionDependencies'
47VK_EXT_API_VERSIONS				= 'releasedApiVersions'
48VK_EXT_CORE_VERSIONS			= 'extensionRequiredCoreVersion'
49VK_XML_EXT_DEPS					= 'requires'
50VK_XML_EXT_NAME					= 'name'
51VK_XML_EXT_PROMO				= 'promotedto'
52VK_XML_EXT_REQUIRES_CORE		= 'requiresCore'
53VK_XML_EXT_SUPPORTED			= 'supported'
54VK_XML_EXT_SUPPORTED_VULKAN		= 'vulkan'
55VK_XML_EXT_API					= 'api'
56VK_XML_EXT_TYPE					= 'type'
57VK_XML_EXT_TYPE_DEVICE			= 'device'
58VK_XML_EXT_TYPE_INSTANCE		= 'instance'
59
60def writeInlFile(filename, lines):
61	khr_util.format.writeInlFile(filename, VK_INL_HEADER, lines)
62
63def genExtDepArray(extDepsName, extDepsDict):
64	yield 'static const std::tuple<deUint32, deUint32, const char*, const char*>\t{}[]\t='.format(extDepsName)
65	yield '{'
66	for ( major, minor, ext, extDeps ) in extDepsDict:
67		for dep in extDeps:
68			yield '\tstd::make_tuple({}, {}, "{}", "{}"),'.format(major, minor, ext, dep)
69	yield '};'
70
71def genApiVersions(name, apiVersions):
72	yield 'static const std::tuple<deUint32, deUint32, deUint32>\t{}[]\t='.format(name)
73	yield '{'
74	for ( version, major, minor ) in apiVersions:
75		yield '\tstd::make_tuple({}, {}, {}),'.format(version, major, minor)
76	yield '};'
77
78def genRequiredCoreVersions(name, coreVersionsDict):
79	yield 'static const std::tuple<deUint32, deUint32, const char*>\t{}[]\t ='.format(name)
80	yield '{'
81	extNames = sorted(coreVersionsDict.keys())
82	for extName in extNames:
83		(major, minor) = coreVersionsDict[extName]
84		yield '\tstd::make_tuple({}, {}, "{}"),'.format(major, minor, extName)
85	yield '};'
86
87def genExtDepInl(dependenciesAndVersions, filename):
88	allExtDepsDict, apiVersions, allExtCoreVersions = dependenciesAndVersions
89	apiVersions.reverse()
90	lines = []
91
92	lines.extend(genExtDepArray(VK_EXT_DEP_INSTANCE, allExtDepsDict[VK_EXT_TYPE_INSTANCE]))
93	lines.extend(genExtDepArray(VK_EXT_DEP_DEVICE, allExtDepsDict[VK_EXT_TYPE_DEVICE]))
94	lines.extend(genApiVersions(VK_EXT_API_VERSIONS, apiVersions))
95	lines.extend(genRequiredCoreVersions(VK_EXT_CORE_VERSIONS, allExtCoreVersions))
96
97	writeInlFile(filename, lines)
98
99class extInfo:
100	def __init__(self):
101		self.type			= VK_EXT_TYPE_INSTANCE
102		self.core			= VK_MAKE_VERSION(1, 0, 0)
103		self.coreMajorMinor	= (1, 0)
104		self.promo			= VK_EXT_NOT_PROMOTED
105		self.deps			= []
106
107def genExtDepsOnApiVersion(ext, extInfoDict, apiVersion):
108	deps = []
109
110	for dep in extInfoDict[ext].deps:
111		if apiVersion >= extInfoDict[dep].promo:
112			continue
113
114		deps.append(dep)
115
116	return deps
117
118def genExtDeps(extensionsAndVersions):
119	extInfoDict, apiVersionID = extensionsAndVersions
120
121	allExtDepsDict	= defaultdict(list)
122	apiVersions		= []
123
124	for (major,minor) in apiVersionID:
125		apiVersions.append((VK_MAKE_VERSION(major, minor, 0),major,minor))
126	apiVersions.sort(key=lambda x: x[0])
127
128	for ext, info in extInfoDict.items():
129		if info.deps == None:
130			continue
131
132		for (version,major,minor) in apiVersions:
133			if info.core <= version:
134				extDeps = genExtDepsOnApiVersion(ext, extInfoDict, version)
135				if extDeps == None:
136					continue
137				allExtDepsDict[info.type].append( ( major, minor, ext, extDeps ) )
138
139	for key, value in allExtDepsDict.items():
140		value.sort(key=lambda x: x[2])
141
142	allExtCoreVersions = {}
143	for (ext, info) in extInfoDict.items():
144		allExtCoreVersions[ext] = info.coreMajorMinor
145
146	return allExtDepsDict, apiVersions, allExtCoreVersions
147
148def getExtInfoDict(vkRegistry):
149	extInfoDict = {}
150	apiVersionID = []
151
152	for feature in vkRegistry.features:
153		if feature.attrib[VK_XML_EXT_API] != VK_XML_EXT_SUPPORTED_VULKAN:
154			continue
155		featureName = feature.attrib[VK_XML_EXT_NAME].split('_')
156		if len(featureName)!=4 or featureName[0] != 'VK' or featureName[1] != 'VERSION' :
157			continue
158		apiVersionID.append( (int(featureName[2]), int(featureName[3])) )
159
160	apiVersionsByName		= {}
161	apiVersionsByNumber		= {}
162	apiMajorMinorByNumber	= {}
163	for (major,minor) in apiVersionID:
164		majorDotMinor = '{}.{}'.format(major,minor)
165		apiVersionsByName['VK_VERSION_{}_{}'.format(major,minor)]	= VK_MAKE_VERSION(major, minor, 0);
166		apiVersionsByNumber[majorDotMinor]							= VK_MAKE_VERSION(major, minor, 0);
167		apiMajorMinorByNumber[majorDotMinor]						= (major, minor)
168
169	for ext in vkRegistry.extensions:
170		if ext.attrib[VK_XML_EXT_SUPPORTED] != VK_XML_EXT_SUPPORTED_VULKAN:
171			continue
172
173		name				= ext.attrib[VK_XML_EXT_NAME]
174		extInfoDict[name]	= extInfo()
175		if ext.attrib[VK_XML_EXT_TYPE] == VK_XML_EXT_TYPE_DEVICE:
176			extInfoDict[name].type = VK_EXT_TYPE_DEVICE
177		if VK_XML_EXT_REQUIRES_CORE in ext.attrib and ext.attrib[VK_XML_EXT_REQUIRES_CORE] in apiVersionsByNumber:
178			extInfoDict[name].core = apiVersionsByNumber[ext.attrib[VK_XML_EXT_REQUIRES_CORE]]
179			extInfoDict[name].coreMajorMinor = apiMajorMinorByNumber[ext.attrib[VK_XML_EXT_REQUIRES_CORE]]
180		if VK_XML_EXT_PROMO in ext.attrib and ext.attrib[VK_XML_EXT_PROMO] in apiVersionsByName :
181			extInfoDict[name].promo = apiVersionsByName[ext.attrib[VK_XML_EXT_PROMO]]
182		if VK_XML_EXT_DEPS in ext.attrib:
183			extInfoDict[name].deps = ext.attrib[VK_XML_EXT_DEPS].split(',')
184
185	return extInfoDict, apiVersionID
186
187if __name__ == '__main__':
188
189	currentDir = os.path.dirname(__file__)
190	outputPath = os.path.join(currentDir, "..", "framework", "vulkan")
191	# if argument was specified it is interpreted as a path to which .inl files will be written
192	if len(sys.argv) > 1:
193		outputPath = str(sys.argv[1])
194
195	VULKAN_XML = os.path.join(currentDir, "..", "..", "vulkan-docs", "src", "xml", "vk.xml")
196	vkRegistry = registry.parse(VULKAN_XML)
197
198	genExtDepInl(genExtDeps(getExtInfoDict(vkRegistry)), os.path.join(outputPath, "vkApiExtensionDependencyInfo.inl"))
199