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