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