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