| # -*- coding: utf-8 -*- |
| |
| #------------------------------------------------------------------------- |
| # drawElements Quality Program utilities |
| # -------------------------------------- |
| # |
| # Copyright 2018 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| #------------------------------------------------------------------------- |
| |
| import os |
| import sys |
| |
| sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..", "scripts")) |
| |
| import khr_util.format |
| import khr_util.registry_cache |
| from collections import defaultdict |
| |
| VK_SOURCE = khr_util.registry_cache.RegistrySource( |
| "https://github.com/KhronosGroup/Vulkan-Docs.git", |
| "xml/vk.xml", |
| "22a5a1459fbe8be546079525c4c9d50bfc20b30b", |
| "26b7945a5fd040e3a3adc578d8ff786d09a7cfeeb48ff1e62aeea8b8cb34fb5b") |
| VK_INL_FILE = os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan", "vkApiExtensionDependencyInfo.inl") |
| VK_INL_HEADER = khr_util.format.genInlHeader("Khronos Vulkan API description (vk.xml)", VK_SOURCE.getRevision()) |
| |
| def VK_MAKE_VERSION(major, minor, patch): |
| return (((major) << 22) | ((minor) << 12) | (patch)) |
| |
| VK_EXT_NOT_PROMOTED = 0xFFFFFFFF |
| VK_EXT_TYPE_INSTANCE = 0 |
| VK_EXT_TYPE_DEVICE = 1 |
| VK_EXT_DEP_INSTANCE = 'instanceExtensionDependencies' |
| VK_EXT_DEP_DEVICE = 'deviceExtensionDependencies' |
| VK_EXT_API_VERSIONS = 'releasedApiVersions' |
| VK_XML_EXT_DEPS = 'requires' |
| VK_XML_EXT_NAME = 'name' |
| VK_XML_EXT_PROMO = 'promotedto' |
| VK_XML_EXT_REQUIRES_CORE = 'requiresCore' |
| VK_XML_EXT_SUPPORTED = 'supported' |
| VK_XML_EXT_SUPPORTED_VULKAN = 'vulkan' |
| VK_XML_EXT_API = 'api' |
| VK_XML_EXT_TYPE = 'type' |
| VK_XML_EXT_TYPE_DEVICE = 'device' |
| VK_XML_EXT_TYPE_INSTANCE = 'instance' |
| |
| def writeInlFile(filename, lines): |
| khr_util.format.writeInlFile(filename, VK_INL_HEADER, lines) |
| |
| def genExtDepArray(extDepsName, extDepsDict): |
| yield 'static const std::tuple<deUint32, deUint32, const char*, const char*>\t{}[]\t='.format(extDepsName) |
| yield '{' |
| for ( major, minor, ext, extDeps ) in extDepsDict: |
| for dep in extDeps: |
| yield '\tstd::make_tuple({}, {}, "{}", "{}"),'.format(major, minor, ext, dep) |
| yield '};' |
| |
| def genApiVersions(name, apiVersions): |
| yield 'static const std::tuple<deUint32, deUint32, deUint32>\t{}[]\t='.format(name) |
| yield '{' |
| for ( version, major, minor ) in apiVersions: |
| yield '\tstd::make_tuple({}, {}, {}),'.format(version, major, minor) |
| yield '};' |
| |
| def genExtDepInl(dependenciesAndVersions): |
| allExtDepsDict, apiVersions = dependenciesAndVersions |
| apiVersions.reverse() |
| lines = [] |
| |
| lines = lines + [line for line in genExtDepArray(VK_EXT_DEP_INSTANCE, allExtDepsDict[VK_EXT_TYPE_INSTANCE])] |
| lines = lines + [line for line in genExtDepArray(VK_EXT_DEP_DEVICE, allExtDepsDict[VK_EXT_TYPE_DEVICE])] |
| lines = lines + [line for line in genApiVersions(VK_EXT_API_VERSIONS, apiVersions)] |
| |
| writeInlFile(VK_INL_FILE, lines) |
| |
| class extInfo: |
| def __init__(self): |
| self.type = VK_EXT_TYPE_INSTANCE |
| self.core = VK_MAKE_VERSION(1, 0, 0) |
| self.promo = VK_EXT_NOT_PROMOTED |
| self.deps = [] |
| |
| def genExtDepsOnApiVersion(ext, extInfoDict, apiVersion): |
| deps = [] |
| |
| for dep in extInfoDict[ext].deps: |
| if apiVersion >= extInfoDict[dep].promo: |
| continue |
| |
| deps.append(dep) |
| |
| return deps |
| |
| def genExtDeps(extensionsAndVersions): |
| extInfoDict, apiVersionID = extensionsAndVersions |
| |
| allExtDepsDict = defaultdict(list) |
| apiVersions = [] |
| |
| for (major,minor) in apiVersionID: |
| apiVersions.append((VK_MAKE_VERSION(major, minor, 0),major,minor)) |
| apiVersions.sort(key=lambda x: x[0]) |
| |
| for ext, info in extInfoDict.items(): |
| if info.deps == None: |
| continue |
| |
| for (version,major,minor) in apiVersions: |
| if info.core <= version: |
| extDeps = genExtDepsOnApiVersion(ext, extInfoDict, version) |
| if extDeps == None: |
| continue |
| allExtDepsDict[info.type].append( ( major, minor, ext, extDeps ) ) |
| |
| for key, value in allExtDepsDict.items(): |
| value.sort(key=lambda x: x[2]) |
| return allExtDepsDict, apiVersions |
| |
| def getExtInfoDict(vkRegistry): |
| extInfoDict = {} |
| apiVersionID = [] |
| |
| for feature in vkRegistry.features: |
| if feature.attrib[VK_XML_EXT_API] != VK_XML_EXT_SUPPORTED_VULKAN: |
| continue |
| featureName = feature.attrib[VK_XML_EXT_NAME].split('_') |
| if len(featureName)!=4 or featureName[0] != 'VK' or featureName[1] != 'VERSION' : |
| continue |
| apiVersionID.append( (int(featureName[2]), int(featureName[3])) ) |
| |
| apiVersionsByName = {} |
| apiVersionsByNumber = {} |
| for (major,minor) in apiVersionID: |
| apiVersionsByName['VK_VERSION_{}_{}'.format(major,minor)] = VK_MAKE_VERSION(major, minor, 0); |
| apiVersionsByNumber['{}.{}'.format(major,minor)] = VK_MAKE_VERSION(major, minor, 0); |
| |
| for ext in vkRegistry.extensions: |
| if ext.attrib[VK_XML_EXT_SUPPORTED] != VK_XML_EXT_SUPPORTED_VULKAN: |
| continue |
| |
| name = ext.attrib[VK_XML_EXT_NAME] |
| extInfoDict[name] = extInfo() |
| if ext.attrib[VK_XML_EXT_TYPE] == VK_XML_EXT_TYPE_DEVICE: |
| extInfoDict[name].type = VK_EXT_TYPE_DEVICE |
| if VK_XML_EXT_REQUIRES_CORE in ext.attrib and ext.attrib[VK_XML_EXT_REQUIRES_CORE] in apiVersionsByNumber: |
| extInfoDict[name].core = apiVersionsByNumber[ext.attrib[VK_XML_EXT_REQUIRES_CORE]] |
| if VK_XML_EXT_PROMO in ext.attrib and ext.attrib[VK_XML_EXT_PROMO] in apiVersionsByName : |
| extInfoDict[name].promo = apiVersionsByName[ext.attrib[VK_XML_EXT_PROMO]] |
| if VK_XML_EXT_DEPS in ext.attrib: |
| extInfoDict[name].deps = ext.attrib[VK_XML_EXT_DEPS].split(',') |
| |
| return extInfoDict, apiVersionID |
| |
| def getVKRegistry(): |
| return khr_util.registry_cache.getRegistry(VK_SOURCE) |
| |
| if __name__ == '__main__': |
| genExtDepInl(genExtDeps(getExtInfoDict(getVKRegistry()))) |