1# -*- coding: utf-8 -*- 2 3#------------------------------------------------------------------------- 4# Vulkan CTS 5# ---------- 6# 7# Copyright (c) 2015 Google Inc. 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 re 25import sys 26import copy 27from itertools import chain 28from collections import OrderedDict 29 30sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..", "scripts")) 31 32from build.common import DEQP_DIR 33from khr_util.format import indentLines, writeInlFile 34 35VULKAN_H_DIR = os.path.join(os.path.dirname(__file__), "src") 36VULKAN_DIR = os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan") 37 38INL_HEADER = """\ 39/* WARNING: This is auto-generated file. Do not modify, since changes will 40 * be lost! Modify the generating script instead. 41 */\ 42""" 43 44DEFINITIONS = [ 45 ("VK_MAX_PHYSICAL_DEVICE_NAME_SIZE", "size_t"), 46 ("VK_MAX_EXTENSION_NAME_SIZE", "size_t"), 47 ("VK_MAX_DRIVER_NAME_SIZE", "size_t"), 48 ("VK_MAX_DRIVER_INFO_SIZE", "size_t"), 49 ("VK_UUID_SIZE", "size_t"), 50 ("VK_LUID_SIZE", "size_t"), 51 ("VK_MAX_MEMORY_TYPES", "size_t"), 52 ("VK_MAX_MEMORY_HEAPS", "size_t"), 53 ("VK_MAX_DESCRIPTION_SIZE", "size_t"), 54 ("VK_MAX_DEVICE_GROUP_SIZE", "size_t"), 55 ("VK_ATTACHMENT_UNUSED", "deUint32"), 56 ("VK_SUBPASS_EXTERNAL", "deUint32"), 57 ("VK_QUEUE_FAMILY_IGNORED", "deUint32"), 58 ("VK_QUEUE_FAMILY_EXTERNAL", "deUint32"), 59 ("VK_REMAINING_MIP_LEVELS", "deUint32"), 60 ("VK_REMAINING_ARRAY_LAYERS", "deUint32"), 61 ("VK_WHOLE_SIZE", "vk::VkDeviceSize"), 62 ("VK_TRUE", "vk::VkBool32"), 63 ("VK_FALSE", "vk::VkBool32"), 64] 65 66PLATFORM_TYPES = [ 67 # VK_KHR_xlib_surface 68 (["Display","*"], ["XlibDisplayPtr"], "void*"), 69 (["Window"], ["XlibWindow"], "deUintptr",), 70 (["VisualID"], ["XlibVisualID"], "deUint32"), 71 72 # VK_KHR_xcb_surface 73 (["xcb_connection_t", "*"], ["XcbConnectionPtr"], "void*"), 74 (["xcb_window_t"], ["XcbWindow"], "deUintptr"), 75 (["xcb_visualid_t"], ["XcbVisualid"], "deUint32"), 76 77 # VK_KHR_wayland_surface 78 (["struct", "wl_display","*"], ["WaylandDisplayPtr"], "void*"), 79 (["struct", "wl_surface", "*"], ["WaylandSurfacePtr"], "void*"), 80 81 # VK_KHR_mir_surface 82 (["MirConnection", "*"], ["MirConnectionPtr"], "void*"), 83 (["MirSurface", "*"], ["MirSurfacePtr"], "void*"), 84 85 # VK_KHR_android_surface 86 (["ANativeWindow", "*"], ["AndroidNativeWindowPtr"], "void*"), 87 88 # VK_KHR_win32_surface 89 (["HINSTANCE"], ["Win32InstanceHandle"], "void*"), 90 (["HWND"], ["Win32WindowHandle"], "void*"), 91 (["HANDLE"], ["Win32Handle"], "void*"), 92 (["const", "SECURITY_ATTRIBUTES", "*"], ["Win32SecurityAttributesPtr"], "const void*"), 93 (["AHardwareBuffer", "*"], ["AndroidHardwareBufferPtr"], "void*"), 94 (["HMONITOR"], ["Win32MonitorHandle"], "void*"), 95 (["LPCWSTR"], ["Win32LPCWSTR"], "const void*"), 96 97 # VK_EXT_acquire_xlib_display 98 (["RROutput"], ["RROutput"], "void*"), 99 100 (["zx_handle_t"], ["zx_handle_t"], "deInt32"), 101 (["GgpFrameToken"], ["GgpFrameToken"], "deInt32"), 102 (["GgpStreamDescriptor"], ["GgpStreamDescriptor"], "deInt32"), 103 (["CAMetalLayer"], ["CAMetalLayer"], "void*"), 104] 105 106PLATFORM_TYPE_NAMESPACE = "pt" 107 108TYPE_SUBSTITUTIONS = [ 109 ("uint8_t", "deUint8"), 110 ("uint16_t", "deUint16"), 111 ("uint32_t", "deUint32"), 112 ("uint64_t", "deUint64"), 113 ("int8_t", "deInt8"), 114 ("int16_t", "deInt16"), 115 ("int32_t", "deInt32"), 116 ("int64_t", "deInt64"), 117 ("bool32_t", "deUint32"), 118 ("size_t", "deUintptr"), 119 120 # Platform-specific 121 ("DWORD", "deUint32"), 122 ("HANDLE*", PLATFORM_TYPE_NAMESPACE + "::" + "Win32Handle*"), 123] 124 125EXTENSION_POSTFIXES = ["KHR", "EXT", "NV", "NVX", "KHX", "NN", "MVK", "FUCHSIA", "GGP", "AMD"] 126EXTENSION_POSTFIXES_STANDARD = ["KHR", "EXT"] 127 128def prefixName (prefix, name): 129 name = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', name[2:]) 130 name = re.sub(r'([a-zA-Z])([0-9])', r'\1_\2', name) 131 name = name.upper() 132 133 name = name.replace("YCB_CR_", "YCBCR_") 134 name = name.replace("WIN_32_", "WIN32_") 135 name = name.replace("8_BIT_", "8BIT_") 136 name = name.replace("16_BIT_", "16BIT_") 137 name = name.replace("INT_64_", "INT64_") 138 name = name.replace("D_3_D_12_", "D3D12_") 139 name = name.replace("IOSSURFACE_", "IOS_SURFACE_") 140 name = name.replace("MAC_OS", "MACOS_") 141 name = name.replace("TEXTURE_LOD", "TEXTURE_LOD_") 142 name = name.replace("VIEWPORT_W", "VIEWPORT_W_") 143 name = name.replace("_IDPROPERTIES", "_ID_PROPERTIES") 144 name = name.replace("PHYSICAL_DEVICE_SHADER_FLOAT_16_INT_8_FEATURES", "PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES") 145 name = name.replace("_PCIBUS_", "_PCI_BUS_") 146 name = name.replace("ASTCD", "ASTC_D") 147 name = name.replace("AABBNV", "AABB_NV") 148 name = name.replace("IMAGE_PIPE", "IMAGEPIPE") 149 name = name.replace("SMBUILTINS", "SM_BUILTINS") 150 name = name.replace("ASTCHDRFEATURES", "ASTC_HDR_FEATURES") 151 name = name.replace("UINT_8", "UINT8") 152 name = name.replace("VULKAN_11_FEATURES", "VULKAN_1_1_FEATURES") 153 name = name.replace("VULKAN_11_PROPERTIES", "VULKAN_1_1_PROPERTIES") 154 name = name.replace("VULKAN_12_FEATURES", "VULKAN_1_2_FEATURES") 155 name = name.replace("VULKAN_12_PROPERTIES", "VULKAN_1_2_PROPERTIES") 156 name = name.replace("INT_8_", "INT8_") 157 name = name.replace("AABBNV", "AABB_NV") 158 name = name.replace("_H_264_", "_H264_") 159 name = name.replace("_H_265_", "_H265_") 160 161 return prefix + name 162 163class Version: 164 def __init__ (self, versionTuple): 165 self.major = versionTuple[0] 166 self.minor = versionTuple[1] 167 self.patch = versionTuple[2] 168 169 def getInHex (self): 170 if self.patch == 0: 171 return "VK_API_VERSION_%d_%d" % (self.major, self.minor) 172 return '0x%Xu' % (hash(self)) 173 174 def isStandardVersion (self): 175 if self.patch != 0: 176 return False 177 if self.major != 1: 178 return False 179 return True 180 181 def getBestRepresentation (self): 182 if self.isStandardVersion(): 183 return self.getInHex() 184 return self.getDefineName() 185 186 def getDefineName (self): 187 return 'VERSION_%d_%d_%d' % (self.major, self.minor, self.patch) 188 189 def __hash__ (self): 190 return (self.major << 22) | (self.minor << 12) | self.patch 191 192 def __eq__ (self, other): 193 return self.major == other.major and self.minor == other.minor and self.patch == other.patch 194 195 def __str__ (self): 196 return self.getBestRepresentation() 197 198 199class Handle: 200 TYPE_DISP = 0 201 TYPE_NONDISP = 1 202 203 def __init__ (self, type, name): 204 self.type = type 205 self.name = name 206 self.alias = None 207 self.isAlias = False 208 209 def getHandleType (self): 210 return prefixName("HANDLE_TYPE_", self.name) 211 212 def checkAliasValidity (self): 213 pass 214 215 def __repr__ (self): 216 return '%s (%s, %s)' % (self.name, self.alias, self.isAlias) 217 218class Definition: 219 def __init__ (self, type, name, value): 220 self.type = type 221 self.name = name 222 self.value = value 223 self.alias = None 224 self.isAlias = False 225 226 def __repr__ (self): 227 return '%s = %s (%s)' % (self.name, self.value, self.type) 228 229class Enum: 230 def __init__ (self, name, values): 231 self.name = name 232 self.values = values 233 self.alias = None 234 self.isAlias = False 235 236 def checkAliasValidity (self): 237 if self.alias != None: 238 if len(self.values) != len(self.alias.values): 239 raise Exception("%s has different number of flags than its alias %s." % (self.name, self.alias.name)) 240 for index, value in enumerate(self.values): 241 aliasVal = self.alias.values[index] 242 if value[1] != aliasVal[1] or not (value[0].startswith(aliasVal[0]) or aliasVal[0].startswith(value[0])): 243 raise Exception("Flag %s of %s has different value than %s of %s." % (self.alias.values[index], self.alias.name, value, self.name)) 244 245 def __repr__ (self): 246 return '%s (%s) %s' % (self.name, self.alias, self.values) 247 248class Bitfield: 249 def __init__ (self, name, values): 250 self.name = name 251 self.values = values 252 self.alias = None 253 self.isAlias = False 254 255 def checkAliasValidity (self): 256 if self.alias != None: 257 if len(self.values) != len(self.alias.values): 258 raise Exception("%s has different number of flags than its alias %s." % (self.name, self.alias.name)) 259 for index, value in enumerate(self.values): 260 aliasVal = self.alias.values[index] 261 if value[1] != aliasVal[1] or not (value[0].startswith(aliasVal[0]) or aliasVal[0].startswith(value[0])): 262 raise Exception("Flag %s of %s has different value than %s of %s." % (self.alias.values[index], self.alias.name, value, self.name)) 263 264 def __repr__ (self): 265 return '%s (%s)' % (self.name, self.alias) 266 267class Variable: 268 def __init__ (self, type, name, arraySizeOrFieldWidth): 269 type = type.replace('*',' *').replace('&',' &') 270 for src, dst in TYPE_SUBSTITUTIONS: 271 type = type.replace(src, dst) 272 self.type = type.split(' ') 273 for platformType, substitute, compat in PLATFORM_TYPES: 274 range = self.contains(self.type, platformType) 275 if range != None: 276 self.type = self.type[:range[0]]+[PLATFORM_TYPE_NAMESPACE + '::' + substitute[0]] + substitute[1:] + self.type[range[1]:] 277 break 278 self.name = name 279 if len(arraySizeOrFieldWidth) > 0 and arraySizeOrFieldWidth[0] == ':': 280 self.arraySize = '' 281 self.fieldWidth = arraySizeOrFieldWidth 282 else: 283 self.arraySize = arraySizeOrFieldWidth 284 self.fieldWidth = '' 285 286 def contains(self, big, small): 287 for i in range(len(big)-len(small)+1): 288 for j in range(len(small)): 289 if big[i+j] != small[j]: 290 break 291 else: 292 return i, i+len(small) 293 return None 294 295 def getType (self): 296 return ' '.join(self.type).replace(' *','*').replace(' &','&') 297 298 def getAsString (self, separator): 299 return '%s%s%s%s%s' % (self.getType(), separator, self.name, self.arraySize, self.fieldWidth) 300 301 def getAsStringForArgumentList (self, separator): 302 return '%s%s%s%s' % (self.getType(), separator, self.name, self.arraySize) 303 304 def __repr__ (self): 305 return '<%s> <%s> <%s>' % (self.type, self.name, self.arraySize) 306 307 def __eq__ (self, other): 308 if len(self.type) != len(other.type): 309 return False 310 for index, type in enumerate(self.type): 311 if "*" == type or "&" == type or "const" == type or "volatile" == type: 312 if type != other.type[index]: 313 return False 314 elif type != other.type[index] and \ 315 type not in map(lambda ext: other.type[index] + ext, EXTENSION_POSTFIXES_STANDARD) and \ 316 other.type[index] not in map(lambda ext: type + ext, EXTENSION_POSTFIXES_STANDARD): 317 return False 318 return self.arraySize == other.arraySize 319 320 def __ne__ (self, other): 321 return not self == other 322 323class CompositeType: 324 CLASS_STRUCT = 0 325 CLASS_UNION = 1 326 327 def __init__ (self, typeClass, name, members, apiVersion = None): 328 self.typeClass = typeClass 329 self.name = name 330 self.members = members 331 self.alias = None 332 self.isAlias = False 333 self.apiVersion = apiVersion 334 335 def getClassName (self): 336 names = {CompositeType.CLASS_STRUCT: 'struct', CompositeType.CLASS_UNION: 'union'} 337 return names[self.typeClass] 338 339 def checkAliasValidity (self): 340 if self.alias != None: 341 if len(self.members) != len(self.alias.members): 342 raise Exception("%s has different number of members than its alias %s." % (self.name, self.alias.name)) 343 for index, member in enumerate(self.members ): 344 break 345 #if member != self.alias.members[index]: 346 #raise Exception("Member %s of %s is different than core member %s in %s." % (self.alias.members[index], self.alias.name, member, self.name)) 347 #raise Exception("Member ",str(self.alias.members[index])," of ", str(self.alias.name)," is different than core member ", str(member)," in ", str(self.name),".") 348 def __repr__ (self): 349 return '%s (%s)' % (self.name, self.alias) 350 351class Function: 352 TYPE_PLATFORM = 0 # Not bound to anything 353 TYPE_INSTANCE = 1 # Bound to VkInstance 354 TYPE_DEVICE = 2 # Bound to VkDevice 355 356 def __init__ (self, name, returnType, arguments, apiVersion = None): 357 self.name = name 358 self.returnType = returnType 359 self.arguments = arguments 360 self.alias = None 361 self.isAlias = False 362 self.apiVersion = apiVersion 363 364 def getType (self): 365 # Special functions 366 if self.name == "vkGetInstanceProcAddr": 367 return Function.TYPE_PLATFORM 368 assert len(self.arguments) > 0 369 firstArgType = self.arguments[0].getType() 370 if firstArgType in ["VkInstance", "VkPhysicalDevice"]: 371 return Function.TYPE_INSTANCE 372 elif firstArgType in ["VkDevice", "VkCommandBuffer", "VkQueue"]: 373 return Function.TYPE_DEVICE 374 else: 375 return Function.TYPE_PLATFORM 376 377 def checkAliasValidity (self): 378 if self.alias != None: 379 if len(self.arguments) != len(self.alias.arguments): 380 raise Exception("%s has different number of arguments than its alias %s." % (self.name, self.alias.name)) 381 if self.returnType != self.alias.returnType or not (self.returnType.startswith(self.alias.returnType) or self.alias.returnType.startswith(self.returnType)): 382 raise Exception("%s has different return value's type than its alias %s." % (self.name, self.alias.name)) 383 for index, argument in enumerate(self.arguments): 384 if argument != self.alias.arguments[index]: 385 raise Exception("argument %s: \"%s\" of %s is different than \"%s\" of %s." % (index, self.alias.arguments[index].getAsString(' '), self.alias.name, argument.getAsString(' '), self.name)) 386 387 def __repr__ (self): 388 return '%s (%s)' % (self.name, self.alias) 389 390class Extension: 391 def __init__ (self, name, handles, enums, bitfields, compositeTypes, functions, definitions, additionalDefinitions, typedefs, versionInCore): 392 self.name = name 393 self.definitions = definitions 394 self.additionalDefs = additionalDefinitions 395 self.handles = handles 396 self.enums = enums 397 self.bitfields = bitfields 398 self.compositeTypes = compositeTypes 399 self.functions = functions 400 self.typedefs = typedefs 401 self.versionInCore = versionInCore 402 403 def __repr__ (self): 404 return 'EXT:\n%s ->\nENUMS:\n%s\nCOMPOS:\n%s\nFUNCS:\n%s\nBITF:\n%s\nHAND:\n%s\nDEFS:\n%s\n' % (self.name, self.enums, self.compositeTypes, self.functions, self.bitfields, self.handles, self.definitions, self.versionInCore) 405 406class API: 407 def __init__ (self, versions, definitions, handles, enums, bitfields, bitfields64, compositeTypes, functions, extensions): 408 self.versions = versions 409 self.definitions = definitions 410 self.handles = handles 411 self.enums = enums 412 self.bitfields = bitfields 413 self.bitfields64 = bitfields64 414 self.compositeTypes = compositeTypes 415 self.functions = functions # \note contains extension functions as well 416 self.extensions = extensions 417 418def readFile (filename): 419 with open(filename, 'rt') as f: 420 return f.read() 421 422IDENT_PTRN = r'[a-zA-Z_][a-zA-Z0-9_]*' 423WIDTH_PTRN = r'[:0-9]*' 424TYPE_PTRN = r'[a-zA-Z_][a-zA-Z0-9_ \t*&]*' 425 426def getInterfaceName (function): 427 assert function.name[:2] == "vk" 428 return function.name[2].lower() + function.name[3:] 429 430def getFunctionTypeName (function): 431 assert function.name[:2] == "vk" 432 return function.name[2:] + "Func" 433 434def endsWith (str, postfix): 435 return str[-len(postfix):] == postfix 436 437def splitNameExtPostfix (name): 438 knownExtPostfixes = EXTENSION_POSTFIXES 439 for postfix in knownExtPostfixes: 440 if endsWith(name, postfix): 441 return (name[:-len(postfix)], postfix) 442 return (name, "") 443 444def getBitEnumNameForBitfield (bitfieldName): 445 bitfieldName, postfix = splitNameExtPostfix(bitfieldName) 446 assert bitfieldName[-1] == "s" 447 return bitfieldName[:-1] + "Bits" + postfix 448 449def getBitfieldNameForBitEnum (bitEnumName): 450 bitEnumName, postfix = splitNameExtPostfix(bitEnumName) 451 assert bitEnumName[-4:] == "Bits" 452 return bitEnumName[:-4] + "s" + postfix 453 454def parsePreprocDefinedValue (src, name): 455 value = parsePreprocDefinedValueOptional(src, name) 456 if value is None: 457 raise Exception("No such definition: %s" % name) 458 return value 459 460def parsePreprocDefinedValueOptional (src, name): 461 definition = re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src) 462 if definition is None: 463 return None 464 value = definition.group(1).strip() 465 if value == "UINT32_MAX": 466 value = "(~0u)" 467 return value 468 469def parseEnum (name, src): 470 keyValuePtrn = '(' + IDENT_PTRN + r')\s*=\s*([^\s,\n}]+)\s*[,\n}]' 471 return Enum(name, re.findall(keyValuePtrn, src)) 472 473# \note Parses raw enums, some are mapped to bitfields later 474def parseEnums (src): 475 matches = re.findall(r'typedef enum(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src) 476 enums = [] 477 for enumname, contents, typename in matches: 478 enums.append(parseEnum(typename, contents)) 479 return enums 480 481def parseCompositeType (type, name, src): 482 typeNamePtrn = r'(' + TYPE_PTRN + r')(\s+' + IDENT_PTRN + r')((\[[^\]]+\]|\s*:\s*[0-9]+)*)\s*;' 483 matches = re.findall(typeNamePtrn, src) 484 members = [Variable(t.strip(), n.strip(), a.replace(' ', '')) for t, n, a, _ in matches] 485 return CompositeType(type, name, members) 486 487def parseCompositeTypes (src): 488 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION } 489 matches = re.findall(r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src) 490 types = [] 491 for type, structname, contents, typename in matches: 492 types.append(parseCompositeType(typeMap[type], typename, contents)) 493 return types 494 495def parseCompositeTypesByVersion (src, versionsData): 496 497 # find occurence of extension is a place where 498 # we cant assign apiVersion to found structures 499 extPtrn = r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"' 500 versionEnd = re.search(extPtrn, src) 501 versions = [Version((v[2], v[3], 0)) for v in versionsData] 502 versions.append(None) 503 504 # construct list of locations where version definitions start, and add the end of the file to it 505 sectionLocations = [versionDef[1] for versionDef in versionsData] 506 sectionLocations.append(versionEnd.start()) 507 sectionLocations.append(len(src)) 508 509 # construct function declaration pattern 510 ptrn = r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;' 511 regPtrn = re.compile(ptrn) 512 types = [] 513 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION } 514 515 # iterate over all versions and find all structure definitions 516 for index, v in enumerate(versions): 517 matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1]) 518 for type, structname, contents, typename in matches: 519 compositeType = parseCompositeType(typeMap[type], typename, contents) 520 compositeType.apiVersion = v 521 types.append(compositeType) 522 return types 523 524def parseVersions (src): 525 # returns list of tuples each with four items: 526 # 1. string with version token (without ' 1' at the end) 527 # 2. starting point off version specific definitions in vulkan.h.in 528 # 3. major version number 529 # 4. minor version number 530 return [(m.group()[:-2], m.start(), int(m.group(1)), int(m.group(2))) for m in re.finditer('VK_VERSION_([1-9])_([0-9]) 1', src)] 531 532def parseHandles (src): 533 matches = re.findall(r'VK_DEFINE(_NON_DISPATCHABLE|)_HANDLE\((' + IDENT_PTRN + r')\)[ \t]*[\n\r]', src) 534 handles = [] 535 typeMap = {'': Handle.TYPE_DISP, '_NON_DISPATCHABLE': Handle.TYPE_NONDISP} 536 for type, name in matches: 537 handle = Handle(typeMap[type], name) 538 handles.append(handle) 539 return handles 540 541def parseArgList (src): 542 typeNamePtrn = r'(' + TYPE_PTRN + r')(\s+' + IDENT_PTRN + r')((\[[^\]]+\])*)\s*' 543 args = [] 544 for rawArg in src.split(','): 545 m = re.search(typeNamePtrn, rawArg) 546 args.append(Variable(m.group(1).strip(), m.group(2).strip(), m.group(3))) 547 return args 548 549def removeTypeExtPostfix (name): 550 for extPostfix in EXTENSION_POSTFIXES_STANDARD: 551 if endsWith(name, extPostfix): 552 return name[0:-len(extPostfix)] 553 return None 554 555def populateExtensionAliases(allObjects, extensionObjects): 556 for object in extensionObjects: 557 withoutPostfix = removeTypeExtPostfix(object.name) 558 if withoutPostfix != None and withoutPostfix in allObjects: 559 # max 1 alias is assumed by functions in this file 560 assert allObjects[withoutPostfix].alias == None 561 allObjects[withoutPostfix].alias = object 562 object.isAlias = True 563 for object in extensionObjects: 564 object.checkAliasValidity() 565 566def populateAliasesWithTypedefs (objects, src): 567 objectsByName = {} 568 for object in objects: 569 objectsByName[object.name] = object 570 ptrn = r'\s*typedef\s+' + object.name + r'\s+([^;]+)' 571 stash = re.findall(ptrn, src) 572 if len(stash) == 1: 573 objExt = copy.deepcopy(object) 574 objExt.name = stash[0] 575 object.alias = objExt 576 objExt.isAlias = True 577 objects.append(objExt) 578 579def removeAliasedValues (enum): 580 valueByName = {} 581 for name, value in enum.values: 582 valueByName[name] = value 583 584 def removeDefExtPostfix (name): 585 for extPostfix in EXTENSION_POSTFIXES: 586 if endsWith(name, "_" + extPostfix): 587 return name[0:-(len(extPostfix)+1)] 588 return None 589 590 newValues = [] 591 for name, value in enum.values: 592 withoutPostfix = removeDefExtPostfix(name) 593 if withoutPostfix != None and withoutPostfix in valueByName and valueByName[withoutPostfix] == value: 594 continue 595 newValues.append((name, value)) 596 enum.values = newValues 597 598def parseFunctions (src): 599 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;' 600 matches = re.findall(ptrn, src) 601 functions = [] 602 for returnType, name, argList in matches: 603 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList))) 604 return functions 605 606def parseFunctionsByVersion (src, versions): 607 # construct list of locations where version definitions start, and add the end of the file to it 608 sectionLocations = [versionDef[1] for versionDef in versions] 609 sectionLocations.append(len(src)) 610 611 # construct function declaration pattern 612 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;' 613 regPtrn = re.compile(ptrn) 614 functions = [] 615 616 # iterate over all versions and find all function definitions 617 for index, v in enumerate(versions): 618 matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1]) 619 for returnType, name, argList in matches: 620 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList), v[0])) 621 return functions 622 623def splitByExtension (src): 624 ptrn = r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"' 625 # Construct long pattern that will be used to split whole source by extensions 626 match = "#define\s+(" 627 for part in re.finditer(ptrn, src): 628 match += part.group(1)+"|" 629 match = match[:-1] + ")\s+1" 630 parts = re.split(match, src) 631 632 # First part is core, following tuples contain extension name and all its definitions 633 byExtension = [(None, parts[0])] 634 for ndx in range(1, len(parts), 2): 635 byExtension.append((parts[ndx], parts[ndx+1])) 636 return byExtension 637 638def parseDefinitions (extensionName, src): 639 640 def skipDefinition (extensionName, definition): 641 if extensionName == None: 642 return True 643 extNameUpper = extensionName.upper() 644 extNameUpper = extNameUpper.replace("VK_KHR_SYNCHRONIZATION2", "VK_KHR_SYNCHRONIZATION_2") 645 extNameUpper = extNameUpper.replace("VK_INTEL_SHADER_INTEGER_FUNCTIONS2", "VK_INTEL_SHADER_INTEGER_FUNCTIONS_2") 646 extNameUpper = extNameUpper.replace("VK_EXT_ROBUSTNESS2", "VK_EXT_ROBUSTNESS_2") 647 extNameUpper = extNameUpper.replace("VK_EXT_FRAGMENT_DENSITY_MAP2", "VK_EXT_FRAGMENT_DENSITY_MAP_2") 648 extNameUpper = extNameUpper.replace("VK_AMD_SHADER_CORE_PROPERTIES2", "VK_AMD_SHADER_CORE_PROPERTIES_2") 649 extNameUpper = extNameUpper.replace("VK_EXT_EXTENDED_DYNAMIC_STATE2", "VK_EXT_EXTENDED_DYNAMIC_STATE_2") 650 # SPEC_VERSION enums 651 if definition[0].startswith(extNameUpper) and definition[1].isdigit(): 652 return False 653 if definition[0].startswith(extNameUpper): 654 return True 655 if definition[1].isdigit(): 656 return True 657 return False 658 659 ptrn = r'#define\s+([^\s]+)\s+([^\r\n]+)' 660 matches = re.findall(ptrn, src) 661 662 return [Definition(None, match[0], match[1]) for match in matches if not skipDefinition(extensionName, match)] 663 664def parseTypedefs (src): 665 666 ptrn = r'typedef\s+([^\s]+)\s+([^\r\n]+);' 667 matches = re.findall(ptrn, src) 668 669 return [Definition(None, match[0], match[1]) for match in matches] 670 671def parseExtensions (src, versions, allFunctions, allCompositeTypes, allEnums, allBitfields, allHandles, allDefinitions): 672 673 def getCoreVersion (extensionName, extensionsData): 674 # returns None when extension was not added to core for any Vulkan version 675 # returns array containing DEVICE or INSTANCE string followed by the vulkan version in which this extension is core 676 # note that this function is also called for vulkan 1.0 source for which extName is None 677 if not extensionName: 678 return None 679 ptrn = extensionName + r'\s+(DEVICE|INSTANCE)\s+([0-9_]+)' 680 coreVersion = re.search(ptrn, extensionsData, re.I) 681 if coreVersion != None: 682 return [coreVersion.group(1)] + [int(number) for number in coreVersion.group(2).split('_')[:3]] 683 return None 684 685 extensionsData = readFile(os.path.join(VULKAN_H_DIR, "extensions_data.txt")) 686 splitSrc = splitByExtension(src) 687 extensions = [] 688 functionsByName = {function.name: function for function in allFunctions} 689 compositeTypesByName = {compType.name: compType for compType in allCompositeTypes} 690 enumsByName = {enum.name: enum for enum in allEnums} 691 bitfieldsByName = {bitfield.name: bitfield for bitfield in allBitfields} 692 handlesByName = {handle.name: handle for handle in allHandles} 693 definitionsByName = {definition.name: definition for definition in allDefinitions} 694 695 for extensionName, extensionSrc in splitSrc: 696 definitions = [Definition("deUint32", v.getInHex(), parsePreprocDefinedValueOptional(extensionSrc, v.getInHex())) for v in versions] 697 definitions.extend([Definition(type, name, parsePreprocDefinedValueOptional(extensionSrc, name)) for name, type in DEFINITIONS]) 698 definitions = [definition for definition in definitions if definition.value != None] 699 additionalDefinitions = parseDefinitions(extensionName, extensionSrc) 700 handles = parseHandles(extensionSrc) 701 functions = parseFunctions(extensionSrc) 702 compositeTypes = parseCompositeTypes(extensionSrc) 703 rawEnums = parseEnums(extensionSrc) 704 bitfieldNames = parseBitfieldNames(extensionSrc) 705 typedefs = parseTypedefs(extensionSrc) 706 enumBitfieldNames = [getBitEnumNameForBitfield(name) for name in bitfieldNames] 707 enums = [enum for enum in rawEnums if enum.name not in enumBitfieldNames] 708 709 extCoreVersion = getCoreVersion(extensionName, extensionsData) 710 extFunctions = [functionsByName[function.name] for function in functions] 711 extCompositeTypes = [compositeTypesByName[compositeType.name] for compositeType in compositeTypes] 712 extEnums = [enumsByName[enum.name] for enum in enums] 713 extBitfields = [bitfieldsByName[bitfieldName] for bitfieldName in bitfieldNames] 714 extHandles = [handlesByName[handle.name] for handle in handles] 715 extDefinitions = [definitionsByName[definition.name] for definition in definitions] 716 717 if extCoreVersion != None: 718 populateExtensionAliases(functionsByName, extFunctions) 719 populateExtensionAliases(handlesByName, extHandles) 720 populateExtensionAliases(enumsByName, extEnums) 721 populateExtensionAliases(bitfieldsByName, extBitfields) 722 populateExtensionAliases(compositeTypesByName, extCompositeTypes) 723 extensions.append(Extension(extensionName, extHandles, extEnums, extBitfields, extCompositeTypes, extFunctions, extDefinitions, additionalDefinitions, typedefs, extCoreVersion)) 724 return extensions 725 726def parseBitfieldNames (src): 727 ptrn = r'typedef\s+VkFlags\s(' + IDENT_PTRN + r')\s*;' 728 matches = re.findall(ptrn, src) 729 730 return matches 731 732def parse64bitBitfieldNames (src): 733 ptrn = r'typedef\s+VkFlags64\s(' + IDENT_PTRN + r')\s*;' 734 matches = re.findall(ptrn, src) 735 736 return matches 737 738def parse64bitBitfieldValues (src, bitfieldNamesList): 739 740 bitfields64 = [] 741 for bitfieldName in bitfieldNamesList: 742 ptrn = r'static const ' + bitfieldName + r'\s*(' + IDENT_PTRN + r')\s*=\s*([a-zA-Z0-9_]+)\s*;' 743 matches = re.findall(ptrn, src) 744 bitfields64.append(Bitfield(bitfieldName, matches)) 745 746 return bitfields64 747 748def parseAPI (src): 749 versionsData = parseVersions(src) 750 versions = [Version((v[2], v[3], 0)) for v in versionsData] 751 definitions = [Definition("deUint32", v.getInHex(), parsePreprocDefinedValue(src, v.getInHex())) for v in versions] +\ 752 [Definition(type, name, parsePreprocDefinedValue(src, name)) for name, type in DEFINITIONS] 753 754 handles = parseHandles(src) 755 rawEnums = parseEnums(src) 756 bitfieldNames = parseBitfieldNames(src) 757 bitfieldEnums = set([getBitEnumNameForBitfield(n) for n in bitfieldNames if getBitEnumNameForBitfield(n) in [enum.name for enum in rawEnums]]) 758 bitfield64Names = parse64bitBitfieldNames(src) 759 bitfields64 = parse64bitBitfieldValues(src, bitfield64Names) 760 enums = [] 761 bitfields = [] 762 compositeTypes = parseCompositeTypesByVersion(src, versionsData) 763 allFunctions = parseFunctionsByVersion(src, versionsData) 764 765 for enum in rawEnums: 766 if enum.name in bitfieldEnums: 767 bitfields.append(Bitfield(getBitfieldNameForBitEnum(enum.name), enum.values)) 768 else: 769 enums.append(enum) 770 771 for bitfieldName in bitfieldNames: 772 if not bitfieldName in [bitfield.name for bitfield in bitfields]: 773 # Add empty bitfield 774 bitfields.append(Bitfield(bitfieldName, [])) 775 776 extensions = parseExtensions(src, versions, allFunctions, compositeTypes, enums, bitfields, handles, definitions) 777 778 # Populate alias fields 779 populateAliasesWithTypedefs(compositeTypes, src) 780 populateAliasesWithTypedefs(enums, src) 781 populateAliasesWithTypedefs(bitfields, src) 782 populateAliasesWithTypedefs(handles, src) 783 784 for enum in enums: 785 removeAliasedValues(enum) 786 787 # Make generator to create Deleter<VkAccelerationStructureNV> 788 for f in allFunctions: 789 if (f.name == 'vkDestroyAccelerationStructureNV'): 790 f.arguments[1].type[0] = 'VkAccelerationStructureNV' 791 792 # Dealias handles VkAccelerationStructureNV and VkAccelerationStructureKHR 793 for handle in handles: 794 if handle.name == 'VkAccelerationStructureKHR': 795 handle.alias = None 796 if handle.name == 'VkAccelerationStructureNV': 797 handle.isAlias = False 798 return API( 799 versions = versions, 800 definitions = definitions, 801 handles = handles, 802 enums = enums, 803 bitfields = bitfields, 804 bitfields64 = bitfields64, 805 compositeTypes = compositeTypes, 806 functions = allFunctions, 807 extensions = extensions) 808 809def splitUniqueAndDuplicatedEntries (handles): 810 listOfUniqueHandles = [] 811 duplicates = OrderedDict() 812 for handle in handles: 813 if handle.alias != None: 814 duplicates[handle.alias] = handle 815 if not handle.isAlias: 816 listOfUniqueHandles.append(handle) 817 return listOfUniqueHandles, duplicates 818 819def writeHandleType (api, filename): 820 uniqeHandles, duplicatedHandles = splitUniqueAndDuplicatedEntries(api.handles) 821 822 def genHandles (): 823 yield "\t%s\t= 0," % uniqeHandles[0].getHandleType() 824 for handle in uniqeHandles[1:]: 825 yield "\t%s," % handle.getHandleType() 826 for duplicate in duplicatedHandles: 827 yield "\t%s\t= %s," % (duplicate.getHandleType(), duplicatedHandles[duplicate].getHandleType()) 828 yield "\tHANDLE_TYPE_LAST\t= %s + 1" % (uniqeHandles[-1].getHandleType()) 829 830 def genHandlesBlock (): 831 yield "enum HandleType" 832 yield "{" 833 834 for line in indentLines(genHandles()): 835 yield line 836 837 yield "};" 838 yield "" 839 840 writeInlFile(filename, INL_HEADER, genHandlesBlock()) 841 842def getEnumValuePrefix (enum): 843 prefix = enum.name[0] 844 for i in range(1, len(enum.name)): 845 if enum.name[i].isupper() and not enum.name[i-1].isupper(): 846 prefix += "_" 847 prefix += enum.name[i].upper() 848 return prefix 849 850def parseInt (value): 851 if value[:2] == "0x": 852 return int(value, 16) 853 else: 854 return int(value, 10) 855 856def areEnumValuesLinear (enum): 857 curIndex = 0 858 for name, value in enum.values: 859 if value[:2] != "VK": 860 intValue = parseInt(value) 861 if intValue != curIndex: 862 # consider enums containing *_MAX_ENUM = 0x7FFFFFFF as linear 863 if intValue == 0x7FFFFFFF: 864 return True 865 return False 866 curIndex += 1 867 return True 868 869def genEnumSrc (enum): 870 yield "enum %s" % enum.name 871 yield "{" 872 873 lines = ["\t%s\t= %s," % v for v in enum.values] 874 if areEnumValuesLinear(enum): 875 lastItem = "\t%s_LAST," % getEnumValuePrefix(enum) 876 if parseInt(enum.values[-1][1]) == 0x7FFFFFFF: 877 # if last enum item is *_MAX_ENUM then we need to make sure 878 # it stays last entry also if we append *_LAST to generated 879 # source (without this value of *_LAST won't be correct) 880 lines.insert(-1, lastItem) 881 else: 882 lines.append(lastItem) 883 884 for line in indentLines(lines): 885 yield line 886 887 yield "};" 888 889def genBitfieldSrc (bitfield): 890 if len(bitfield.values) > 0: 891 yield "enum %s" % getBitEnumNameForBitfield(bitfield.name) 892 yield "{" 893 for line in indentLines(["\t%s\t= %s," % v for v in bitfield.values]): 894 yield line 895 yield "};" 896 yield "typedef deUint32 %s;" % bitfield.name 897 898def genBitfield64Src (bitfield64): 899 yield "typedef deUint64 %s;" % bitfield64.name 900 if len(bitfield64.values) > 0: 901 ptrn = "static const " + bitfield64.name + " %s\t= %s;" 902 for line in indentLines([ptrn % v for v in bitfield64.values]): 903 yield line 904 yield "" 905 906def genCompositeTypeSrc (type): 907 yield "%s %s" % (type.getClassName(), type.name) 908 yield "{" 909 for line in indentLines(['\t'+m.getAsString('\t')+';' for m in type.members]): 910 yield line 911 yield "};" 912 913def genHandlesSrc (handles): 914 uniqeHandles, duplicatedHandles = splitUniqueAndDuplicatedEntries(handles) 915 916 def genLines (handles): 917 for handle in uniqeHandles: 918 if handle.type == Handle.TYPE_DISP: 919 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType()) 920 elif handle.type == Handle.TYPE_NONDISP: 921 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType()) 922 923 for duplicate in duplicatedHandles: 924 if duplicate.type == Handle.TYPE_DISP: 925 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (duplicate.name, duplicatedHandles[duplicate].getHandleType()) 926 elif duplicate.type == Handle.TYPE_NONDISP: 927 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (duplicate.name, duplicatedHandles[duplicate].getHandleType()) 928 929 for line in indentLines(genLines(handles)): 930 yield line 931 932def stripTrailingComment(str): 933 index = str.find("//") 934 if index == -1: 935 return str 936 return str[:index] 937 938def genDefinitionsSrc (definitions): 939 for line in ["#define %s\t(static_cast<%s>\t(%s))" % (definition.name, definition.type, stripTrailingComment(definition.value)) for definition in definitions]: 940 yield line 941 942def genDefinitionsAliasSrc (definitions): 943 for line in ["#define %s\t%s" % (definition.name, definitions[definition].name) for definition in definitions]: 944 if definition.value != definitions[definition].value and definition.value != definitions[definition].name: 945 raise Exception("Value of %s (%s) is different than core definition value %s (%s)." % (definition.name, definition.value, definitions[definition].name, definitions[definition].value)) 946 yield line 947 948def genMaxFrameworkVersion (definitions): 949 maxApiVersionMajor = 1 950 maxApiVersionMinor = 0 951 for definition in definitions: 952 match = re.match("VK_API_VERSION_(\d+)_(\d+)", definition.name) 953 if match: 954 apiVersionMajor = int(match.group(1)) 955 apiVersionMinor = int(match.group(2)) 956 if apiVersionMajor > maxApiVersionMajor: 957 maxApiVersionMajor = apiVersionMajor 958 maxApiVersionMinor = apiVersionMinor 959 elif apiVersionMajor == maxApiVersionMajor and apiVersionMinor > maxApiVersionMinor: 960 maxApiVersionMinor = apiVersionMinor 961 yield "#define VK_API_MAX_FRAMEWORK_VERSION\tVK_API_VERSION_%d_%d" % (maxApiVersionMajor, maxApiVersionMinor) 962 963def writeBasicTypes (api, filename): 964 965 def gen (): 966 definitionsCore, definitionDuplicates = splitUniqueAndDuplicatedEntries(api.definitions) 967 968 for line in indentLines(chain(genDefinitionsSrc(definitionsCore), genMaxFrameworkVersion(definitionsCore), genDefinitionsAliasSrc(definitionDuplicates))): 969 yield line 970 yield "" 971 972 for line in genHandlesSrc(api.handles): 973 yield line 974 yield "" 975 976 for enum in api.enums: 977 if not enum.isAlias: 978 for line in genEnumSrc(enum): 979 yield line 980 else: 981 for enum2 in api.enums: 982 if enum2.alias == enum: 983 yield "typedef %s %s;" % (enum2.name, enum.name) 984 yield "" 985 986 for bitfield in api.bitfields: 987 if not bitfield.isAlias: 988 for line in genBitfieldSrc(bitfield): 989 yield line 990 else: 991 for bitfield2 in api.bitfields: 992 if bitfield2.alias == bitfield: 993 yield "typedef %s %s;" % (bitfield2.name, bitfield.name) 994 yield "" 995 996 for bitfield64 in api.bitfields64: 997 for line in genBitfield64Src(bitfield64): 998 yield line 999 1000 for line in indentLines(["VK_DEFINE_PLATFORM_TYPE(%s,\t%s);" % (s[0], c) for n, s, c in PLATFORM_TYPES]): 1001 yield line 1002 1003 for ext in api.extensions: 1004 if ext.additionalDefs != None: 1005 for definition in ext.additionalDefs: 1006 yield "#define " + definition.name + " " + definition.value 1007 1008 writeInlFile(filename, INL_HEADER, gen()) 1009 1010def writeCompositeTypes (api, filename): 1011 def gen (): 1012 for type in api.compositeTypes: 1013 type.checkAliasValidity() 1014 1015 if not type.isAlias: 1016 for line in genCompositeTypeSrc(type): 1017 yield line 1018 else: 1019 for type2 in api.compositeTypes: 1020 if type2.alias == type: 1021 yield "typedef %s %s;" % (type2.name, type.name) 1022 yield "" 1023 1024 writeInlFile(filename, INL_HEADER, gen()) 1025 1026def argListToStr (args): 1027 return ", ".join(v.getAsStringForArgumentList(' ') for v in args) 1028 1029def writeInterfaceDecl (api, filename, functionTypes, concrete): 1030 def genProtos (): 1031 postfix = "" if concrete else " = 0" 1032 for function in api.functions: 1033 if not function.getType() in functionTypes: 1034 continue 1035 if not function.isAlias: 1036 yield "virtual %s\t%s\t(%s) const%s;" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments), postfix) 1037 1038 writeInlFile(filename, INL_HEADER, indentLines(genProtos())) 1039 1040def writeFunctionPtrTypes (api, filename): 1041 def genTypes (): 1042 for function in api.functions: 1043 yield "typedef VKAPI_ATTR %s\t(VKAPI_CALL* %s)\t(%s);" % (function.returnType, getFunctionTypeName(function), argListToStr(function.arguments)) 1044 1045 writeInlFile(filename, INL_HEADER, indentLines(genTypes())) 1046 1047def writeFunctionPointers (api, filename, functionTypes): 1048 def FunctionsYielder (): 1049 for function in api.functions: 1050 if function.getType() in functionTypes: 1051 if function.isAlias: 1052 if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice": 1053 yield "%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function)) 1054 else: 1055 yield "%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function)) 1056 1057 writeInlFile(filename, INL_HEADER, indentLines(FunctionsYielder())) 1058 1059def writeInitFunctionPointers (api, filename, functionTypes, cond = None): 1060 def makeInitFunctionPointers (): 1061 for function in api.functions: 1062 if function.getType() in functionTypes and (cond == None or cond(function)): 1063 interfaceName = getInterfaceName(function) 1064 if function.isAlias: 1065 if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice": 1066 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name) 1067 else: 1068 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name) 1069 if function.alias != None: 1070 yield "if (!m_vk.%s)" % (getInterfaceName(function)) 1071 yield " m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.alias.name) 1072 lines = [line.replace(' ', '\t') for line in indentLines(makeInitFunctionPointers())] 1073 writeInlFile(filename, INL_HEADER, lines) 1074 1075def writeFuncPtrInterfaceImpl (api, filename, functionTypes, className): 1076 def makeFuncPtrInterfaceImpl (): 1077 for function in api.functions: 1078 if function.getType() in functionTypes and not function.isAlias: 1079 yield "" 1080 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments)) 1081 yield "{" 1082 if function.name == "vkEnumerateInstanceVersion": 1083 yield " if (m_vk.enumerateInstanceVersion)" 1084 yield " return m_vk.enumerateInstanceVersion(pApiVersion);" 1085 yield "" 1086 yield " *pApiVersion = VK_API_VERSION_1_0;" 1087 yield " return VK_SUCCESS;" 1088 elif function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice" and function.alias != None: 1089 yield " vk::VkPhysicalDeviceProperties props;" 1090 yield " m_vk.getPhysicalDeviceProperties(physicalDevice, &props);" 1091 yield " if (props.apiVersion >= VK_API_VERSION_1_1)" 1092 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments)) 1093 yield " else" 1094 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function.alias), ", ".join(a.name for a in function.arguments)) 1095 else: 1096 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments)) 1097 yield "}" 1098 1099 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceImpl()) 1100 1101def writeStrUtilProto (api, filename): 1102 def makeStrUtilProto (): 1103 for line in indentLines(["const char*\tget%sName\t(%s value);" % (enum.name[2:], enum.name) for enum in api.enums if not enum.isAlias]): 1104 yield line 1105 yield "" 1106 for line in indentLines(["inline tcu::Format::Enum<%s>\tget%sStr\t(%s value)\t{ return tcu::Format::Enum<%s>(get%sName, value);\t}" % (e.name, e.name[2:], e.name, e.name, e.name[2:]) for e in api.enums if not e.isAlias]): 1107 yield line 1108 yield "" 1109 for line in indentLines(["inline std::ostream&\toperator<<\t(std::ostream& s, %s value)\t{ return s << get%sStr(value);\t}" % (e.name, e.name[2:]) for e in api.enums if not e.isAlias]): 1110 yield line 1111 yield "" 1112 for line in indentLines(["tcu::Format::Bitfield<32>\tget%sStr\t(%s value);" % (bitfield.name[2:], bitfield.name) for bitfield in api.bitfields if not bitfield.isAlias or bitfield.name=='VkBuildAccelerationStructureFlagsNV']): 1113 yield line 1114 yield "" 1115 for line in indentLines(["std::ostream&\toperator<<\t(std::ostream& s, const %s& value);" % (s.name) for s in api.compositeTypes if not s.isAlias]): 1116 yield line 1117 1118 writeInlFile(filename, INL_HEADER, makeStrUtilProto()) 1119 1120def writeStrUtilImpl (api, filename): 1121 def makeStrUtilImpl (): 1122 for line in indentLines(["template<> const char*\tgetTypeName<%s>\t(void) { return \"%s\";\t}" % (handle.name, handle.name) for handle in api.handles if not handle.isAlias]): 1123 yield line 1124 1125 yield "" 1126 yield "namespace %s" % PLATFORM_TYPE_NAMESPACE 1127 yield "{" 1128 1129 for line in indentLines("std::ostream& operator<< (std::ostream& s, %s\tv) { return s << tcu::toHex(v.internal); }" % ''.join(s) for n, s, c in PLATFORM_TYPES): 1130 yield line 1131 1132 yield "}" 1133 1134 for enum in api.enums: 1135 if enum.isAlias: 1136 continue 1137 yield "" 1138 yield "const char* get%sName (%s value)" % (enum.name[2:], enum.name) 1139 yield "{" 1140 yield "\tswitch (value)" 1141 yield "\t{" 1142 for line in indentLines(["\t\tcase %s:\treturn \"%s\";" % (n, n) for n, v in enum.values if v[:2] != "VK"] + ["\t\tdefault:\treturn DE_NULL;"]): 1143 yield line 1144 yield "\t}" 1145 yield "}" 1146 1147 for bitfield in api.bitfields: 1148 if bitfield.isAlias: 1149 if bitfield.name != 'VkBuildAccelerationStructureFlagsNV': 1150 continue 1151 yield "" 1152 yield "tcu::Format::Bitfield<32> get%sStr (%s value)" % (bitfield.name[2:], bitfield.name) 1153 yield "{" 1154 1155 if len(bitfield.values) > 0: 1156 yield "\tstatic const tcu::Format::BitDesc s_desc[] =" 1157 yield "\t{" 1158 for line in indentLines(["\t\ttcu::Format::BitDesc(%s,\t\"%s\")," % (n, n) for n, v in bitfield.values]): 1159 yield line 1160 yield "\t};" 1161 yield "\treturn tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));" 1162 else: 1163 yield "\treturn tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL);" 1164 yield "}" 1165 1166 bitfieldTypeNames = set([bitfield.name for bitfield in api.bitfields]) 1167 1168 for type in api.compositeTypes: 1169 if not type.isAlias: 1170 yield "" 1171 yield "std::ostream& operator<< (std::ostream& s, const %s& value)" % type.name 1172 yield "{" 1173 yield "\ts << \"%s = {\\n\";" % type.name 1174 for member in type.members: 1175 memberName = member.name 1176 valFmt = None 1177 newLine = "" 1178 if member.getType() in bitfieldTypeNames: 1179 valFmt = "get%sStr(value.%s)" % (member.getType()[2:], member.name) 1180 elif member.getType() == "const char*" or member.getType() == "char*": 1181 valFmt = "getCharPtrStr(value.%s)" % member.name 1182 elif member.getType() == PLATFORM_TYPE_NAMESPACE + "::Win32LPCWSTR": 1183 valFmt = "getWStr(value.%s)" % member.name 1184 elif member.arraySize != '': 1185 singleDimensional = not '][' in member.arraySize 1186 if member.name in ["extensionName", "deviceName", "layerName", "description"]: 1187 valFmt = "(const char*)value.%s" % member.name 1188 elif singleDimensional and (member.getType() == 'char' or member.getType() == 'deUint8'): 1189 newLine = "'\\n' << " 1190 valFmt = "tcu::formatArray(tcu::Format::HexIterator<%s>(DE_ARRAY_BEGIN(value.%s)), tcu::Format::HexIterator<%s>(DE_ARRAY_END(value.%s)))" % (member.getType(), member.name, member.getType(), member.name) 1191 else: 1192 if member.name == "memoryTypes" or member.name == "memoryHeaps": 1193 endIter = "DE_ARRAY_BEGIN(value.%s) + value.%sCount" % (member.name, member.name[:-1]) 1194 else: 1195 endIter = "DE_ARRAY_END(value.%s)" % member.name 1196 newLine = "'\\n' << " 1197 valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), %s)" % (member.name, endIter) 1198 memberName = member.name 1199 else: 1200 valFmt = "value.%s" % member.name 1201 yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';" 1202 yield "\ts << '}';" 1203 yield "\treturn s;" 1204 yield "}" 1205 writeInlFile(filename, INL_HEADER, makeStrUtilImpl()) 1206 1207 1208def writeObjTypeImpl (api, filename): 1209 def makeObjTypeImpl (): 1210 1211 yield "namespace vk" 1212 yield "{" 1213 1214 yield "template<typename T> VkObjectType getObjectType (void);" 1215 1216 for line in indentLines(["template<> inline VkObjectType\tgetObjectType<%s>\t(void) { return %s;\t}" % (handle.name, prefixName("VK_OBJECT_TYPE_", handle.name)) for handle in api.handles if not handle.isAlias]): 1217 yield line 1218 1219 yield "}" 1220 1221 writeInlFile(filename, INL_HEADER, makeObjTypeImpl()) 1222 1223class ConstructorFunction: 1224 def __init__ (self, type, name, objectType, ifaceArgs, arguments): 1225 self.type = type 1226 self.name = name 1227 self.objectType = objectType 1228 self.ifaceArgs = ifaceArgs 1229 self.arguments = arguments 1230 1231def getConstructorFunctions (api): 1232 funcs = [] 1233 ifacesDict = { 1234 Function.TYPE_PLATFORM: [Variable("const PlatformInterface&", "vk", "")], 1235 Function.TYPE_INSTANCE: [Variable("const InstanceInterface&", "vk", "")], 1236 Function.TYPE_DEVICE: [Variable("const DeviceInterface&", "vk", "")] 1237 } 1238 for function in api.functions: 1239 if function.isAlias: 1240 continue 1241 if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "createInfoCount" in [a.name for a in function.arguments]: 1242 if function.name == "vkCreateDisplayModeKHR": 1243 continue # No way to delete display modes (bug?) 1244 1245 # \todo [pyry] Rather hacky 1246 ifaceArgs = ifacesDict[function.getType()] 1247 if function.name == "vkCreateDevice": 1248 ifaceArgs = [Variable("const PlatformInterface&", "vkp", ""), Variable("VkInstance", "instance", "")] + ifaceArgs 1249 1250 assert (function.arguments[-2].type == ["const", "VkAllocationCallbacks", "*"]) 1251 1252 objectType = function.arguments[-1].type[0] #not getType() but type[0] on purpose 1253 arguments = function.arguments[:-1] 1254 funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function), objectType, ifaceArgs, arguments)) 1255 return funcs 1256 1257def addVersionDefines(versionSpectrum): 1258 output = ["#define " + ver.getDefineName() + " " + ver.getInHex() for ver in versionSpectrum if not ver.isStandardVersion()] 1259 return output 1260 1261def removeVersionDefines(versionSpectrum): 1262 output = ["#undef " + ver.getDefineName() for ver in versionSpectrum if not ver.isStandardVersion()] 1263 return output 1264 1265def writeRefUtilProto (api, filename): 1266 functions = getConstructorFunctions(api) 1267 1268 def makeRefUtilProto (): 1269 unindented = [] 1270 for line in indentLines(["Move<%s>\t%s\t(%s = DE_NULL);" % (function.objectType, function.name, argListToStr(function.ifaceArgs + function.arguments)) for function in functions]): 1271 yield line 1272 1273 writeInlFile(filename, INL_HEADER, makeRefUtilProto()) 1274 1275def writeRefUtilImpl (api, filename): 1276 functions = getConstructorFunctions(api) 1277 1278 def makeRefUtilImpl (): 1279 yield "namespace refdetails" 1280 yield "{" 1281 yield "" 1282 1283 for function in api.functions: 1284 if function.getType() == Function.TYPE_DEVICE \ 1285 and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \ 1286 and not function.name == "vkDestroyDevice" \ 1287 and not function.isAlias: 1288 objectType = function.arguments[-2].getType() 1289 yield "template<>" 1290 yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType) 1291 yield "{" 1292 yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function)) 1293 yield "}" 1294 yield "" 1295 1296 yield "} // refdetails" 1297 yield "" 1298 1299 dtorDict = { 1300 Function.TYPE_PLATFORM: "object", 1301 Function.TYPE_INSTANCE: "instance", 1302 Function.TYPE_DEVICE: "device" 1303 } 1304 1305 for function in functions: 1306 deleterArgsString = '' 1307 if function.name == "createDevice": 1308 # createDevice requires two additional parameters to setup VkDevice deleter 1309 deleterArgsString = "vkp, instance, object, " + function.arguments[-1].name 1310 else: 1311 deleterArgsString = "vk, %s, %s" % (dtorDict[function.type], function.arguments[-1].name) 1312 1313 yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr(function.ifaceArgs + function.arguments)) 1314 yield "{" 1315 yield "\t%s object = 0;" % function.objectType 1316 yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"])) 1317 yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, deleterArgsString) 1318 yield "}" 1319 yield "" 1320 1321 writeInlFile(filename, INL_HEADER, makeRefUtilImpl()) 1322 1323def writeStructTraitsImpl (api, filename): 1324 def gen (): 1325 for type in api.compositeTypes: 1326 if type.getClassName() == "struct" and type.members[0].name == "sType" and not type.isAlias and type.name != "VkBaseOutStructure" and type.name != "VkBaseInStructure": 1327 yield "template<> VkStructureType getStructureType<%s> (void)" % type.name 1328 yield "{" 1329 yield "\treturn %s;" % prefixName("VK_STRUCTURE_TYPE_", type.name) 1330 yield "}" 1331 yield "" 1332 1333 writeInlFile(filename, INL_HEADER, gen()) 1334 1335def writeNullDriverImpl (api, filename): 1336 def genNullDriverImpl (): 1337 specialFuncNames = [ 1338 "vkCreateGraphicsPipelines", 1339 "vkCreateComputePipelines", 1340 "vkCreateRayTracingPipelinesNV", 1341 "vkCreateRayTracingPipelinesKHR", 1342 "vkGetInstanceProcAddr", 1343 "vkGetDeviceProcAddr", 1344 "vkEnumeratePhysicalDevices", 1345 "vkEnumerateInstanceExtensionProperties", 1346 "vkEnumerateDeviceExtensionProperties", 1347 "vkGetPhysicalDeviceFeatures", 1348 "vkGetPhysicalDeviceFeatures2KHR", 1349 "vkGetPhysicalDeviceProperties", 1350 "vkGetPhysicalDeviceProperties2KHR", 1351 "vkGetPhysicalDeviceQueueFamilyProperties", 1352 "vkGetPhysicalDeviceMemoryProperties", 1353 "vkGetPhysicalDeviceFormatProperties", 1354 "vkGetPhysicalDeviceImageFormatProperties", 1355 "vkGetDeviceQueue", 1356 "vkGetBufferMemoryRequirements", 1357 "vkGetBufferMemoryRequirements2KHR", 1358 "vkGetImageMemoryRequirements", 1359 "vkGetImageMemoryRequirements2KHR", 1360 "vkAllocateMemory", 1361 "vkMapMemory", 1362 "vkUnmapMemory", 1363 "vkAllocateDescriptorSets", 1364 "vkFreeDescriptorSets", 1365 "vkResetDescriptorPool", 1366 "vkAllocateCommandBuffers", 1367 "vkFreeCommandBuffers", 1368 "vkCreateDisplayModeKHR", 1369 "vkCreateSharedSwapchainsKHR", 1370 "vkGetPhysicalDeviceExternalBufferPropertiesKHR", 1371 "vkGetPhysicalDeviceImageFormatProperties2KHR", 1372 "vkGetMemoryAndroidHardwareBufferANDROID", 1373 ] 1374 1375 coreFunctions = [f for f in api.functions if not f.isAlias] 1376 specialFuncs = [f for f in coreFunctions if f.name in specialFuncNames] 1377 createFuncs = [f for f in coreFunctions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs] 1378 destroyFuncs = [f for f in coreFunctions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs] 1379 dummyFuncs = [f for f in coreFunctions if f not in specialFuncs + createFuncs + destroyFuncs] 1380 1381 def getHandle (name): 1382 for handle in api.handles: 1383 if handle.name == name[0]: 1384 return handle 1385 raise Exception("No such handle: %s" % name) 1386 1387 for function in createFuncs: 1388 objectType = function.arguments[-1].type[:-1] 1389 argsStr = ", ".join([a.name for a in function.arguments[:-1]]) 1390 1391 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments)) 1392 yield "{" 1393 yield "\tDE_UNREF(%s);" % function.arguments[-2].name 1394 1395 if getHandle(objectType).type == Handle.TYPE_NONDISP: 1396 yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[0][2:], objectType[0], argsStr) 1397 else: 1398 yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[0][2:], objectType[0], argsStr) 1399 yield "}" 1400 yield "" 1401 1402 for function in destroyFuncs: 1403 objectArg = function.arguments[-2] 1404 1405 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments)) 1406 yield "{" 1407 for arg in function.arguments[:-2]: 1408 yield "\tDE_UNREF(%s);" % arg.name 1409 1410 if getHandle(objectArg.type).type == Handle.TYPE_NONDISP: 1411 yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.getType()[2:], objectArg.getType(), objectArg.name, function.arguments[-1].name) 1412 else: 1413 yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.getType()[2:], objectArg.getType(), objectArg.name, function.arguments[-1].name) 1414 1415 yield "}" 1416 yield "" 1417 1418 for function in dummyFuncs: 1419 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments)) 1420 yield "{" 1421 for arg in function.arguments: 1422 yield "\tDE_UNREF(%s);" % arg.name 1423 if function.returnType != "void": 1424 yield "\treturn VK_SUCCESS;" 1425 yield "}" 1426 yield "" 1427 1428 def genFuncEntryTable (type, name): 1429 funcs = [f for f in api.functions if f.getType() == type] 1430 refFuncs = {} 1431 for f in api.functions: 1432 if f.alias != None: 1433 refFuncs[f.alias] = f 1434 1435 yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name 1436 yield "{" 1437 for line in indentLines(["\tVK_NULL_FUNC_ENTRY(%s,\t%s)," % (function.name, getInterfaceName(function if not function.isAlias else refFuncs[function])) for function in funcs]): 1438 yield line 1439 yield "};" 1440 yield "" 1441 1442 # Func tables 1443 for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"): 1444 yield line 1445 1446 for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"): 1447 yield line 1448 1449 for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"): 1450 yield line 1451 1452 writeInlFile(filename, INL_HEADER, genNullDriverImpl()) 1453 1454def writeTypeUtil (api, filename): 1455 # Structs filled by API queries are not often used in test code 1456 QUERY_RESULT_TYPES = set([ 1457 "VkPhysicalDeviceFeatures", 1458 "VkPhysicalDeviceLimits", 1459 "VkFormatProperties", 1460 "VkImageFormatProperties", 1461 "VkPhysicalDeviceSparseProperties", 1462 "VkQueueFamilyProperties", 1463 "VkMemoryType", 1464 "VkMemoryHeap", 1465 "StdVideoH264SpsVuiFlags", 1466 "StdVideoH264SpsFlags", 1467 "StdVideoH264PpsFlags", 1468 "StdVideoDecodeH264PictureInfoFlags", 1469 "StdVideoDecodeH264ReferenceInfoFlags", 1470 "StdVideoDecodeH264MvcElementFlags", 1471 "StdVideoEncodeH264SliceHeaderFlags", 1472 "StdVideoEncodeH264PictureInfoFlags", 1473 "StdVideoEncodeH264RefMgmtFlags", 1474 "StdVideoH265HrdFlags", 1475 "StdVideoH265VpsFlags", 1476 "StdVideoH265SpsVuiFlags", 1477 "StdVideoH265SpsFlags", 1478 "StdVideoH265PpsFlags", 1479 "StdVideoDecodeH265PictureInfoFlags", 1480 "StdVideoDecodeH265ReferenceInfoFlags", 1481 "StdVideoEncodeH265PictureInfoFlags" 1482 ]) 1483 COMPOSITE_TYPES = set([t.name for t in api.compositeTypes if not t.isAlias]) 1484 1485 def isSimpleStruct (type): 1486 def hasArrayMember (type): 1487 for member in type.members: 1488 if member.arraySize != '': 1489 return True 1490 return False 1491 1492 def hasCompositeMember (type): 1493 for member in type.members: 1494 if member.getType() in COMPOSITE_TYPES: 1495 return True 1496 return False 1497 1498 return type.typeClass == CompositeType.CLASS_STRUCT and \ 1499 type.members[0].getType() != "VkStructureType" and \ 1500 not type.name in QUERY_RESULT_TYPES and \ 1501 not hasArrayMember(type) and \ 1502 not hasCompositeMember(type) 1503 1504 def gen (): 1505 for type in api.compositeTypes: 1506 if not isSimpleStruct(type) or type.isAlias: 1507 continue 1508 1509 name = type.name[2:] if type.name[:2].lower() == "vk" else type.name 1510 1511 yield "" 1512 yield "inline %s make%s (%s)" % (type.name, name, argListToStr(type.members)) 1513 yield "{" 1514 yield "\t%s res;" % type.name 1515 for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]): 1516 yield line 1517 yield "\treturn res;" 1518 yield "}" 1519 1520 writeInlFile(filename, INL_HEADER, gen()) 1521 1522def writeDriverIds(filename): 1523 1524 driverIdsString = [] 1525 driverIdsString.append("static const struct\n" 1526 "{\n" 1527 "\tstd::string driver;\n" 1528 "\tdeUint32 id;\n" 1529 "} driverIds [] =\n" 1530 "{") 1531 1532 vulkanCore = readFile(os.path.join(VULKAN_H_DIR, "vulkan_core.h")) 1533 1534 items = re.search(r'(?:typedef\s+enum\s+VkDriverId\s*{)((.*\n)*)(?:}\s*VkDriverId\s*;)', vulkanCore).group(1).split(',') 1535 driverItems = dict() 1536 for item in items: 1537 item.strip() 1538 splitted = item.split('=') 1539 key = splitted[0].strip() 1540 value_str = splitted[1].strip() 1541 try: # is this previously defined value? 1542 value = driverItems[value_str] 1543 except: 1544 value = value_str 1545 value_str = "" 1546 if value_str: 1547 value_str = "\t// " + value_str 1548 driverItems[key] = value 1549 if not item == items[-1]: 1550 driverIdsString.append("\t{\"" + key + "\"" + ", " + value + "}," + value_str) 1551 else: 1552 driverIdsString.append("\t{\"" + key + "\"" + ", " + value + "}" + value_str) 1553 driverItems[key] = value 1554 1555 driverIdsString.append("};") 1556 1557 writeInlFile(filename, INL_HEADER, driverIdsString) 1558 1559 1560def writeSupportedExtenions(api, filename): 1561 1562 def writeExtensionsForVersions(map): 1563 result = [] 1564 for version in map: 1565 result.append(" if (coreVersion >= " + str(version) + ")") 1566 result.append(" {") 1567 for extension in map[version]: 1568 result.append(' dst.push_back("' + extension.name + '");') 1569 result.append(" }") 1570 1571 return result 1572 1573 instanceMap = {} 1574 deviceMap = {} 1575 versionSet = set() 1576 1577 for ext in api.extensions: 1578 if ext.versionInCore != None: 1579 if ext.versionInCore[0] == 'INSTANCE': 1580 list = instanceMap.get(Version(ext.versionInCore[1:])) 1581 instanceMap[Version(ext.versionInCore[1:])] = list + [ext] if list else [ext] 1582 else: 1583 list = deviceMap.get(Version(ext.versionInCore[1:])) 1584 deviceMap[Version(ext.versionInCore[1:])] = list + [ext] if list else [ext] 1585 versionSet.add(Version(ext.versionInCore[1:])) 1586 1587 lines = addVersionDefines(versionSet) + [ 1588 "", 1589 "void getCoreDeviceExtensionsImpl (deUint32 coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(deviceMap) != 0 else ""), 1590 "{"] + writeExtensionsForVersions(deviceMap) + [ 1591 "}", 1592 "", 1593 "void getCoreInstanceExtensionsImpl (deUint32 coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(instanceMap) != 0 else ""), 1594 "{"] + writeExtensionsForVersions(instanceMap) + [ 1595 "}", 1596 ""] + removeVersionDefines(versionSet) 1597 writeInlFile(filename, INL_HEADER, lines) 1598 1599def writeExtensionFunctions (api, filename): 1600 1601 def isInstanceExtension (ext): 1602 if ext.name and ext.functions: 1603 if ext.functions[0].getType() == Function.TYPE_INSTANCE: 1604 return True 1605 else: 1606 return False 1607 1608 def isDeviceExtension (ext): 1609 if ext.name and ext.functions: 1610 if ext.functions[0].getType() == Function.TYPE_DEVICE: 1611 return True 1612 else: 1613 return False 1614 1615 def writeExtensionNameArrays (): 1616 instanceExtensionNames = [] 1617 deviceExtensionNames = [] 1618 for ext in api.extensions: 1619 if ext.name and isInstanceExtension(ext): 1620 instanceExtensionNames += [ext.name] 1621 elif ext.name and isDeviceExtension(ext): 1622 deviceExtensionNames += [ext.name] 1623 yield '::std::string instanceExtensionNames[] =\n{' 1624 for instanceExtName in instanceExtensionNames: 1625 if (instanceExtName == instanceExtensionNames[len(instanceExtensionNames) - 1]): 1626 yield '\t"%s"' % instanceExtName 1627 else: 1628 yield '\t"%s",' % instanceExtName 1629 yield '};\n' 1630 yield '::std::string deviceExtensionNames[] =\n{' 1631 for deviceExtName in deviceExtensionNames: 1632 if (deviceExtName == deviceExtensionNames[len(deviceExtensionNames) - 1]): 1633 yield '\t"%s"' % deviceExtName 1634 else: 1635 yield '\t"%s",' % deviceExtName 1636 yield '};' 1637 1638 def writeExtensionFunctions (functionType): 1639 isFirstWrite = True 1640 dg_list = [] # Device groups functions need special casing, as Vulkan 1.0 keeps them in VK_KHR_device_groups whereas 1.1 moved them into VK_KHR_swapchain 1641 if functionType == Function.TYPE_INSTANCE: 1642 yield 'void getInstanceExtensionFunctions (deUint32 apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{' 1643 dg_list = ["vkGetPhysicalDevicePresentRectanglesKHR"] 1644 elif functionType == Function.TYPE_DEVICE: 1645 yield 'void getDeviceExtensionFunctions (deUint32 apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{' 1646 dg_list = ["vkGetDeviceGroupPresentCapabilitiesKHR", "vkGetDeviceGroupSurfacePresentModesKHR", "vkAcquireNextImage2KHR"] 1647 for ext in api.extensions: 1648 funcNames = [] 1649 if ext.name: 1650 for func in ext.functions: 1651 if func.getType() == functionType: 1652 # only add functions with same vendor as extension 1653 # this is a workaroudn for entrypoints requiring more 1654 # than one excetions and lack of the dependency in vulkan_core.h 1655 vendor = ext.name.split('_')[1] 1656 if func.name.endswith(vendor): 1657 funcNames.append(func.name) 1658 if ext.name: 1659 yield '\tif (extName == "%s")' % ext.name 1660 yield '\t{' 1661 for funcName in funcNames: 1662 if funcName in dg_list: 1663 yield '\t\tif(apiVersion >= VK_API_VERSION_1_1) functions.push_back("%s");' % funcName 1664 else: 1665 yield '\t\tfunctions.push_back("%s");' % funcName 1666 if ext.name == "VK_KHR_device_group": 1667 for dg_func in dg_list: 1668 yield '\t\tif(apiVersion < VK_API_VERSION_1_1) functions.push_back("%s");' % dg_func 1669 yield '\t\treturn;' 1670 yield '\t}' 1671 isFirstWrite = False 1672 if not isFirstWrite: 1673 yield '\tDE_FATAL("Extension name not found");' 1674 yield '}' 1675 1676 lines = [''] 1677 for line in writeExtensionFunctions(Function.TYPE_INSTANCE): 1678 lines += [line] 1679 lines += [''] 1680 for line in writeExtensionFunctions(Function.TYPE_DEVICE): 1681 lines += [line] 1682 lines += [''] 1683 for line in writeExtensionNameArrays(): 1684 lines += [line] 1685 1686 writeInlFile(filename, INL_HEADER, lines) 1687 1688def writeCoreFunctionalities(api, filename): 1689 functionOriginValues = ["FUNCTIONORIGIN_PLATFORM", "FUNCTIONORIGIN_INSTANCE", "FUNCTIONORIGIN_DEVICE"] 1690 lines = addVersionDefines(api.versions) + [ 1691 "", 1692 'enum FunctionOrigin', '{'] + [line for line in indentLines([ 1693 '\t' + functionOriginValues[0] + '\t= 0,', 1694 '\t' + functionOriginValues[1] + ',', 1695 '\t' + functionOriginValues[2]])] + [ 1696 "};", 1697 "", 1698 "typedef ::std::pair<const char*, FunctionOrigin> FunctionInfo;", 1699 "typedef ::std::vector<FunctionInfo> FunctionInfosList;", 1700 "typedef ::std::map<deUint32, FunctionInfosList> ApisMap;", 1701 "", 1702 "void initApisMap (ApisMap& apis)", 1703 "{", 1704 " apis.clear();"] + [ 1705 " apis.insert(::std::pair<deUint32, FunctionInfosList>(" + str(v) + ", FunctionInfosList()));" for v in api.versions] + [ 1706 ""] 1707 1708 apiVersions = [] 1709 for index, v in enumerate(api.versions): 1710 funcs = [] 1711 apiVersions.append("VK_VERSION_{0}_{1}".format(v.major, v.minor)) 1712 # iterate over all functions that are core in latest vulkan version 1713 # note that first item in api.extension array are actually all definitions that are in vulkan.h.in before section with extensions 1714 for fun in api.extensions[0].functions: 1715 if fun.apiVersion in apiVersions: 1716 funcs.append(' apis[' + str(v) + '].push_back(FunctionInfo("' + fun.name + '",\t' + functionOriginValues[fun.getType()] + '));') 1717 lines = lines + [line for line in indentLines(funcs)] + [""] 1718 1719 lines = lines + ["}", ""] + removeVersionDefines(api.versions) 1720 writeInlFile(filename, INL_HEADER, lines) 1721 1722def writeDeviceFeatures2(api, filename): 1723 # list of structures that should be tested with getPhysicalDeviceFeatures2 1724 # this is not posible to determine from vulkan_core.h, if new feature structures 1725 # are added they should be manualy added to this list 1726 testedStructures = [ 1727 'VkPhysicalDeviceConditionalRenderingFeaturesEXT', 1728 'VkPhysicalDeviceScalarBlockLayoutFeatures', 1729 'VkPhysicalDevicePerformanceQueryFeaturesKHR', 1730 'VkPhysicalDevice16BitStorageFeatures', 1731 'VkPhysicalDeviceMultiviewFeatures', 1732 'VkPhysicalDeviceProtectedMemoryFeatures', 1733 'VkPhysicalDeviceSamplerYcbcrConversionFeatures', 1734 'VkPhysicalDeviceVariablePointersFeatures', 1735 'VkPhysicalDevice8BitStorageFeatures', 1736 'VkPhysicalDeviceShaderAtomicInt64Features', 1737 'VkPhysicalDeviceShaderFloat16Int8Features', 1738 'VkPhysicalDeviceBufferDeviceAddressFeaturesEXT', 1739 'VkPhysicalDeviceBufferDeviceAddressFeatures', 1740 'VkPhysicalDeviceDescriptorIndexingFeatures', 1741 'VkPhysicalDeviceTimelineSemaphoreFeatures', 1742 'VkPhysicalDeviceFragmentDensityMapFeaturesEXT', 1743 'VkPhysicalDeviceFragmentDensityMap2FeaturesEXT' 1744 ] 1745 # helper class used to encapsulate all data needed during generation 1746 class StructureDetail: 1747 def __init__ (self, name): 1748 nameResult = re.search('(.*)Features(.*)', name[len('VkPhysicalDevice'):]) 1749 nameSplitUp = '' 1750 # generate structure type name from structure name 1751 # note that sometimes digits are separated with '_': 1752 # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT 1753 # but mostly they are not: 1754 # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES 1755 if (nameResult.group(1) == 'FragmentDensityMap2'): 1756 nameSplitUp = ['FRAGMENT', 'DENSITY', 'MAP', '2', 'FEATURES'] 1757 else: 1758 nameSplit = re.findall(r'[1-9A-Z]+(?:[a-z1-9]+|[A-Z]*(?=[A-Z]|$))', nameResult.group(1)) 1759 nameSplitUp = map(str.upper, nameSplit) 1760 nameSplitUp = list(nameSplitUp) + ['FEATURES'] 1761 # check if there is extension suffix 1762 if (len(nameResult.group(2)) != 0): 1763 nameSplitUp.append(nameResult.group(2)) 1764 self.name = name 1765 self.sType = 'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_' + '_'.join(nameSplitUp) 1766 self.instanceName = 'd' + name[11:] 1767 self.flagName = 'is' + name[16:] 1768 self.extension = None 1769 self.major = None 1770 self.minor = None 1771 self.members = [] 1772 # helper extension class used in algorith below 1773 class StructureFoundContinueToNextOne(Exception): 1774 pass 1775 testedStructureDetail = [StructureDetail(struct) for struct in testedStructures] 1776 # iterate over all searched structures and find extensions that enable them 1777 for structureDetail in testedStructureDetail: 1778 try: 1779 # iterate over all extensions 1780 for extension in api.extensions[1:]: 1781 # check composite types and typedefs in case extension is part of core 1782 for structureList in [extension.compositeTypes, extension.typedefs]: 1783 # iterate over all structures added by extension 1784 for extensionStructure in structureList: 1785 # compare checked structure name to name of structure from extension 1786 if structureDetail.name == extensionStructure.name: 1787 structureDetail.extension = extension.name 1788 if extension.versionInCore is not None: 1789 structureDetail.major = extension.versionInCore[1] 1790 structureDetail.minor = extension.versionInCore[2] 1791 raise StructureFoundContinueToNextOne 1792 except StructureFoundContinueToNextOne: 1793 continue 1794 for structureDetail in testedStructureDetail: 1795 for compositeType in api.compositeTypes: 1796 if structureDetail.name != compositeType.name: 1797 continue 1798 structureMembers = compositeType.members[2:] 1799 structureDetail.members = [m.name for m in structureMembers] 1800 if structureDetail.major is not None: 1801 break 1802 # if structure was not added with extension then check if 1803 # it was added directly with one of vulkan versions 1804 apiVersion = compositeType.apiVersion 1805 if apiVersion is None: 1806 continue 1807 structureDetail.major = apiVersion.major 1808 structureDetail.minor = apiVersion.minor 1809 break 1810 # generate file content 1811 structureDefinitions = [] 1812 featureEnabledFlags = [] 1813 clearStructures = [] 1814 structureChain = [] 1815 logStructures = [] 1816 verifyStructures = [] 1817 for index, structureDetail in enumerate(testedStructureDetail): 1818 # create two instances of each structure 1819 nameSpacing = '\t' * int((55 - len(structureDetail.name)) / 4) 1820 structureDefinitions.append(structureDetail.name + nameSpacing + structureDetail.instanceName + '[count];') 1821 # create flags that check if proper extension or vulkan version is available 1822 condition = '' 1823 extension = structureDetail.extension 1824 major = structureDetail.major 1825 if extension is not None: 1826 condition = ' checkExtension(properties, "' + extension + '")' 1827 if major is not None: 1828 if condition != '': 1829 condition += '\t' * int((39 - len(extension)) / 4) + '|| ' 1830 else: 1831 condition += '\t' * 17 + ' ' 1832 condition += 'context.contextSupports(vk::ApiVersion(' + str(major) + ', ' + str(structureDetail.minor) + ', 0))' 1833 condition += ';' 1834 nameSpacing = '\t' * int((40 - len(structureDetail.flagName)) / 4) 1835 featureEnabledFlags.append('const bool ' + structureDetail.flagName + nameSpacing + '=' + condition) 1836 # clear memory of each structure 1837 nameSpacing = '\t' * int((43 - len(structureDetail.instanceName)) / 4) 1838 clearStructures.append('\tdeMemset(&' + structureDetail.instanceName + '[ndx],' + nameSpacing + '0xFF * ndx, sizeof(' + structureDetail.name + '));') 1839 # construct structure chain 1840 nextInstanceName = 'DE_NULL'; 1841 if index < len(testedStructureDetail)-1: 1842 nextInstanceName = '&' + testedStructureDetail[index+1].instanceName + '[ndx]' 1843 structureChain.append('\t' + structureDetail.instanceName + '[ndx].sType = ' + structureDetail.sType + ';') 1844 structureChain.append('\t' + structureDetail.instanceName + '[ndx].pNext = ' + nextInstanceName + ';\n') 1845 # construct log section 1846 logStructures.append('if (' + structureDetail.flagName + ')') 1847 logStructures.append('\tlog << TestLog::Message << ' + structureDetail.instanceName + '[0] << TestLog::EndMessage;') 1848 #construct verification section 1849 verifyStructures.append('if (' + structureDetail.flagName + ' &&') 1850 for index, m in enumerate(structureDetail.members): 1851 prefix = '\t(' if index == 0 else '\t ' 1852 postfix = '))' if index == len(structureDetail.members)-1 else ' ||' 1853 verifyStructures.append(prefix + structureDetail.instanceName + '[0].' + m + ' != ' + structureDetail.instanceName + '[1].' + m + postfix) 1854 verifyStructures.append('{\n\t\tTCU_FAIL("Mismatch between ' + structureDetail.name + '");\n}') 1855 # construct file content 1856 stream = [] 1857 stream.extend(structureDefinitions) 1858 stream.append('') 1859 stream.extend(featureEnabledFlags) 1860 stream.append('\nfor (int ndx = 0; ndx < count; ++ndx)\n{') 1861 stream.extend(clearStructures) 1862 stream.append('') 1863 stream.extend(structureChain) 1864 stream.append('\tdeMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));\n' 1865 '\textFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;\n' 1866 '\textFeatures.pNext = &' + testedStructureDetail[0].instanceName + '[ndx];\n' 1867 '\tvki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);\n}\n') 1868 stream.extend(logStructures) 1869 stream.append('') 1870 stream.extend(verifyStructures) 1871 writeInlFile(filename, INL_HEADER, stream) 1872 1873def generateDeviceFeaturesDefs(src): 1874 # look for definitions 1875 ptrnSType = r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_FEATURES(\w*)\s*=' 1876 matches = re.findall(ptrnSType, src, re.M) 1877 matches = sorted(matches, key=lambda m: m[0]) 1878 # construct final list 1879 defs = [] 1880 for sType, sSuffix in matches: 1881 structName = re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '') 1882 ptrnStructName = r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Features' + sSuffix.replace('_', '') + ')' 1883 matchStructName = re.search(ptrnStructName, src, re.IGNORECASE) 1884 if matchStructName: 1885 # handle special cases 1886 if sType == "EXCLUSIVE_SCISSOR": 1887 sType = "SCISSOR_EXCLUSIVE" 1888 elif sType == "ASTC_DECODE": 1889 sType = "ASTC_DECODE_MODE" 1890 if sType in {'VULKAN_1_1', 'VULKAN_1_2'}: 1891 continue 1892 # end handling special cases 1893 ptrnExtensionName = r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_EXTENSION_NAME).+$' 1894 matchExtensionName = re.search(ptrnExtensionName, src, re.M) 1895 ptrnSpecVersion = r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_SPEC_VERSION).+$' 1896 matchSpecVersion = re.search(ptrnSpecVersion, src, re.M) 1897 defs.append( (sType, '', sSuffix, matchStructName.group(1), \ 1898 matchExtensionName.group(0) if matchExtensionName else None, 1899 matchExtensionName.group(1) if matchExtensionName else None, 1900 matchSpecVersion.group(1) if matchSpecVersion else '0') ) 1901 return defs 1902 1903def generateDevicePropertiesDefs(src): 1904 # look for definitions 1905 ptrnSType = r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_PROPERTIES(\w*)\s*=' 1906 matches = re.findall(ptrnSType, src, re.M) 1907 matches = sorted(matches, key=lambda m: m[0]) 1908 # construct final list 1909 defs = [] 1910 for sType, sSuffix in matches: 1911 # handle special cases 1912 if sType in {'VULKAN_1_1', 'VULKAN_1_2', 'GROUP', 'MEMORY_BUDGET', 'MEMORY', 'TOOL'}: 1913 continue 1914 # there are cases like VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD 1915 # where 2 is after PROPERTIES - to handle this we need to split suffix to two parts 1916 sVerSuffix = '' 1917 sExtSuffix = sSuffix 1918 suffixStart = sSuffix.rfind('_') 1919 if suffixStart > 0: 1920 sVerSuffix = sSuffix[:suffixStart] 1921 sExtSuffix = sSuffix[suffixStart:] 1922 # handle special case 1923 if sType == "ID": 1924 structName = sType 1925 else: 1926 structName = re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '') 1927 ptrnStructName = r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Properties' + sSuffix.replace('_', '') + ')' 1928 matchStructName = re.search(ptrnStructName, src, re.M) 1929 if matchStructName: 1930 extType = sType 1931 if extType == "MAINTENANCE_3": 1932 extType = "MAINTENANCE3" 1933 elif extType == "DISCARD_RECTANGLE": 1934 extType = "DISCARD_RECTANGLES" 1935 elif extType == "DRIVER": 1936 extType = "DRIVER_PROPERTIES" 1937 elif extType == "POINT_CLIPPING": 1938 extType = "MAINTENANCE2" 1939 elif extType == "SHADER_CORE": 1940 extType = "SHADER_CORE_PROPERTIES" 1941 # end handling special cases 1942 ptrnExtensionName = r'^\s*#define\s+(\w+' + sExtSuffix + '_' + extType + sVerSuffix +'[_0-9]*_EXTENSION_NAME).+$' 1943 matchExtensionName = re.search(ptrnExtensionName, src, re.M) 1944 ptrnSpecVersion = r'^\s*#define\s+(\w+' + sExtSuffix + '_' + extType + sVerSuffix + '[_0-9]*_SPEC_VERSION).+$' 1945 matchSpecVersion = re.search(ptrnSpecVersion, src, re.M) 1946 defs.append( (sType, sVerSuffix, sExtSuffix, matchStructName.group(1), \ 1947 matchExtensionName.group(0) if matchExtensionName else None, 1948 matchExtensionName.group(1) if matchExtensionName else None, 1949 matchSpecVersion.group (1) if matchSpecVersion else '0') ) 1950 return defs 1951 1952def writeDeviceFeatures(api, dfDefs, filename): 1953 # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs 1954 # and construct dictionary with all of their attributes 1955 blobMembers = {} 1956 blobStructs = {} 1957 blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$") 1958 for structureType in api.compositeTypes: 1959 match = blobPattern.match(structureType.name) 1960 if match: 1961 allMembers = [member.name for member in structureType.members] 1962 vkVersion = match.group(1) 1963 blobMembers[vkVersion] = allMembers[2:] 1964 blobStructs[vkVersion] = set() 1965 initFromBlobDefinitions = [] 1966 emptyInitDefinitions = [] 1967 # iterate over all feature structures 1968 allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*") 1969 nonExtFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*$") 1970 for structureType in api.compositeTypes: 1971 # skip structures that are not feature structures 1972 if not allFeaturesPattern.match(structureType.name): 1973 continue 1974 # skip structures that were previously identified as blobs 1975 if blobPattern.match(structureType.name): 1976 continue 1977 if structureType.isAlias: 1978 continue 1979 # skip sType and pNext and just grab third and next attributes 1980 structureMembers = structureType.members[2:] 1981 notPartOfBlob = True 1982 if nonExtFeaturesPattern.match(structureType.name): 1983 # check if this member is part of any of the blobs 1984 for blobName, blobMemberList in blobMembers.items(): 1985 # if just one member is not part of this blob go to the next blob 1986 # (we asume that all members are part of blob - no need to check all) 1987 if structureMembers[0].name not in blobMemberList: 1988 continue 1989 # add another feature structure name to this blob 1990 blobStructs[blobName].add(structureType) 1991 # add specialization for this feature structure 1992 memberCopying = "" 1993 for member in structureMembers: 1994 memberCopying += "\tfeatureType.{0} = allFeaturesBlobs.vk{1}.{0};\n".format(member.name, blobName) 1995 wholeFunction = \ 1996 "template<> void initFeatureFromBlob<{0}>({0}& featureType, const AllFeaturesBlobs& allFeaturesBlobs)\n" \ 1997 "{{\n" \ 1998 "{1}" \ 1999 "}}".format(structureType.name, memberCopying) 2000 initFromBlobDefinitions.append(wholeFunction) 2001 notPartOfBlob = False 2002 # assuming that all members are part of blob, goto next 2003 break 2004 # add empty template definition as on Fedora there are issue with 2005 # linking using just generic template - all specializations are needed 2006 if notPartOfBlob: 2007 emptyFunction = "template<> void initFeatureFromBlob<{0}>({0}&, const AllFeaturesBlobs&) {{}}" 2008 emptyInitDefinitions.append(emptyFunction.format(structureType.name)) 2009 extensionDefines = [] 2010 makeFeatureDescDefinitions = [] 2011 featureStructWrappers = [] 2012 for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extLine, extName, specVer) in enumerate(dfDefs): 2013 extensionNameDefinition = extName 2014 if not extensionNameDefinition: 2015 extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType) 2016 # construct defines with names 2017 if extLine: 2018 extensionDefines.append(extLine) 2019 else: 2020 extensionDefines.append('#define {0} "not_existent_feature"'.format(extensionNameDefinition)) 2021 # handle special cases 2022 if sType == "SCISSOR_EXCLUSIVE": 2023 sType = "EXCLUSIVE_SCISSOR" 2024 elif sType == "ASTC_DECODE_MODE": 2025 sType = "ASTC_DECODE" 2026 # end handling special cases 2027 # construct makeFeatureDesc template function definitions 2028 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sVerSuffix + sExtSuffix) 2029 makeFeatureDescDefinitions.append("template<> FeatureDesc makeFeatureDesc<{0}>(void) " \ 2030 "{{ return FeatureDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dfDefs)-idx)) 2031 # construct CreateFeatureStruct wrapper block 2032 featureStructWrappers.append("\t{{ createFeatureStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer)) 2033 # construct method that will check if structure sType is part of blob 2034 blobChecker = "bool isPartOfBlobFeatures (VkStructureType sType)\n{\n" \ 2035 "\tconst std::vector<VkStructureType> sTypeVect =" \ 2036 "\t{\n" 2037 # iterate over blobs with list of structures 2038 for blobName in sorted(blobStructs.keys()): 2039 blobChecker += "\t\t// Vulkan{0}\n".format(blobName) 2040 # iterate over all feature structures in current blob 2041 structuresList = list(blobStructs[blobName]) 2042 structuresList = sorted(structuresList, key=lambda s: s.name) 2043 for structType in structuresList: 2044 # find definition of this structure in dfDefs 2045 structName = structType.name 2046 # handle special cases 2047 if structName == 'VkPhysicalDeviceShaderDrawParameterFeatures': 2048 structName = 'VkPhysicalDeviceShaderDrawParametersFeatures' 2049 # end handling special cases 2050 structDef = [s for s in dfDefs if s[3] == structName][0] 2051 sType = structDef[0] 2052 sSuffix = structDef[1] + structDef[2] 2053 # handle special cases 2054 if sType == "SCISSOR_EXCLUSIVE": 2055 sType = "EXCLUSIVE_SCISSOR" 2056 # end handling special cases 2057 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sSuffix) 2058 blobChecker += "\t\t{0},\n".format(sTypeName) 2059 blobChecker += "\t};\n" \ 2060 "\treturn de::contains(sTypeVect.begin(), sTypeVect.end(), sType);\n" \ 2061 "}\n" 2062 # combine all definition lists 2063 stream = [ 2064 '#include "vkDeviceFeatures.hpp"\n', 2065 'namespace vk\n{'] 2066 stream.extend(extensionDefines) 2067 stream.append('\n') 2068 stream.extend(initFromBlobDefinitions) 2069 stream.append('\n// generic template is not enough for some compilers') 2070 stream.extend(emptyInitDefinitions) 2071 stream.append('\n') 2072 stream.extend(makeFeatureDescDefinitions) 2073 stream.append('\n') 2074 stream.append('static const FeatureStructCreationData featureStructCreationArray[] =\n{') 2075 stream.extend(featureStructWrappers) 2076 stream.append('};\n') 2077 stream.append(blobChecker) 2078 stream.append('} // vk\n') 2079 writeInlFile(filename, INL_HEADER, stream) 2080 2081def writeDeviceProperties(api, dpDefs, filename): 2082 # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs 2083 # and construct dictionary with all of their attributes 2084 blobMembers = {} 2085 blobStructs = {} 2086 blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Properties[0-9]*$") 2087 for structureType in api.compositeTypes: 2088 match = blobPattern.match(structureType.name) 2089 if match: 2090 allMembers = [member.name for member in structureType.members] 2091 vkVersion = match.group(1) 2092 blobMembers[vkVersion] = allMembers[2:] 2093 blobStructs[vkVersion] = set() 2094 initFromBlobDefinitions = [] 2095 emptyInitDefinitions = [] 2096 # iterate over all property structures 2097 allPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*") 2098 nonExtPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*$") 2099 for structureType in api.compositeTypes: 2100 # skip structures that are not property structures 2101 if not allPropertiesPattern.match(structureType.name): 2102 continue 2103 # skip structures that were previously identified as blobs 2104 if blobPattern.match(structureType.name): 2105 continue 2106 if structureType.isAlias: 2107 continue 2108 # skip sType and pNext and just grab third and next attributes 2109 structureMembers = structureType.members[2:] 2110 notPartOfBlob = True 2111 if nonExtPropertiesPattern.match(structureType.name): 2112 # check if this member is part of any of the blobs 2113 for blobName, blobMemberList in blobMembers.items(): 2114 # if just one member is not part of this blob go to the next blob 2115 # (we asume that all members are part of blob - no need to check all) 2116 if structureMembers[0].name not in blobMemberList: 2117 continue 2118 # add another property structure name to this blob 2119 blobStructs[blobName].add(structureType) 2120 # add specialization for this property structure 2121 memberCopying = "" 2122 for member in structureMembers: 2123 if not member.arraySize: 2124 # handle special case 2125 if structureType.name == "VkPhysicalDeviceSubgroupProperties" and "subgroup" not in member.name : 2126 blobMemberName = "subgroup" + member.name[0].capitalize() + member.name[1:] 2127 memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{2};\n".format(member.name, blobName, blobMemberName) 2128 # end handling special case 2129 else: 2130 memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{0};\n".format(member.name, blobName) 2131 else: 2132 memberCopying += "\tmemcpy(propertyType.{0}, allPropertiesBlobs.vk{1}.{0}, sizeof({2}) * {3});\n".format(member.name, blobName, member.type[0], member.arraySize[1:-1]) 2133 wholeFunction = \ 2134 "template<> void initPropertyFromBlob<{0}>({0}& propertyType, const AllPropertiesBlobs& allPropertiesBlobs)\n" \ 2135 "{{\n" \ 2136 "{1}" \ 2137 "}}".format(structureType.name, memberCopying) 2138 initFromBlobDefinitions.append(wholeFunction) 2139 notPartOfBlob = False 2140 # assuming that all members are part of blob, goto next 2141 break 2142 # add empty template definition as on Fedora there are issue with 2143 # linking using just generic template - all specializations are needed 2144 if notPartOfBlob: 2145 emptyFunction = "template<> void initPropertyFromBlob<{0}>({0}&, const AllPropertiesBlobs&) {{}}" 2146 emptyInitDefinitions.append(emptyFunction.format(structureType.name)) 2147 extensionDefines = [] 2148 makePropertyDescDefinitions = [] 2149 propertyStructWrappers = [] 2150 for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extLine, extName, specVer) in enumerate(dpDefs): 2151 extensionNameDefinition = extName 2152 if not extensionNameDefinition: 2153 extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType) 2154 # construct defines with names 2155 if extLine: 2156 extensionDefines.append(extLine) 2157 else: 2158 extensionDefines.append('#define {0} "core_property"'.format(extensionNameDefinition)) 2159 # construct makePropertyDesc template function definitions 2160 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sVerSuffix + sExtSuffix) 2161 makePropertyDescDefinitions.append("template<> PropertyDesc makePropertyDesc<{0}>(void) " \ 2162 "{{ return PropertyDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dpDefs)-idx)) 2163 # construct CreateProperty struct wrapper block 2164 propertyStructWrappers.append("\t{{ createPropertyStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer)) 2165 # construct method that will check if structure sType is part of blob 2166 blobChecker = "bool isPartOfBlobProperties (VkStructureType sType)\n{\n" \ 2167 "\tconst std::vector<VkStructureType> sTypeVect =" \ 2168 "\t{\n" 2169 # iterate over blobs with list of structures 2170 for blobName in sorted(blobStructs.keys()): 2171 blobChecker += "\t\t// Vulkan{0}\n".format(blobName) 2172 # iterate over all feature structures in current blob 2173 structuresList = list(blobStructs[blobName]) 2174 structuresList = sorted(structuresList, key=lambda s: s.name) 2175 for structType in structuresList: 2176 # find definition of this structure in dpDefs 2177 structName = structType.name 2178 structDef = [s for s in dpDefs if s[3] == structName][0] 2179 sType = structDef[0] 2180 sSuffix = structDef[1] + structDef[2] 2181 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sSuffix) 2182 blobChecker += "\t\t{0},\n".format(sTypeName) 2183 blobChecker += "\t};\n" \ 2184 "\treturn de::contains(sTypeVect.begin(), sTypeVect.end(), sType);\n" \ 2185 "}\n" 2186 # combine all definition lists 2187 stream = [ 2188 '#include "vkDeviceProperties.hpp"\n', 2189 'namespace vk\n{'] 2190 stream.extend(extensionDefines) 2191 stream.append('\n') 2192 stream.extend(initFromBlobDefinitions) 2193 stream.append('\n// generic template is not enough for some compilers') 2194 stream.extend(emptyInitDefinitions) 2195 stream.append('\n') 2196 stream.extend(makePropertyDescDefinitions) 2197 stream.append('\n') 2198 stream.append('static const PropertyStructCreationData propertyStructCreationArray[] =\n{') 2199 stream.extend(propertyStructWrappers) 2200 stream.append('};\n') 2201 stream.append(blobChecker) 2202 stream.append('} // vk\n') 2203 writeInlFile(filename, INL_HEADER, stream) 2204 2205def genericDeviceFeaturesWriter(dfDefs, pattern, filename): 2206 stream = [] 2207 for _, _, _, extStruct, _, _, _ in dfDefs: 2208 nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "") 2209 stream.append(pattern.format(extStruct, nameSubStr)) 2210 writeInlFile(filename, INL_HEADER, indentLines(stream)) 2211 2212def writeDeviceFeaturesDefaultDeviceDefs(dfDefs, filename): 2213 pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceFeatures.getFeatureType<{0}>();\t}}" 2214 genericDeviceFeaturesWriter(dfDefs, pattern, filename) 2215 2216def writeDeviceFeaturesContextDecl(dfDefs, filename): 2217 pattern = "const vk::{0}&\tget{1}\t(void) const;" 2218 genericDeviceFeaturesWriter(dfDefs, pattern, filename) 2219 2220def writeDeviceFeaturesContextDefs(dfDefs, filename): 2221 pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}" 2222 genericDeviceFeaturesWriter(dfDefs, pattern, filename) 2223 2224def genericDevicePropertiesWriter(dfDefs, pattern, filename): 2225 stream = [] 2226 for _, _, _, extStruct, _, _, _ in dfDefs: 2227 nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "") 2228 if extStruct == "VkPhysicalDeviceRayTracingPropertiesNV": 2229 nameSubStr += "NV" 2230 stream.append(pattern.format(extStruct, nameSubStr)) 2231 writeInlFile(filename, INL_HEADER, indentLines(stream)) 2232 2233def writeDevicePropertiesDefaultDeviceDefs(dfDefs, filename): 2234 pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceProperties.getPropertyType<{0}>();\t}}" 2235 genericDevicePropertiesWriter(dfDefs, pattern, filename) 2236 2237def writeDevicePropertiesContextDecl(dfDefs, filename): 2238 pattern = "const vk::{0}&\tget{1}\t(void) const;" 2239 genericDevicePropertiesWriter(dfDefs, pattern, filename) 2240 2241def writeDevicePropertiesContextDefs(dfDefs, filename): 2242 pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}" 2243 genericDevicePropertiesWriter(dfDefs, pattern, filename) 2244 2245def splitWithQuotation(line): 2246 result = [] 2247 splitted = re.findall(r'[^"\s]\S*|".+?"', line) 2248 for s in splitted: 2249 result.append(s.replace('"', '')) 2250 return result 2251 2252def writeMandatoryFeatures(filename): 2253 stream = [] 2254 pattern = r'\s*([\w]+)\s+FEATURES\s+\((.*)\)\s+REQUIREMENTS\s+\((.*)\)' 2255 mandatoryFeatures = readFile(os.path.join(VULKAN_H_DIR, "mandatory_features.txt")) 2256 matches = re.findall(pattern, mandatoryFeatures) 2257 dictStructs = {} 2258 dictData = [] 2259 for m in matches: 2260 allRequirements = splitWithQuotation(m[2]) 2261 dictData.append( [ m[0], m[1].strip(), allRequirements ] ) 2262 if m[0] != 'VkPhysicalDeviceFeatures' : 2263 if (m[0] not in dictStructs): 2264 dictStructs[m[0]] = [m[0][2:3].lower() + m[0][3:]] 2265 if (allRequirements[0]): 2266 if (allRequirements[0] not in dictStructs[m[0]][1:]): 2267 dictStructs[m[0]].append(allRequirements[0]) 2268 2269 stream.extend(['bool checkMandatoryFeatures(const vkt::Context& context)\n{', 2270 '\tif (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))', 2271 '\t\tTCU_THROW(NotSupportedError, "Extension VK_KHR_get_physical_device_properties2 is not present");', 2272 '', 2273 '\tVkPhysicalDevice\t\t\t\t\tphysicalDevice\t\t= context.getPhysicalDevice();', 2274 '\tconst InstanceInterface&\t\t\tvki\t\t\t\t\t= context.getInstanceInterface();', 2275 '\tconst vector<VkExtensionProperties>\tdeviceExtensions\t= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);', 2276 '', 2277 '\ttcu::TestLog& log = context.getTestContext().getLog();', 2278 '\tvk::VkPhysicalDeviceFeatures2 coreFeatures;', 2279 '\tdeMemset(&coreFeatures, 0, sizeof(coreFeatures));', 2280 '\tcoreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;', 2281 '\tvoid** nextPtr = &coreFeatures.pNext;', 2282 '']) 2283 2284 listStruct = sorted(dictStructs.items(), key=lambda tup: tup[0]) # sort to have same results for py2 and py3 2285 for k, v in listStruct: 2286 if (v[1].startswith("ApiVersion")): 2287 cond = '\tif (context.contextSupports(vk::' + v[1] + '))' 2288 else: 2289 cond = '\tif (vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "' + v[1] + '"))' 2290 stream.extend(['\tvk::' + k + ' ' + v[0]+ ';', 2291 '\tdeMemset(&' + v[0] + ', 0, sizeof(' + v[0] + '));', 2292 '']) 2293 reqs = v[1:] 2294 if len(reqs) > 0 : 2295 cond = 'if ( ' 2296 for i, req in enumerate(reqs) : 2297 if (req.startswith("ApiVersion")): 2298 cond = cond + 'context.contextSupports(vk::' + req + ')' 2299 else: 2300 cond = cond + 'isExtensionSupported(deviceExtensions, RequiredExtension("' + req + '"))' 2301 if i+1 < len(reqs) : 2302 cond = cond + ' || ' 2303 cond = cond + ' )' 2304 stream.append('\t' + cond) 2305 stream.extend(['\t{', 2306 '\t\t' + v[0] + '.sType = getStructureType<' + k + '>();', 2307 '\t\t*nextPtr = &' + v[0] + ';', 2308 '\t\tnextPtr = &' + v[0] + '.pNext;', 2309 '\t}', 2310 '']) 2311 stream.extend(['\tcontext.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &coreFeatures);', 2312 '\tbool result = true;', 2313 '']) 2314 2315 for v in dictData: 2316 structType = v[0]; 2317 structName = 'coreFeatures.features'; 2318 if v[0] != 'VkPhysicalDeviceFeatures' : 2319 structName = dictStructs[v[0]][0] 2320 if len(v[2]) > 0 : 2321 condition = 'if ( ' 2322 for i, req in enumerate(v[2]) : 2323 if (req.startswith("ApiVersion")): 2324 condition = condition + 'context.contextSupports(vk::' + req + ')' 2325 elif '.' in req: 2326 condition = condition + req 2327 else: 2328 condition = condition + 'isExtensionSupported(deviceExtensions, RequiredExtension("' + req + '"))' 2329 if i+1 < len(v[2]) : 2330 condition = condition + ' && ' 2331 condition = condition + ' )' 2332 stream.append('\t' + condition) 2333 stream.append('\t{') 2334 # Don't need to support an AND case since that would just be another line in the .txt 2335 if len(v[1].split(" ")) == 1: 2336 stream.append('\t\tif ( ' + structName + '.' + v[1] + ' == VK_FALSE )') 2337 else: 2338 condition = 'if ( ' 2339 for i, feature in enumerate(v[1].split(" ")): 2340 if i != 0: 2341 condition = condition + ' && ' 2342 condition = condition + '( ' + structName + '.' + feature + ' == VK_FALSE )' 2343 condition = condition + ' )' 2344 stream.append('\t\t' + condition) 2345 featureSet = v[1].replace(" ", " or ") 2346 stream.extend(['\t\t{', 2347 '\t\t\tlog << tcu::TestLog::Message << "Mandatory feature ' + featureSet + ' not supported" << tcu::TestLog::EndMessage;', 2348 '\t\t\tresult = false;', 2349 '\t\t}', 2350 '\t}', 2351 '']) 2352 stream.append('\treturn result;') 2353 stream.append('}\n') 2354 writeInlFile(filename, INL_HEADER, stream) 2355 2356def writeExtensionList(filename, patternPart): 2357 stream = [] 2358 stream.append('static const char* s_allowed{0}KhrExtensions[] =\n{{'.format(patternPart.title())) 2359 extensionsData = readFile(os.path.join(VULKAN_H_DIR, "extensions_data.txt")) 2360 pattern = r'\s*([^\s]+)\s+{0}\s*[0-9_]*'.format(patternPart) 2361 matches = re.findall(pattern, extensionsData) 2362 for m in matches: 2363 stream.append('\t"' + m + '",') 2364 stream.append('};\n') 2365 writeInlFile(filename, INL_HEADER, stream) 2366 2367def preprocessTopInclude(src, dir): 2368 pattern = r'#include\s+"([^\n]+)"' 2369 while True: 2370 inc = re.search(pattern, src) 2371 if inc is None: 2372 return src 2373 incFileName = inc.string[inc.start(1):inc.end(1)] 2374 patternIncNamed = r'#include\s+"' + incFileName + '"' 2375 incBody = readFile(os.path.join(dir, incFileName)) if incFileName != 'vk_platform.h' else '' 2376 incBodySanitized = re.sub(pattern, '', incBody) 2377 bodyEndSanitized = re.sub(patternIncNamed, '', src[inc.end(0):]) 2378 src = src[0:inc.start(0)] + incBodySanitized + bodyEndSanitized 2379 return src 2380 2381if __name__ == "__main__": 2382 # Read all .h files, with vulkan_core.h first 2383 files = os.listdir(VULKAN_H_DIR) 2384 files = [f for f in files if f.endswith(".h")] 2385 files.sort() 2386 files.remove("vulkan_core.h") 2387 first = ["vk_video/vulkan_video_codecs_common.h", "vulkan_core.h"] 2388 files = first + files 2389 2390 src = "" 2391 for file in files: 2392 src += preprocessTopInclude(readFile(os.path.join(VULKAN_H_DIR,file)), VULKAN_H_DIR) 2393 2394 src = re.sub('\s*//[^\n]*', '', src) 2395 src = re.sub('\n\n', '\n', src) 2396 2397 api = parseAPI(src) 2398 2399 platformFuncs = [Function.TYPE_PLATFORM] 2400 instanceFuncs = [Function.TYPE_INSTANCE] 2401 deviceFuncs = [Function.TYPE_DEVICE] 2402 2403 dfd = generateDeviceFeaturesDefs(src) 2404 writeDeviceFeatures (api, dfd, os.path.join(VULKAN_DIR, "vkDeviceFeatures.inl")) 2405 writeDeviceFeaturesDefaultDeviceDefs (dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForDefaultDeviceDefs.inl")) 2406 writeDeviceFeaturesContextDecl (dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForContextDecl.inl")) 2407 writeDeviceFeaturesContextDefs (dfd, os.path.join(VULKAN_DIR, "vkDeviceFeaturesForContextDefs.inl")) 2408 2409 dpd = generateDevicePropertiesDefs(src) 2410 writeDeviceProperties (api, dpd, os.path.join(VULKAN_DIR, "vkDeviceProperties.inl")) 2411 2412 writeDevicePropertiesDefaultDeviceDefs (dpd, os.path.join(VULKAN_DIR, "vkDevicePropertiesForDefaultDeviceDefs.inl")) 2413 writeDevicePropertiesContextDecl (dpd, os.path.join(VULKAN_DIR, "vkDevicePropertiesForContextDecl.inl")) 2414 writeDevicePropertiesContextDefs (dpd, os.path.join(VULKAN_DIR, "vkDevicePropertiesForContextDefs.inl")) 2415 2416 writeHandleType (api, os.path.join(VULKAN_DIR, "vkHandleType.inl")) 2417 writeBasicTypes (api, os.path.join(VULKAN_DIR, "vkBasicTypes.inl")) 2418 writeCompositeTypes (api, os.path.join(VULKAN_DIR, "vkStructTypes.inl")) 2419 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualPlatformInterface.inl"), platformFuncs, False) 2420 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualInstanceInterface.inl"), instanceFuncs, False) 2421 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualDeviceInterface.inl"), deviceFuncs, False) 2422 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcretePlatformInterface.inl"), platformFuncs, True) 2423 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteInstanceInterface.inl"), instanceFuncs, True) 2424 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteDeviceInterface.inl"), deviceFuncs, True) 2425 writeFunctionPtrTypes (api, os.path.join(VULKAN_DIR, "vkFunctionPointerTypes.inl")) 2426 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkPlatformFunctionPointers.inl"), platformFuncs) 2427 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInstanceFunctionPointers.inl"), instanceFuncs) 2428 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkDeviceFunctionPointers.inl"), deviceFuncs) 2429 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitPlatformFunctionPointers.inl"), platformFuncs, lambda f: f.name != "vkGetInstanceProcAddr") 2430 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitInstanceFunctionPointers.inl"), instanceFuncs) 2431 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitDeviceFunctionPointers.inl"), deviceFuncs) 2432 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkPlatformDriverImpl.inl"), platformFuncs, "PlatformDriver") 2433 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkInstanceDriverImpl.inl"), instanceFuncs, "InstanceDriver") 2434 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkDeviceDriverImpl.inl"), deviceFuncs, "DeviceDriver") 2435 writeStrUtilProto (api, os.path.join(VULKAN_DIR, "vkStrUtil.inl")) 2436 writeStrUtilImpl (api, os.path.join(VULKAN_DIR, "vkStrUtilImpl.inl")) 2437 writeRefUtilProto (api, os.path.join(VULKAN_DIR, "vkRefUtil.inl")) 2438 writeRefUtilImpl (api, os.path.join(VULKAN_DIR, "vkRefUtilImpl.inl")) 2439 writeStructTraitsImpl (api, os.path.join(VULKAN_DIR, "vkGetStructureTypeImpl.inl")) 2440 writeNullDriverImpl (api, os.path.join(VULKAN_DIR, "vkNullDriverImpl.inl")) 2441 writeTypeUtil (api, os.path.join(VULKAN_DIR, "vkTypeUtil.inl")) 2442 writeSupportedExtenions (api, os.path.join(VULKAN_DIR, "vkSupportedExtensions.inl")) 2443 writeCoreFunctionalities (api, os.path.join(VULKAN_DIR, "vkCoreFunctionalities.inl")) 2444 writeExtensionFunctions (api, os.path.join(VULKAN_DIR, "vkExtensionFunctions.inl")) 2445 writeDeviceFeatures2 (api, os.path.join(VULKAN_DIR, "vkDeviceFeatures2.inl")) 2446 writeMandatoryFeatures ( os.path.join(VULKAN_DIR, "vkMandatoryFeatures.inl")) 2447 writeExtensionList ( os.path.join(VULKAN_DIR, "vkInstanceExtensions.inl"), 'INSTANCE') 2448 writeExtensionList ( os.path.join(VULKAN_DIR, "vkDeviceExtensions.inl"), 'DEVICE') 2449 writeDriverIds ( os.path.join(VULKAN_DIR, "vkKnownDriverIds.inl")) 2450 writeObjTypeImpl (api, os.path.join(VULKAN_DIR, "vkObjTypeImpl.inl")) 2451