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 29import khr_util.registry_cache 30from collections import defaultdict 31 32VK_SOURCE = khr_util.registry_cache.RegistrySource( 33 "https://github.com/KhronosGroup/Vulkan-Docs.git", 34 "xml/vk.xml", 35 "cee0f4b12acde766e64d0d038b03458c74bb67f1", 36 "eb31286278b1ecf55ae817198a4238f82ea8fe028aa0631e2c1b09747f10ebb4") 37VK_INL_FILE = os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan", "vkApiExtensionDependencyInfo.inl") 38VK_INL_HEADER = khr_util.format.genInlHeader("Khronos Vulkan API description (vk.xml)", VK_SOURCE.getRevision()) 39 40def VK_MAKE_VERSION(major, minor, patch): 41 return (((major) << 22) | ((minor) << 12) | (patch)) 42 43VK_EXT_NOT_PROMOTED = 0xFFFFFFFF 44VK_EXT_TYPE_INSTANCE = 0 45VK_EXT_TYPE_DEVICE = 1 46VK_EXT_DEP_INSTANCE = 'instanceExtensionDependencies' 47VK_EXT_DEP_DEVICE = 'deviceExtensionDependencies' 48VK_EXT_API_VERSIONS = 'releasedApiVersions' 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 genExtDepInl(dependenciesAndVersions): 79 allExtDepsDict, apiVersions = dependenciesAndVersions 80 apiVersions.reverse() 81 lines = [] 82 83 lines = lines + [line for line in genExtDepArray(VK_EXT_DEP_INSTANCE, allExtDepsDict[VK_EXT_TYPE_INSTANCE])] 84 lines = lines + [line for line in genExtDepArray(VK_EXT_DEP_DEVICE, allExtDepsDict[VK_EXT_TYPE_DEVICE])] 85 lines = lines + [line for line in genApiVersions(VK_EXT_API_VERSIONS, apiVersions)] 86 87 writeInlFile(VK_INL_FILE, lines) 88 89class extInfo: 90 def __init__(self): 91 self.type = VK_EXT_TYPE_INSTANCE 92 self.core = VK_MAKE_VERSION(1, 0, 0) 93 self.promo = VK_EXT_NOT_PROMOTED 94 self.deps = [] 95 96def genExtDepsOnApiVersion(ext, extInfoDict, apiVersion): 97 deps = [] 98 99 for dep in extInfoDict[ext].deps: 100 if apiVersion >= extInfoDict[dep].promo: 101 continue 102 103 deps.append(dep) 104 105 return deps 106 107def genExtDeps(extensionsAndVersions): 108 extInfoDict, apiVersionID = extensionsAndVersions 109 110 allExtDepsDict = defaultdict(list) 111 apiVersions = [] 112 113 for (major,minor) in apiVersionID: 114 apiVersions.append((VK_MAKE_VERSION(major, minor, 0),major,minor)) 115 apiVersions.sort(key=lambda x: x[0]) 116 117 for ext, info in extInfoDict.items(): 118 if info.deps == None: 119 continue 120 121 for (version,major,minor) in apiVersions: 122 if info.core <= version: 123 extDeps = genExtDepsOnApiVersion(ext, extInfoDict, version) 124 if extDeps == None: 125 continue 126 allExtDepsDict[info.type].append( ( major, minor, ext, extDeps ) ) 127 128 for key, value in allExtDepsDict.items(): 129 value.sort(key=lambda x: x[2]) 130 return allExtDepsDict, apiVersions 131 132def getExtInfoDict(vkRegistry): 133 extInfoDict = {} 134 apiVersionID = [] 135 136 for feature in vkRegistry.features: 137 if feature.attrib[VK_XML_EXT_API] != VK_XML_EXT_SUPPORTED_VULKAN: 138 continue 139 featureName = feature.attrib[VK_XML_EXT_NAME].split('_') 140 if len(featureName)!=4 or featureName[0] != 'VK' or featureName[1] != 'VERSION' : 141 continue 142 apiVersionID.append( (int(featureName[2]), int(featureName[3])) ) 143 144 apiVersionsByName = {} 145 apiVersionsByNumber = {} 146 for (major,minor) in apiVersionID: 147 apiVersionsByName['VK_VERSION_{}_{}'.format(major,minor)] = VK_MAKE_VERSION(major, minor, 0); 148 apiVersionsByNumber['{}.{}'.format(major,minor)] = VK_MAKE_VERSION(major, minor, 0); 149 150 for ext in vkRegistry.extensions: 151 if ext.attrib[VK_XML_EXT_SUPPORTED] != VK_XML_EXT_SUPPORTED_VULKAN: 152 continue 153 154 name = ext.attrib[VK_XML_EXT_NAME] 155 extInfoDict[name] = extInfo() 156 if ext.attrib[VK_XML_EXT_TYPE] == VK_XML_EXT_TYPE_DEVICE: 157 extInfoDict[name].type = VK_EXT_TYPE_DEVICE 158 if VK_XML_EXT_REQUIRES_CORE in ext.attrib and ext.attrib[VK_XML_EXT_REQUIRES_CORE] in apiVersionsByNumber: 159 extInfoDict[name].core = apiVersionsByNumber[ext.attrib[VK_XML_EXT_REQUIRES_CORE]] 160 if VK_XML_EXT_PROMO in ext.attrib and ext.attrib[VK_XML_EXT_PROMO] in apiVersionsByName : 161 extInfoDict[name].promo = apiVersionsByName[ext.attrib[VK_XML_EXT_PROMO]] 162 if VK_XML_EXT_DEPS in ext.attrib: 163 extInfoDict[name].deps = ext.attrib[VK_XML_EXT_DEPS].split(',') 164 165 return extInfoDict, apiVersionID 166 167def getVKRegistry(): 168 return khr_util.registry_cache.getRegistry(VK_SOURCE) 169 170if __name__ == '__main__': 171 genExtDepInl(genExtDeps(getExtInfoDict(getVKRegistry()))) 172