• 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_FILE						= os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan", "vkApiExtensionDependencyInfo.inl")
33VK_INL_HEADER					= """\
34/* WARNING: This is auto-generated file. Do not modify, since changes will
35 * be lost! Modify the generating script instead.
36 */\
37
38"""
39
40
41def VK_MAKE_VERSION(major, minor, patch):
42	return (((major) << 22) | ((minor) << 12) | (patch))
43
44VK_EXT_NOT_PROMOTED				= 0xFFFFFFFF
45VK_EXT_TYPE_INSTANCE			= 0
46VK_EXT_TYPE_DEVICE				= 1
47VK_EXT_DEP_INSTANCE				= 'instanceExtensionDependencies'
48VK_EXT_DEP_DEVICE				= 'deviceExtensionDependencies'
49VK_EXT_API_VERSIONS				= 'releasedApiVersions'
50VK_EXT_CORE_VERSIONS			= 'extensionRequiredCoreVersion'
51VK_XML_EXT_DEPS					= 'requires'
52VK_XML_EXT_NAME					= 'name'
53VK_XML_EXT_PROMO				= 'promotedto'
54VK_XML_EXT_REQUIRES_CORE		= 'requiresCore'
55VK_XML_EXT_SUPPORTED			= 'supported'
56VK_XML_EXT_SUPPORTED_VULKAN		= 'vulkan'
57VK_XML_EXT_API					= 'api'
58VK_XML_EXT_TYPE					= 'type'
59VK_XML_EXT_TYPE_DEVICE			= 'device'
60VK_XML_EXT_TYPE_INSTANCE		= 'instance'
61
62def writeInlFile(filename, lines):
63	khr_util.format.writeInlFile(filename, VK_INL_HEADER, lines)
64
65def genExtDepArray(extDepsName, extDepsDict):
66	yield 'static const std::tuple<deUint32, deUint32, const char*, const char*>\t{}[]\t='.format(extDepsName)
67	yield '{'
68	for ( major, minor, ext, extDeps ) in extDepsDict:
69		for dep in extDeps:
70			yield '\tstd::make_tuple({}, {}, "{}", "{}"),'.format(major, minor, ext, dep)
71	yield '};'
72
73def genApiVersions(name, apiVersions):
74	yield 'static const std::tuple<deUint32, deUint32, deUint32>\t{}[]\t='.format(name)
75	yield '{'
76	for ( version, major, minor ) in apiVersions:
77		yield '\tstd::make_tuple({}, {}, {}),'.format(version, major, minor)
78	yield '};'
79
80def genRequiredCoreVersions(name, coreVersionsDict):
81	yield 'static const std::tuple<deUint32, deUint32, const char*>\t{}[]\t ='.format(name)
82	yield '{'
83	extNames = sorted(coreVersionsDict.keys())
84	for extName in extNames:
85		(major, minor) = coreVersionsDict[extName]
86		yield '\tstd::make_tuple({}, {}, "{}"),'.format(major, minor, extName)
87	yield '};'
88
89def genExtDepInl(dependenciesAndVersions, filename):
90	allExtDepsDict, apiVersions, allExtCoreVersions = dependenciesAndVersions
91	apiVersions.reverse()
92	lines = []
93
94	lines.extend(genExtDepArray(VK_EXT_DEP_INSTANCE, allExtDepsDict[VK_EXT_TYPE_INSTANCE]))
95	lines.extend(genExtDepArray(VK_EXT_DEP_DEVICE, allExtDepsDict[VK_EXT_TYPE_DEVICE]))
96	lines.extend(genApiVersions(VK_EXT_API_VERSIONS, apiVersions))
97	lines.extend(genRequiredCoreVersions(VK_EXT_CORE_VERSIONS, allExtCoreVersions))
98
99	writeInlFile(filename, lines)
100
101class extInfo:
102	def __init__(self):
103		self.type			= VK_EXT_TYPE_INSTANCE
104		self.core			= VK_MAKE_VERSION(1, 0, 0)
105		self.coreMajorMinor	= (1, 0)
106		self.promo			= VK_EXT_NOT_PROMOTED
107		self.deps			= []
108
109def genExtDepsOnApiVersion(ext, extInfoDict, apiVersion):
110	deps = []
111
112	for dep in extInfoDict[ext].deps:
113		if apiVersion >= extInfoDict[dep].promo:
114			continue
115
116		deps.append(dep)
117
118	return deps
119
120def genExtDeps(extensionsAndVersions):
121	extInfoDict, apiVersionID = extensionsAndVersions
122
123	allExtDepsDict	= defaultdict(list)
124	apiVersions		= []
125
126	for (major,minor) in apiVersionID:
127		apiVersions.append((VK_MAKE_VERSION(major, minor, 0),major,minor))
128	apiVersions.sort(key=lambda x: x[0])
129
130	for ext, info in extInfoDict.items():
131		if info.deps == None:
132			continue
133
134		for (version,major,minor) in apiVersions:
135			if info.core <= version:
136				extDeps = genExtDepsOnApiVersion(ext, extInfoDict, version)
137				if extDeps == None:
138					continue
139				allExtDepsDict[info.type].append( ( major, minor, ext, extDeps ) )
140
141	for key, value in allExtDepsDict.items():
142		value.sort(key=lambda x: x[2])
143
144	allExtCoreVersions = {}
145	for (ext, info) in extInfoDict.items():
146		allExtCoreVersions[ext] = info.coreMajorMinor
147
148	return allExtDepsDict, apiVersions, allExtCoreVersions
149
150def getExtInfoDict(vkRegistry):
151	extInfoDict = {}
152	apiVersionID = []
153
154	for feature in vkRegistry.features:
155		if feature.attrib[VK_XML_EXT_API] != VK_XML_EXT_SUPPORTED_VULKAN:
156			continue
157		featureName = feature.attrib[VK_XML_EXT_NAME].split('_')
158		if len(featureName)!=4 or featureName[0] != 'VK' or featureName[1] != 'VERSION' :
159			continue
160		apiVersionID.append( (int(featureName[2]), int(featureName[3])) )
161
162	apiVersionsByName		= {}
163	apiVersionsByNumber		= {}
164	apiMajorMinorByNumber	= {}
165	for (major,minor) in apiVersionID:
166		majorDotMinor = '{}.{}'.format(major,minor)
167		apiVersionsByName['VK_VERSION_{}_{}'.format(major,minor)]	= VK_MAKE_VERSION(major, minor, 0);
168		apiVersionsByNumber[majorDotMinor]							= VK_MAKE_VERSION(major, minor, 0);
169		apiMajorMinorByNumber[majorDotMinor]						= (major, minor)
170
171	for ext in vkRegistry.extensions:
172		if ext.attrib[VK_XML_EXT_SUPPORTED] != VK_XML_EXT_SUPPORTED_VULKAN:
173			continue
174
175		name				= ext.attrib[VK_XML_EXT_NAME]
176		extInfoDict[name]	= extInfo()
177		if ext.attrib[VK_XML_EXT_TYPE] == VK_XML_EXT_TYPE_DEVICE:
178			extInfoDict[name].type = VK_EXT_TYPE_DEVICE
179		if VK_XML_EXT_REQUIRES_CORE in ext.attrib and ext.attrib[VK_XML_EXT_REQUIRES_CORE] in apiVersionsByNumber:
180			extInfoDict[name].core = apiVersionsByNumber[ext.attrib[VK_XML_EXT_REQUIRES_CORE]]
181			extInfoDict[name].coreMajorMinor = apiMajorMinorByNumber[ext.attrib[VK_XML_EXT_REQUIRES_CORE]]
182		if VK_XML_EXT_PROMO in ext.attrib and ext.attrib[VK_XML_EXT_PROMO] in apiVersionsByName :
183			extInfoDict[name].promo = apiVersionsByName[ext.attrib[VK_XML_EXT_PROMO]]
184		if VK_XML_EXT_DEPS in ext.attrib:
185			extInfoDict[name].deps = ext.attrib[VK_XML_EXT_DEPS].split(',')
186
187	return extInfoDict, apiVersionID
188
189if __name__ == '__main__':
190
191	# script requires output path to which .inl files will be written
192	if len(sys.argv) == 1:
193		sys.exit("Error - output path wasn't specified in argument")
194	outputPath = str(sys.argv[1])
195
196	VULKAN_XML = os.path.join(os.path.dirname(__file__), "..", "..", "vulkan-docs", "src", "xml", "vk.xml")
197	vkRegistry = registry.parse(VULKAN_XML)
198
199	genExtDepInl(genExtDeps(getExtInfoDict(vkRegistry)), os.path.join(outputPath, "vkApiExtensionDependencyInfo.inl"))
200