1 # -*- coding: utf-8 -*-
3 #-------------------------------------------------------------------------
7 # Copyright (c) 2015 Google Inc.
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
21 #-------------------------------------------------------------------------
29 from itertools import chain
30 from collections import OrderedDict
32 sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..", "scripts"))
34 from build.common import DEQP_DIR, execute
35 from khr_util.format import indentLines, writeInlFile
37 VULKAN_HEADERS_INCLUDE_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "vulkan-docs", "src", "include")
38 VULKAN_SRC_DIR = os.path.join(os.path.dirname(__file__), "src")
41 /* WARNING: This is auto-generated file. Do not modify, since changes will
42 * be lost! Modify the generating script instead.
43 * This file was generated by /scripts/gen_framework.py
48 ("VK_MAX_PHYSICAL_DEVICE_NAME_SIZE", "size_t"),
49 ("VK_MAX_EXTENSION_NAME_SIZE", "size_t"),
50 ("VK_MAX_DRIVER_NAME_SIZE", "size_t"),
51 ("VK_MAX_DRIVER_INFO_SIZE", "size_t"),
52 ("VK_UUID_SIZE", "size_t"),
53 ("VK_LUID_SIZE", "size_t"),
54 ("VK_MAX_MEMORY_TYPES", "size_t"),
55 ("VK_MAX_MEMORY_HEAPS", "size_t"),
56 ("VK_MAX_DESCRIPTION_SIZE", "size_t"),
57 ("VK_MAX_DEVICE_GROUP_SIZE", "size_t"),
58 ("VK_ATTACHMENT_UNUSED", "uint32_t"),
59 ("VK_SUBPASS_EXTERNAL", "uint32_t"),
60 ("VK_QUEUE_FAMILY_IGNORED", "uint32_t"),
61 ("VK_QUEUE_FAMILY_EXTERNAL", "uint32_t"),
62 ("VK_REMAINING_MIP_LEVELS", "uint32_t"),
63 ("VK_REMAINING_ARRAY_LAYERS", "uint32_t"),
64 ("VK_WHOLE_SIZE", "vk::VkDeviceSize"),
65 ("VK_TRUE", "vk::VkBool32"),
66 ("VK_FALSE", "vk::VkBool32"),
71 (["Display","*"], ["XlibDisplayPtr"], "void*"),
72 (["Window"], ["XlibWindow"], "uintptr_t",),
73 (["VisualID"], ["XlibVisualID"], "uint32_t"),
76 (["xcb_connection_t", "*"], ["XcbConnectionPtr"], "void*"),
77 (["xcb_window_t"], ["XcbWindow"], "uintptr_t"),
78 (["xcb_visualid_t"], ["XcbVisualid"], "uint32_t"),
80 # VK_KHR_wayland_surface
81 (["struct", "wl_display","*"], ["WaylandDisplayPtr"], "void*"),
82 (["struct", "wl_surface", "*"], ["WaylandSurfacePtr"], "void*"),
85 (["MirConnection", "*"], ["MirConnectionPtr"], "void*"),
86 (["MirSurface", "*"], ["MirSurfacePtr"], "void*"),
88 # VK_KHR_android_surface
89 (["ANativeWindow", "*"], ["AndroidNativeWindowPtr"], "void*"),
91 # VK_KHR_win32_surface
92 (["HINSTANCE"], ["Win32InstanceHandle"], "void*"),
93 (["HWND"], ["Win32WindowHandle"], "void*"),
94 (["HANDLE"], ["Win32Handle"], "void*"),
95 (["const", "SECURITY_ATTRIBUTES", "*"], ["Win32SecurityAttributesPtr"], "const void*"),
96 (["AHardwareBuffer", "*"], ["AndroidHardwareBufferPtr"], "void*"),
97 (["HMONITOR"], ["Win32MonitorHandle"], "void*"),
98 (["LPCWSTR"], ["Win32LPCWSTR"], "const void*"),
100 # VK_EXT_acquire_xlib_display
101 (["RROutput"], ["RROutput"], "void*"),
103 (["zx_handle_t"], ["zx_handle_t"], "uint32_t"),
104 (["GgpFrameToken"], ["GgpFrameToken"], "int32_t"),
105 (["GgpStreamDescriptor"], ["GgpStreamDescriptor"], "int32_t"),
106 (["CAMetalLayer"], ["CAMetalLayer"], "void*"),
109 PLATFORM_TYPE_NAMESPACE = "pt"
111 TYPE_SUBSTITUTIONS = [
113 ("DWORD", "uint32_t"),
114 ("HANDLE*", PLATFORM_TYPE_NAMESPACE + "::" + "Win32Handle*"),
117 EXTENSION_POSTFIXES = ["KHR", "EXT", "NV", "NVX", "KHX", "NN", "MVK", "FUCHSIA", "GGP", "AMD", "QNX"]
118 EXTENSION_POSTFIXES_STANDARD = ["KHR", "EXT"]
120 def prefixName (prefix, name):
121 name = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', name[2:])
122 name = re.sub(r'([a-zA-Z])([0-9])', r'\1_\2', name)
125 name = name.replace("YCB_CR_", "YCBCR_")
126 name = name.replace("WIN_32_", "WIN32_")
127 name = name.replace("8_BIT_", "8BIT_")
128 name = name.replace("16_BIT_", "16BIT_")
129 name = name.replace("INT_64_", "INT64_")
130 name = name.replace("D_3_D_12_", "D3D12_")
131 name = name.replace("IOSSURFACE_", "IOS_SURFACE_")
132 name = name.replace("MAC_OS", "MACOS_")
133 name = name.replace("TEXTURE_LOD", "TEXTURE_LOD_")
134 name = name.replace("VIEWPORT_W", "VIEWPORT_W_")
135 name = name.replace("_IDPROPERTIES", "_ID_PROPERTIES")
136 name = name.replace("PHYSICAL_DEVICE_SHADER_FLOAT_16_INT_8_FEATURES", "PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES")
137 name = name.replace("PHYSICAL_DEVICE_RGBA_10_X_6_FORMATS_FEATURES_EXT", "PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT")
138 name = name.replace("_PCIBUS_", "_PCI_BUS_")
139 name = name.replace("ASTCD", "ASTC_D")
140 name = name.replace("AABBNV", "AABB_NV")
141 name = name.replace("IMAGE_PIPE", "IMAGEPIPE")
142 name = name.replace("SMBUILTINS", "SM_BUILTINS")
143 name = name.replace("ASTCHDRFEATURES", "ASTC_HDR_FEATURES")
144 name = name.replace("UINT_8", "UINT8")
145 name = name.replace("VULKAN_11_FEATURES", "VULKAN_1_1_FEATURES")
146 name = name.replace("VULKAN_11_PROPERTIES", "VULKAN_1_1_PROPERTIES")
147 name = name.replace("VULKAN_12_FEATURES", "VULKAN_1_2_FEATURES")
148 name = name.replace("VULKAN_12_PROPERTIES", "VULKAN_1_2_PROPERTIES")
149 name = name.replace("VULKAN_13_FEATURES", "VULKAN_1_3_FEATURES")
150 name = name.replace("VULKAN_13_PROPERTIES", "VULKAN_1_3_PROPERTIES")
151 name = name.replace("INT_8_", "INT8_")
152 name = name.replace("AABBNV", "AABB_NV")
153 name = name.replace("_H_264_", "_H264_")
154 name = name.replace("_H_265_", "_H265_")
155 name = name.replace("RDMAFEATURES", "RDMA_FEATURES")
156 name = name.replace("RGBA_10_X_6", "RGBA10X6")
157 name = name.replace("2_D", "2D_")
158 name = name.replace("3_D", "3D_")
163 def __init__ (self, versionTuple):
164 self.major = versionTuple[0]
165 self.minor = versionTuple[1]
166 self.patch = versionTuple[2]
170 return "VK_API_VERSION_%d_%d" % (self.major, self.minor)
171 return '0x%Xu' % (hash(self))
173 def isStandardVersion (self):
180 def getBestRepresentation (self):
181 if self.isStandardVersion():
182 return self.getInHex()
183 return self.getDefineName()
185 def getDefineName (self):
186 return 'VERSION_%d_%d_%d' % (self.major, self.minor, self.patch)
189 return (self.major << 22) | (self.minor << 12) | self.patch
191 def __eq__ (self, other):
192 return self.major == other.major and self.minor == other.minor and self.patch == other.patch
195 return self.getBestRepresentation()
202 def __init__ (self, type, name):
208 def getHandleType (self):
209 return prefixName("HANDLE_TYPE_", self.name)
211 def checkAliasValidity (self):
215 return '%s (%s, %s)' % (self.name, self.alias, self.isAlias)
218 def __init__ (self, type, name, value):
226 return '%s = %s (%s)' % (self.name, self.value, self.type)
229 def __init__ (self, name, values):
235 def checkAliasValidity (self):
236 if self.alias != None:
237 if len(self.values) != len(self.alias.values):
238 raise Exception("%s has different number of flags than its alias %s." % (self.name, self.alias.name))
239 for index, value in enumerate(self.values):
240 aliasVal = self.alias.values[index]
241 if value[1] != aliasVal[1] or not (value[0].startswith(aliasVal[0]) or aliasVal[0].startswith(value[0])):
242 raise Exception("Flag %s of %s has different value than %s of %s." % (self.alias.values[index], self.alias.name, value, self.name))
245 return '%s (%s) %s' % (self.name, self.alias, self.values)
248 def __init__ (self, name, values):
254 def checkAliasValidity (self):
255 if self.alias != None:
256 if len(self.values) != len(self.alias.values):
257 raise Exception("%s has different number of flags than its alias %s." % (self.name, self.alias.name))
258 for index, value in enumerate(self.values):
259 aliasVal = self.alias.values[index]
260 if value[1] != aliasVal[1] or not (value[0].startswith(aliasVal[0]) or aliasVal[0].startswith(value[0])):
261 raise Exception("Flag %s of %s has different value than %s of %s." % (self.alias.values[index], self.alias.name, value, self.name))
264 return '%s (%s)' % (self.name, self.alias)
267 def __init__ (self, type, name, arraySizeOrFieldWidth):
268 type = type.replace('*',' *').replace('&',' &')
269 for src, dst in TYPE_SUBSTITUTIONS:
270 type = type.replace(src, dst)
271 self.type = type.split(' ')
272 for platformType, substitute, compat in PLATFORM_TYPES:
273 range = self.contains(self.type, platformType)
275 self.type = self.type[:range[0]]+[PLATFORM_TYPE_NAMESPACE + '::' + substitute[0]] + substitute[1:] + self.type[range[1]:]
278 if len(arraySizeOrFieldWidth) > 0 and arraySizeOrFieldWidth[0] == ':':
280 self.fieldWidth = arraySizeOrFieldWidth
282 self.arraySize = arraySizeOrFieldWidth
285 def contains(self, big, small):
286 for i in range(len(big)-len(small)+1):
287 for j in range(len(small)):
288 if big[i+j] != small[j]:
291 return i, i+len(small)
295 return ' '.join(self.type).replace(' *','*').replace(' &','&')
297 def getAsString (self, separator):
298 return '%s%s%s%s%s' % (self.getType(), separator, self.name, self.arraySize, self.fieldWidth)
300 def getAsStringForArgumentList (self, separator):
301 return '%s%s%s%s' % (self.getType(), separator, self.name, self.arraySize)
304 return '<%s> <%s> <%s>' % (self.type, self.name, self.arraySize)
306 def __eq__ (self, other):
307 if len(self.type) != len(other.type):
309 for index, type in enumerate(self.type):
310 if "*" == type or "&" == type or "const" == type or "volatile" == type:
311 if type != other.type[index]:
313 elif type != other.type[index] and \
314 type not in map(lambda ext: other.type[index] + ext, EXTENSION_POSTFIXES_STANDARD) and \
315 other.type[index] not in map(lambda ext: type + ext, EXTENSION_POSTFIXES_STANDARD):
317 return self.arraySize == other.arraySize
319 def __ne__ (self, other):
320 return not self == other
326 def __init__ (self, typeClass, name, members, apiVersion = None):
327 self.typeClass = typeClass
329 self.members = members
332 self.apiVersion = apiVersion
334 def getClassName (self):
335 names = {CompositeType.CLASS_STRUCT: 'struct', CompositeType.CLASS_UNION: 'union'}
336 return names[self.typeClass]
338 def checkAliasValidity (self):
339 if self.alias != None:
340 if len(self.members) != len(self.alias.members):
341 raise Exception("%s has different number of members than its alias %s." % (self.name, self.alias.name))
342 for index, member in enumerate(self.members ):
344 #if member != self.alias.members[index]:
345 #raise Exception("Member %s of %s is different than core member %s in %s." % (self.alias.members[index], self.alias.name, member, self.name))
346 #raise Exception("Member ",str(self.alias.members[index])," of ", str(self.alias.name)," is different than core member ", str(member)," in ", str(self.name),".")
348 return '%s (%s)' % (self.name, self.alias)
351 TYPE_PLATFORM = 0 # Not bound to anything
352 TYPE_INSTANCE = 1 # Bound to VkInstance
353 TYPE_DEVICE = 2 # Bound to VkDevice
355 def __init__ (self, name, returnType, arguments, apiVersion = None):
357 self.returnType = returnType
358 self.arguments = arguments
361 self.apiVersion = apiVersion
365 if self.name == "vkGetInstanceProcAddr":
366 return Function.TYPE_PLATFORM
367 assert len(self.arguments) > 0
368 firstArgType = self.arguments[0].getType()
369 if firstArgType in ["VkInstance", "VkPhysicalDevice"]:
370 return Function.TYPE_INSTANCE
371 elif firstArgType in ["VkDevice", "VkCommandBuffer", "VkQueue"]:
372 return Function.TYPE_DEVICE
374 return Function.TYPE_PLATFORM
376 def checkAliasValidity (self):
377 if self.alias != None:
378 if len(self.arguments) != len(self.alias.arguments):
379 raise Exception("%s has different number of arguments than its alias %s." % (self.name, self.alias.name))
380 if self.returnType != self.alias.returnType or not (self.returnType.startswith(self.alias.returnType) or self.alias.returnType.startswith(self.returnType)):
381 raise Exception("%s has different return value's type than its alias %s." % (self.name, self.alias.name))
382 for index, argument in enumerate(self.arguments):
383 if argument != self.alias.arguments[index]:
384 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))
387 return '%s (%s)' % (self.name, self.alias)
390 def __init__ (self, name, handles, enums, bitfields, compositeTypes, functions, definitions, additionalDefinitions, typedefs, versionInCore):
392 self.definitions = definitions
393 self.additionalDefs = additionalDefinitions
394 self.handles = handles
396 self.bitfields = bitfields
397 self.compositeTypes = compositeTypes
398 self.functions = functions
399 self.typedefs = typedefs
400 self.versionInCore = versionInCore
403 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)
406 def __init__ (self, versions, definitions, handles, enums, bitfields, bitfields64, compositeTypes, functions, extensions, additionalExtensionData):
407 self.versions = versions
408 self.definitions = definitions
409 self.handles = handles
411 self.bitfields = bitfields
412 self.bitfields64 = bitfields64
413 self.compositeTypes = compositeTypes
414 self.functions = functions # \note contains extension functions as well
415 self.extensions = extensions
416 self.additionalExtensionData = additionalExtensionData # \note contains mandatory features and information about promotion
418 def readFile (filename):
419 with open(filename, 'rt') as f:
422 IDENT_PTRN = r'[a-zA-Z_][a-zA-Z0-9_]*'
423 WIDTH_PTRN = r'[:0-9]*'
424 TYPE_PTRN = r'[a-zA-Z_][a-zA-Z0-9_ \t*&]*'
426 def getInterfaceName (function):
427 assert function.name[:2] == "vk"
428 return function.name[2].lower() + function.name[3:]
430 def getFunctionTypeName (function):
431 assert function.name[:2] == "vk"
432 return function.name[2:] + "Func"
434 def endsWith (str, postfix):
435 return str[-len(postfix):] == postfix
437 def splitNameExtPostfix (name):
438 knownExtPostfixes = EXTENSION_POSTFIXES
439 for postfix in knownExtPostfixes:
440 if endsWith(name, postfix):
441 return (name[:-len(postfix)], postfix)
444 def getBitEnumNameForBitfield (bitfieldName):
445 bitfieldName, postfix = splitNameExtPostfix(bitfieldName)
446 assert bitfieldName[-1] == "s"
447 return bitfieldName[:-1] + "Bits" + postfix
449 def getBitfieldNameForBitEnum (bitEnumName):
450 bitEnumName, postfix = splitNameExtPostfix(bitEnumName)
451 assert bitEnumName[-4:] == "Bits"
452 return bitEnumName[:-4] + "s" + postfix
454 def parsePreprocDefinedValue (src, name):
455 value = parsePreprocDefinedValueOptional(src, name)
457 raise Exception("No such definition: %s" % name)
460 def parsePreprocDefinedValueOptional (src, name):
461 definition = re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src)
462 if definition is None:
464 value = definition.group(1).strip()
465 if value == "UINT32_MAX":
469 def parseEnum (name, src):
470 keyValuePtrn = '(' + IDENT_PTRN + r')\s*=\s*([^\s,\n}]+)\s*[,\n}]'
471 return Enum(name, re.findall(keyValuePtrn, src))
473 # \note Parses raw enums, some are mapped to bitfields later
474 def parseEnums (src):
475 matches = re.findall(r'typedef enum(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
477 for enumname, contents, typename in matches:
478 enums.append(parseEnum(typename, contents))
481 def parseCompositeType (type, name, src):
482 typeNamePtrn = r'(' + TYPE_PTRN + r')(\s+' + IDENT_PTRN + r')((\[[^\]]+\]|\s*:\s*[0-9]+)*)\s*;'
483 matches = re.findall(typeNamePtrn, src)
484 members = [Variable(t.strip(), n.strip(), a.replace(' ', '')) for t, n, a, _ in matches]
485 return CompositeType(type, name, members)
487 def parseCompositeTypes (src):
488 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
489 matches = re.findall(r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
491 for type, structname, contents, typename in matches:
492 types.append(parseCompositeType(typeMap[type], typename, contents))
495 def parseCompositeTypesByVersion (src, versionsData):
497 # find occurence of extension is a place where
498 # we cant assign apiVersion to found structures
499 extPtrn = r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"'
500 versionEnd = re.search(extPtrn, src)
501 versions = [Version((v[2], v[3], 0)) for v in versionsData]
502 versions.append(None)
504 # construct list of locations where version definitions start, and add the end of the file to it
505 sectionLocations = [versionDef[1] for versionDef in versionsData]
506 sectionLocations.append(versionEnd.start())
507 sectionLocations.append(len(src))
509 # construct function declaration pattern
510 ptrn = r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;'
511 regPtrn = re.compile(ptrn)
513 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
515 # iterate over all versions and find all structure definitions
516 for index, v in enumerate(versions):
517 matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1])
518 for type, structname, contents, typename in matches:
519 compositeType = parseCompositeType(typeMap[type], typename, contents)
520 compositeType.apiVersion = v
521 types.append(compositeType)
524 def parseVersions (src):
525 # returns list of tuples each with four items:
526 # 1. string with version token (without ' 1' at the end)
527 # 2. starting point off version specific definitions in vulkan.h.in
528 # 3. major version number
529 # 4. minor version number
530 return [(m.group()[:-2], m.start(), int(m.group(1)), int(m.group(2))) for m in re.finditer('VK_VERSION_([1-9])_([0-9]) 1', src)]
532 def parseHandles (src):
533 matches = re.findall(r'VK_DEFINE(_NON_DISPATCHABLE|)_HANDLE\((' + IDENT_PTRN + r')\)[ \t]*[\n\r]', src)
535 typeMap = {'': Handle.TYPE_DISP, '_NON_DISPATCHABLE': Handle.TYPE_NONDISP}
536 for type, name in matches:
537 handle = Handle(typeMap[type], name)
538 handles.append(handle)
541 def parseArgList (src):
542 typeNamePtrn = r'(' + TYPE_PTRN + r')(\s+' + IDENT_PTRN + r')((\[[^\]]+\])*)\s*'
544 for rawArg in src.split(','):
545 m = re.search(typeNamePtrn, rawArg)
546 args.append(Variable(m.group(1).strip(), m.group(2).strip(), m.group(3)))
549 def removeTypeExtPostfix (name):
550 for extPostfix in EXTENSION_POSTFIXES_STANDARD:
551 if endsWith(name, extPostfix):
552 return name[0:-len(extPostfix)]
555 def populateExtensionAliases(allObjects, extensionObjects):
556 for object in extensionObjects:
557 withoutPostfix = removeTypeExtPostfix(object.name)
558 if withoutPostfix != None and withoutPostfix in allObjects:
559 # max 1 alias is assumed by functions in this file
560 assert allObjects[withoutPostfix].alias == None
561 allObjects[withoutPostfix].alias = object
562 object.isAlias = True
563 for object in extensionObjects:
564 object.checkAliasValidity()
566 def populateAliasesWithTypedefs (objects, src):
568 for object in objects:
569 objectsByName[object.name] = object
570 ptrn = r'\s*typedef\s+' + object.name + r'\s+([^;]+)'
571 stash = re.findall(ptrn, src)
573 objExt = copy.deepcopy(object)
574 objExt.name = stash[0]
575 object.alias = objExt
576 objExt.isAlias = True
577 objects.append(objExt)
579 def removeAliasedValues (enum):
581 for name, value in enum.values:
582 valueByName[name] = value
584 def removeDefExtPostfix (name):
585 for extPostfix in EXTENSION_POSTFIXES:
586 if endsWith(name, "_" + extPostfix):
587 return name[0:-(len(extPostfix)+1)]
591 for name, value in enum.values:
592 withoutPostfix = removeDefExtPostfix(name)
593 if withoutPostfix != None and withoutPostfix in valueByName and valueByName[withoutPostfix] == value:
595 newValues.append((name, value))
596 enum.values = newValues
598 def parseFunctions (src):
599 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
600 matches = re.findall(ptrn, src)
602 for returnType, name, argList in matches:
603 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList)))
606 def parseFunctionsByVersion (src, versions):
607 # construct list of locations where version definitions start, and add the end of the file to it
608 sectionLocations = [versionDef[1] for versionDef in versions]
609 sectionLocations.append(len(src))
611 # construct function declaration pattern
612 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
613 regPtrn = re.compile(ptrn)
616 # iterate over all versions and find all function definitions
617 for index, v in enumerate(versions):
618 matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1])
619 for returnType, name, argList in matches:
620 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList), v[0]))
623 def splitByExtension (src):
624 ptrn = r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"'
625 # Construct long pattern that will be used to split whole source by extensions
626 match = "#define\s+("
627 for part in re.finditer(ptrn, src):
628 match += part.group(1)+"|"
629 match = match[:-1] + ")\s+1"
630 parts = re.split(match, src)
632 # First part is core, following tuples contain extension name and all its definitions
633 byExtension = [(None, parts[0])]
634 for ndx in range(1, len(parts), 2):
635 byExtension.append((parts[ndx], parts[ndx+1]))
638 def parseDefinitions (extensionName, src):
640 def skipDefinition (extensionName, definition):
641 if extensionName == None:
643 extNameUpper = extensionName.upper()
644 extNameUpper = extNameUpper.replace("VK_KHR_SYNCHRONIZATION2", "VK_KHR_SYNCHRONIZATION_2")
645 extNameUpper = extNameUpper.replace("VK_INTEL_SHADER_INTEGER_FUNCTIONS2", "VK_INTEL_SHADER_INTEGER_FUNCTIONS_2")
646 extNameUpper = extNameUpper.replace("VK_EXT_ROBUSTNESS2", "VK_EXT_ROBUSTNESS_2")
647 extNameUpper = extNameUpper.replace("VK_EXT_FRAGMENT_DENSITY_MAP2", "VK_EXT_FRAGMENT_DENSITY_MAP_2")
648 extNameUpper = extNameUpper.replace("VK_EXT_SHADER_ATOMIC_FLOAT2", "VK_EXT_SHADER_ATOMIC_FLOAT_2")
649 extNameUpper = extNameUpper.replace("VK_AMD_SHADER_CORE_PROPERTIES2", "VK_AMD_SHADER_CORE_PROPERTIES_2")
650 extNameUpper = extNameUpper.replace("VK_EXT_EXTENDED_DYNAMIC_STATE2", "VK_EXT_EXTENDED_DYNAMIC_STATE_2")
652 if definition[0].startswith(extNameUpper) and definition[1].isdigit():
654 if definition[0].startswith(extNameUpper):
656 if definition[0].endswith("_H_"):
660 ptrn = r'#define\s+([^\s]+)\s+([^\r\n]+)'
661 matches = re.findall(ptrn, src)
663 return [Definition(None, match[0], match[1]) for match in matches if not skipDefinition(extensionName, match)]
665 def parseTypedefs (src):
667 ptrn = r'typedef\s+([^\s]+)\s+([^\r\n]+);'
668 matches = re.findall(ptrn, src)
670 return [Definition(None, match[0], match[1]) for match in matches]
672 def parseExtensions (src, versions, allFunctions, allCompositeTypes, allEnums, allBitfields, allHandles, allDefinitions, additionalExtensionData):
674 # note registeredExtensionDict is also executed for vulkan 1.0 source for which extension name is None
675 registeredExtensionDict = {None: None}
676 for extensionName, data in additionalExtensionData:
677 # make sure that this extension was registered
678 if 'register_extension' not in data.keys():
680 # save array containing 'device' or 'instance' string followed by the optional vulkan version in which this extension is core;
681 # note that register_extension section is also required for partialy promoted extensions like VK_EXT_extended_dynamic_state2
682 # but those extensions should not fill 'core' tag
683 registeredExtensionDict[extensionName] = [ data['register_extension']['type'] ]
684 match = re.match("(\d).(\d).(\d)", data['register_extension']['core'])
686 registeredExtensionDict[extensionName].extend( [ int(match.group(1)), int(match.group(2)), int(match.group(3)) ] )
688 splitSrc = splitByExtension(src)
690 functionsByName = {function.name: function for function in allFunctions}
691 compositeTypesByName = {compType.name: compType for compType in allCompositeTypes}
692 enumsByName = {enum.name: enum for enum in allEnums}
693 bitfieldsByName = {bitfield.name: bitfield for bitfield in allBitfields}
694 handlesByName = {handle.name: handle for handle in allHandles}
695 definitionsByName = {definition.name: definition for definition in allDefinitions}
697 for extensionName, extensionSrc in splitSrc:
698 definitions = [Definition("uint32_t", v.getInHex(), parsePreprocDefinedValueOptional(extensionSrc, v.getInHex())) for v in versions]
699 definitions.extend([Definition(type, name, parsePreprocDefinedValueOptional(extensionSrc, name)) for name, type in DEFINITIONS])
700 definitions = [definition for definition in definitions if definition.value != None]
701 additionalDefinitions = parseDefinitions(extensionName, extensionSrc)
702 handles = parseHandles(extensionSrc)
703 functions = parseFunctions(extensionSrc)
704 compositeTypes = parseCompositeTypes(extensionSrc)
705 rawEnums = parseEnums(extensionSrc)
706 bitfieldNames = parse32bitBitfieldNames(extensionSrc)
707 typedefs = parseTypedefs(extensionSrc)
708 enumBitfieldNames = [getBitEnumNameForBitfield(name) for name in bitfieldNames]
709 enums = [enum for enum in rawEnums if enum.name not in enumBitfieldNames]
711 extCoreVersion = None
712 extData = registeredExtensionDict.get(extensionName, None)
713 extFunctions = [functionsByName[function.name] for function in functions]
714 extCompositeTypes = [compositeTypesByName[compositeType.name] for compositeType in compositeTypes]
715 extEnums = [enumsByName[enum.name] for enum in enums]
716 extBitfields = [bitfieldsByName[bitfieldName] for bitfieldName in bitfieldNames]
717 extHandles = [handlesByName[handle.name] for handle in handles]
718 extDefinitions = [definitionsByName[definition.name] for definition in definitions]
721 populateExtensionAliases(functionsByName, extFunctions)
722 populateExtensionAliases(handlesByName, extHandles)
723 populateExtensionAliases(enumsByName, extEnums)
724 populateExtensionAliases(bitfieldsByName, extBitfields)
725 populateExtensionAliases(compositeTypesByName, extCompositeTypes)
727 extCoreVersion = extData
729 extensions.append(Extension(extensionName, extHandles, extEnums, extBitfields, extCompositeTypes, extFunctions, extDefinitions, additionalDefinitions, typedefs, extCoreVersion))
732 def parse32bitBitfieldNames (src):
733 ptrn = r'typedef\s+VkFlags\s(' + IDENT_PTRN + r')\s*;'
734 matches = re.findall(ptrn, src)
738 def parse64bitBitfieldNames (src):
739 ptrn = r'typedef\s+VkFlags64\s(' + IDENT_PTRN + r')\s*;'
740 matches = re.findall(ptrn, src)
744 def parse64bitBitfieldValues (src, bitfieldNamesList):
747 for bitfieldName in bitfieldNamesList:
748 ptrn = r'static const ' + bitfieldName + r'\s*(' + IDENT_PTRN + r')\s*=\s*([a-zA-Z0-9_]+)\s*;'
749 matches = re.findall(ptrn, src)
750 bitfields64.append(Bitfield(bitfieldName, matches))
755 versionsData = parseVersions(src)
756 versions = [Version((v[2], v[3], 0)) for v in versionsData]
757 definitions = [Definition("uint32_t", v.getInHex(), parsePreprocDefinedValue(src, v.getInHex())) for v in versions] +\
758 [Definition(type, name, parsePreprocDefinedValue(src, name)) for name, type in DEFINITIONS]
760 handles = parseHandles(src)
761 rawEnums = parseEnums(src)
762 bitfieldNames = parse32bitBitfieldNames(src)
763 bitfieldEnums = set([getBitEnumNameForBitfield(n) for n in bitfieldNames if getBitEnumNameForBitfield(n) in [enum.name for enum in rawEnums]])
764 bitfield64Names = parse64bitBitfieldNames(src)
765 bitfields64 = parse64bitBitfieldValues(src, bitfield64Names)
768 compositeTypes = parseCompositeTypesByVersion(src, versionsData)
769 allFunctions = parseFunctionsByVersion(src, versionsData)
770 additionalExtensionData = {}
772 # read all files from extensions directory
773 for fileName in glob.glob(os.path.join(VULKAN_SRC_DIR, "extensions", "*.json")):
774 extensionName = os.path.basename(fileName)[:-5]
775 fileContent = readFile(fileName)
777 additionalExtensionData[extensionName] = json.loads(fileContent)
778 except ValueError as err:
779 print("Error in %s: %s" % (os.path.basename(fileName), str(err)))
781 additionalExtensionData = sorted(additionalExtensionData.items(), key=lambda e: e[0])
783 for enum in rawEnums:
784 if enum.name in bitfieldEnums:
785 bitfields.append(Bitfield(getBitfieldNameForBitEnum(enum.name), enum.values))
789 for bitfieldName in bitfieldNames:
790 if not bitfieldName in [bitfield.name for bitfield in bitfields]:
792 bitfields.append(Bitfield(bitfieldName, []))
794 extensions = parseExtensions(src, versions, allFunctions, compositeTypes, enums, bitfields, handles, definitions, additionalExtensionData)
796 # Populate alias fields
797 populateAliasesWithTypedefs(compositeTypes, src)
798 populateAliasesWithTypedefs(enums, src)
799 populateAliasesWithTypedefs(bitfields, src)
800 populateAliasesWithTypedefs(bitfields64, src)
801 populateAliasesWithTypedefs(handles, src)
804 removeAliasedValues(enum)
806 # Make generator to create Deleter<VkAccelerationStructureNV>
807 for f in allFunctions:
808 if (f.name == 'vkDestroyAccelerationStructureNV'):
809 f.arguments[1].type[0] = 'VkAccelerationStructureNV'
811 # Dealias handles VkAccelerationStructureNV and VkAccelerationStructureKHR
812 for handle in handles:
813 if handle.name == 'VkAccelerationStructureKHR':
815 if handle.name == 'VkAccelerationStructureNV':
816 handle.isAlias = False
820 definitions = definitions,
823 bitfields = bitfields,
824 bitfields64 = bitfields64,
825 compositeTypes = compositeTypes,
826 functions = allFunctions,
827 extensions = extensions,
828 additionalExtensionData = additionalExtensionData)
830 def splitUniqueAndDuplicatedEntries (handles):
831 listOfUniqueHandles = []
832 duplicates = OrderedDict()
833 for handle in handles:
834 if handle.alias != None:
835 duplicates[handle.alias] = handle
836 if not handle.isAlias:
837 listOfUniqueHandles.append(handle)
838 return listOfUniqueHandles, duplicates
840 def writeHandleType (api, filename):
841 uniqeHandles, duplicatedHandles = splitUniqueAndDuplicatedEntries(api.handles)
844 yield "\t%s\t= 0," % uniqeHandles[0].getHandleType()
845 for handle in uniqeHandles[1:]:
846 yield "\t%s," % handle.getHandleType()
847 for duplicate in duplicatedHandles:
848 yield "\t%s\t= %s," % (duplicate.getHandleType(), duplicatedHandles[duplicate].getHandleType())
849 yield "\tHANDLE_TYPE_LAST\t= %s + 1" % (uniqeHandles[-1].getHandleType())
851 def genHandlesBlock ():
852 yield "enum HandleType"
855 for line in indentLines(genHandles()):
861 writeInlFile(filename, INL_HEADER, genHandlesBlock())
863 def getEnumValuePrefix (enum):
864 prefix = enum.name[0]
865 for i in range(1, len(enum.name)):
866 if enum.name[i].isupper() and not enum.name[i-1].isupper():
868 prefix += enum.name[i].upper()
871 def parseInt (value):
872 if value[:2] == "0x":
873 return int(value, 16)
875 return int(value, 10)
877 def areEnumValuesLinear (enum):
880 for name, value in enum.values:
881 if value[:2] != "VK":
882 intValue = parseInt(value)
883 if intValue != curIndex:
884 # enum is linear when all items are in order
885 if intValue != 0x7FFFFFFF:
887 # count number of items with 0x7FFFFFFF value;
888 # enum containing single 0x7FFFFFFF item are also
889 # considered as linear (this is usualy *_MAX_ENUM item)
891 # enums containing more then one 0x7FFFFFFF value
892 # are not considered as linear (vulkan video enums)
898 def genEnumSrc (enum):
899 yield "enum %s" % enum.name
903 if areEnumValuesLinear(enum):
904 hasMaxItem = parseInt(enum.values[-1][1]) == 0x7FFFFFFF
906 values = enum.values[:-1] if hasMaxItem else enum.values
907 lastItem = "\t%s_LAST," % getEnumValuePrefix(enum)
909 # linear values first, followed by *_LAST
910 lines += ["\t%s\t= %s," % v for v in values if v[1][:2] != "VK"]
911 lines.append(lastItem)
913 # equivalence enums and *_MAX_ENUM
914 lines += ["\t%s\t= %s," % v for v in values if v[1][:2] == "VK"]
916 lines.append("\t%s\t= %s," % enum.values[-1])
918 lines += ["\t%s\t= %s," % v for v in enum.values]
920 for line in indentLines(lines):
925 def genBitfieldSrc (bitfield):
926 if len(bitfield.values) > 0:
927 yield "enum %s" % getBitEnumNameForBitfield(bitfield.name)
929 for line in indentLines(["\t%s\t= %s," % v for v in bitfield.values]):
932 yield "typedef uint32_t %s;" % bitfield.name
934 def genBitfield64Src (bitfield64):
935 yield "typedef uint64_t %s;" % bitfield64.name
936 if len(bitfield64.values) > 0:
937 ptrn = "static const " + bitfield64.name + " %s\t= %s;"
938 for line in indentLines([ptrn % v for v in bitfield64.values]):
942 def genCompositeTypeSrc (type):
943 yield "%s %s" % (type.getClassName(), type.name)
945 for line in indentLines(['\t'+m.getAsString('\t')+';' for m in type.members]):
949 def genHandlesSrc (handles):
950 uniqeHandles, duplicatedHandles = splitUniqueAndDuplicatedEntries(handles)
952 def genLines (handles):
953 for handle in uniqeHandles:
954 if handle.type == Handle.TYPE_DISP:
955 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
956 elif handle.type == Handle.TYPE_NONDISP:
957 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
959 for duplicate in duplicatedHandles:
960 if duplicate.type == Handle.TYPE_DISP:
961 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (duplicate.name, duplicatedHandles[duplicate].getHandleType())
962 elif duplicate.type == Handle.TYPE_NONDISP:
963 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (duplicate.name, duplicatedHandles[duplicate].getHandleType())
965 for line in indentLines(genLines(handles)):
968 def stripTrailingComment(str):
969 index = str.find("//")
974 def genDefinitionsSrc (definitions):
975 for line in ["#define %s\t(static_cast<%s>\t(%s))" % (definition.name, definition.type, stripTrailingComment(definition.value)) for definition in definitions]:
978 def genDefinitionsAliasSrc (definitions):
979 for line in ["#define %s\t%s" % (definition.name, definitions[definition].name) for definition in definitions]:
980 if definition.value != definitions[definition].value and definition.value != definitions[definition].name:
981 raise Exception("Value of %s (%s) is different than core definition value %s (%s)." % (definition.name, definition.value, definitions[definition].name, definitions[definition].value))
984 def genMaxFrameworkVersion (definitions):
985 maxApiVersionMajor = 1
986 maxApiVersionMinor = 0
987 for definition in definitions:
988 match = re.match("VK_API_VERSION_(\d+)_(\d+)", definition.name)
990 apiVersionMajor = int(match.group(1))
991 apiVersionMinor = int(match.group(2))
992 if apiVersionMajor > maxApiVersionMajor:
993 maxApiVersionMajor = apiVersionMajor
994 maxApiVersionMinor = apiVersionMinor
995 elif apiVersionMajor == maxApiVersionMajor and apiVersionMinor > maxApiVersionMinor:
996 maxApiVersionMinor = apiVersionMinor
997 yield "#define VK_API_MAX_FRAMEWORK_VERSION\tVK_API_VERSION_%d_%d" % (maxApiVersionMajor, maxApiVersionMinor)
999 def writeBasicTypes (api, filename):
1002 definitionsCore, definitionDuplicates = splitUniqueAndDuplicatedEntries(api.definitions)
1004 for line in indentLines(chain(genDefinitionsSrc(definitionsCore), genMaxFrameworkVersion(definitionsCore), genDefinitionsAliasSrc(definitionDuplicates))):
1008 for line in genHandlesSrc(api.handles):
1012 for enum in api.enums:
1013 if not enum.isAlias:
1014 for line in genEnumSrc(enum):
1017 for enum2 in api.enums:
1018 if enum2.alias == enum:
1019 yield "typedef %s %s;" % (enum2.name, enum.name)
1022 for bitfield in api.bitfields:
1023 if not bitfield.isAlias:
1024 for line in genBitfieldSrc(bitfield):
1027 for bitfield2 in api.bitfields:
1028 if bitfield2.alias == bitfield:
1029 yield "typedef %s %s;" % (bitfield2.name, bitfield.name)
1032 for bitfield in api.bitfields64:
1033 if not bitfield.isAlias:
1034 for line in genBitfield64Src(bitfield):
1037 for bitfield2 in api.bitfields64:
1038 if bitfield2.alias == bitfield:
1039 yield "typedef %s %s;" % (bitfield2.name, bitfield.name)
1042 for line in indentLines(["VK_DEFINE_PLATFORM_TYPE(%s,\t%s)" % (s[0], c) for n, s, c in PLATFORM_TYPES]):
1045 for ext in api.extensions:
1046 if ext.additionalDefs != None:
1047 for definition in ext.additionalDefs:
1048 yield "#define " + definition.name + " " + definition.value
1050 writeInlFile(filename, INL_HEADER, gen())
1052 def writeCompositeTypes (api, filename):
1054 for type in api.compositeTypes:
1055 type.checkAliasValidity()
1057 if not type.isAlias:
1058 for line in genCompositeTypeSrc(type):
1061 for type2 in api.compositeTypes:
1062 if type2.alias == type:
1063 yield "typedef %s %s;" % (type2.name, type.name)
1066 writeInlFile(filename, INL_HEADER, gen())
1068 def argListToStr (args):
1069 return ", ".join(v.getAsStringForArgumentList(' ') for v in args)
1071 def writeInterfaceDecl (api, filename, functionTypes, concrete):
1073 postfix = "" if concrete else " = 0"
1074 for function in api.functions:
1075 if not function.getType() in functionTypes:
1077 if not function.isAlias:
1078 yield "virtual %s\t%s\t(%s) const%s;" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments), postfix)
1080 writeInlFile(filename, INL_HEADER, indentLines(genProtos()))
1082 def writeFunctionPtrTypes (api, filename):
1084 for function in api.functions:
1085 yield "typedef VKAPI_ATTR %s\t(VKAPI_CALL* %s)\t(%s);" % (function.returnType, getFunctionTypeName(function), argListToStr(function.arguments))
1087 writeInlFile(filename, INL_HEADER, indentLines(genTypes()))
1089 def writeFunctionPointers (api, filename, functionTypes):
1090 def FunctionsYielder ():
1091 for function in api.functions:
1092 if function.getType() in functionTypes:
1093 if function.isAlias:
1094 if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice":
1095 yield "%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function))
1097 yield "%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function))
1099 writeInlFile(filename, INL_HEADER, indentLines(FunctionsYielder()))
1101 def writeInitFunctionPointers (api, filename, functionTypes, cond = None):
1102 def makeInitFunctionPointers ():
1103 for function in api.functions:
1104 if function.getType() in functionTypes and (cond == None or cond(function)):
1105 interfaceName = getInterfaceName(function)
1106 if function.isAlias:
1107 if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice":
1108 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
1110 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
1111 if function.alias != None:
1112 yield "if (!m_vk.%s)" % (getInterfaceName(function))
1113 yield " m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.alias.name)
1114 lines = [line.replace(' ', '\t') for line in indentLines(makeInitFunctionPointers())]
1115 writeInlFile(filename, INL_HEADER, lines)
1117 def writeFuncPtrInterfaceImpl (api, filename, functionTypes, className):
1118 def makeFuncPtrInterfaceImpl ():
1119 for function in api.functions:
1120 if function.getType() in functionTypes and not function.isAlias:
1122 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments))
1124 if function.name == "vkEnumerateInstanceVersion":
1125 yield " if (m_vk.enumerateInstanceVersion)"
1126 yield " return m_vk.enumerateInstanceVersion(pApiVersion);"
1128 yield " *pApiVersion = VK_API_VERSION_1_0;"
1129 yield " return VK_SUCCESS;"
1130 elif function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice" and function.alias != None:
1131 yield " vk::VkPhysicalDeviceProperties props;"
1132 yield " m_vk.getPhysicalDeviceProperties(physicalDevice, &props);"
1133 yield " if (props.apiVersion >= VK_API_VERSION_1_1)"
1134 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
1136 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function.alias), ", ".join(a.name for a in function.arguments))
1138 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
1141 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceImpl())
1143 def writeStrUtilProto (api, filename):
1144 def makeStrUtilProto ():
1145 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]):
1148 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]):
1151 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]):
1154 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']):
1157 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]):
1160 writeInlFile(filename, INL_HEADER, makeStrUtilProto())
1162 def writeStrUtilImpl (api, filename):
1163 def makeStrUtilImpl ():
1164 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]):
1168 yield "namespace %s" % PLATFORM_TYPE_NAMESPACE
1171 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):
1176 for enum in api.enums:
1180 yield "const char* get%sName (%s value)" % (enum.name[2:], enum.name)
1182 yield "\tswitch (value)"
1185 lastValue = 0x7FFFFFFF
1186 for n, v in enum.values:
1187 if (v[:2] != "VK") and (v != lastValue):
1188 enumValues.append(f"\t\tcase {n}:\treturn \"{n}\";")
1190 enumValues.append("\t\tdefault:\treturn DE_NULL;")
1191 for line in indentLines(enumValues):
1196 for bitfield in api.bitfields:
1197 if bitfield.isAlias:
1198 if bitfield.name != 'VkBuildAccelerationStructureFlagsNV':
1201 yield "tcu::Format::Bitfield<32> get%sStr (%s value)" % (bitfield.name[2:], bitfield.name)
1204 if len(bitfield.values) > 0:
1205 yield "\tstatic const tcu::Format::BitDesc s_desc[] ="
1207 for line in indentLines(["\t\ttcu::Format::BitDesc(%s,\t\"%s\")," % (n, n) for n, v in bitfield.values]):
1210 yield "\treturn tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));"
1212 yield "\treturn tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL);"
1215 bitfieldTypeNames = set([bitfield.name for bitfield in api.bitfields])
1217 for type in api.compositeTypes:
1218 if not type.isAlias:
1220 yield "std::ostream& operator<< (std::ostream& s, const %s& value)" % type.name
1222 yield "\ts << \"%s = {\\n\";" % type.name
1223 for member in type.members:
1224 memberName = member.name
1227 if member.getType() in bitfieldTypeNames:
1228 valFmt = "get%sStr(value.%s)" % (member.getType()[2:], member.name)
1229 elif member.getType() == "const char*" or member.getType() == "char*":
1230 valFmt = "getCharPtrStr(value.%s)" % member.name
1231 elif member.getType() == PLATFORM_TYPE_NAMESPACE + "::Win32LPCWSTR":
1232 valFmt = "getWStr(value.%s)" % member.name
1233 elif member.arraySize != '':
1234 singleDimensional = not '][' in member.arraySize
1235 if member.name in ["extensionName", "deviceName", "layerName", "description"]:
1236 valFmt = "(const char*)value.%s" % member.name
1237 elif singleDimensional and (member.getType() == 'char' or member.getType() == 'uint8_t'):
1238 newLine = "'\\n' << "
1239 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)
1241 if member.name == "memoryTypes" or member.name == "memoryHeaps":
1242 endIter = "DE_ARRAY_BEGIN(value.%s) + value.%sCount" % (member.name, member.name[:-1])
1244 endIter = "DE_ARRAY_END(value.%s)" % member.name
1245 newLine = "'\\n' << "
1246 valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), %s)" % (member.name, endIter)
1247 memberName = member.name
1249 valFmt = "value.%s" % member.name
1250 yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';"
1254 writeInlFile(filename, INL_HEADER, makeStrUtilImpl())
1257 def writeObjTypeImpl (api, filename):
1258 def makeObjTypeImpl ():
1260 yield "namespace vk"
1263 yield "template<typename T> VkObjectType getObjectType (void);"
1265 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]):
1270 writeInlFile(filename, INL_HEADER, makeObjTypeImpl())
1272 class ConstructorFunction:
1273 def __init__ (self, type, name, objectType, ifaceArgs, arguments):
1276 self.objectType = objectType
1277 self.ifaceArgs = ifaceArgs
1278 self.arguments = arguments
1280 def getConstructorFunctions (api):
1283 Function.TYPE_PLATFORM: [Variable("const PlatformInterface&", "vk", "")],
1284 Function.TYPE_INSTANCE: [Variable("const InstanceInterface&", "vk", "")],
1285 Function.TYPE_DEVICE: [Variable("const DeviceInterface&", "vk", "")]
1287 for function in api.functions:
1288 if function.isAlias:
1290 if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "createInfoCount" in [a.name for a in function.arguments]:
1291 if function.name == "vkCreateDisplayModeKHR":
1292 continue # No way to delete display modes (bug?)
1294 # \todo [pyry] Rather hacky
1295 ifaceArgs = ifacesDict[function.getType()]
1296 if function.name == "vkCreateDevice":
1297 ifaceArgs = [Variable("const PlatformInterface&", "vkp", ""), Variable("VkInstance", "instance", "")] + ifaceArgs
1299 assert (function.arguments[-2].type == ["const", "VkAllocationCallbacks", "*"])
1301 objectType = function.arguments[-1].type[0] #not getType() but type[0] on purpose
1302 arguments = function.arguments[:-1]
1303 funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function), objectType, ifaceArgs, arguments))
1306 def addVersionDefines(versionSpectrum):
1307 output = ["#define " + ver.getDefineName() + " " + ver.getInHex() for ver in versionSpectrum if not ver.isStandardVersion()]
1310 def removeVersionDefines(versionSpectrum):
1311 output = ["#undef " + ver.getDefineName() for ver in versionSpectrum if not ver.isStandardVersion()]
1314 def writeRefUtilProto (api, filename):
1315 functions = getConstructorFunctions(api)
1317 def makeRefUtilProto ():
1319 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]):
1322 writeInlFile(filename, INL_HEADER, makeRefUtilProto())
1324 def writeRefUtilImpl (api, filename):
1325 functions = getConstructorFunctions(api)
1327 def makeRefUtilImpl ():
1328 yield "namespace refdetails"
1332 for function in api.functions:
1333 if function.getType() == Function.TYPE_DEVICE \
1334 and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \
1335 and not function.name == "vkDestroyDevice" \
1336 and not function.isAlias:
1337 objectType = function.arguments[-2].getType()
1339 yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType)
1341 yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function))
1345 yield "} // refdetails"
1349 Function.TYPE_PLATFORM: "object",
1350 Function.TYPE_INSTANCE: "instance",
1351 Function.TYPE_DEVICE: "device"
1354 for function in functions:
1355 deleterArgsString = ''
1356 if function.name == "createDevice":
1357 # createDevice requires two additional parameters to setup VkDevice deleter
1358 deleterArgsString = "vkp, instance, object, " + function.arguments[-1].name
1360 deleterArgsString = "vk, %s, %s" % (dtorDict[function.type], function.arguments[-1].name)
1362 yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr(function.ifaceArgs + function.arguments))
1364 yield "\t%s object = 0;" % function.objectType
1365 yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"]))
1366 yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, deleterArgsString)
1370 writeInlFile(filename, INL_HEADER, makeRefUtilImpl())
1372 def writeStructTraitsImpl (api, filename):
1374 for type in api.compositeTypes:
1375 if type.getClassName() == "struct" and type.members[0].name == "sType" and not type.isAlias and type.name != "VkBaseOutStructure" and type.name != "VkBaseInStructure":
1376 yield "template<> VkStructureType getStructureType<%s> (void)" % type.name
1378 yield "\treturn %s;" % prefixName("VK_STRUCTURE_TYPE_", type.name)
1382 writeInlFile(filename, INL_HEADER, gen())
1384 def writeNullDriverImpl (api, filename):
1385 def genNullDriverImpl ():
1386 specialFuncNames = [
1387 "vkCreateGraphicsPipelines",
1388 "vkCreateComputePipelines",
1389 "vkCreateRayTracingPipelinesNV",
1390 "vkCreateRayTracingPipelinesKHR",
1391 "vkGetInstanceProcAddr",
1392 "vkGetDeviceProcAddr",
1393 "vkEnumeratePhysicalDevices",
1394 "vkEnumerateInstanceExtensionProperties",
1395 "vkEnumerateDeviceExtensionProperties",
1396 "vkGetPhysicalDeviceFeatures",
1397 "vkGetPhysicalDeviceFeatures2KHR",
1398 "vkGetPhysicalDeviceProperties",
1399 "vkGetPhysicalDeviceProperties2KHR",
1400 "vkGetPhysicalDeviceQueueFamilyProperties",
1401 "vkGetPhysicalDeviceMemoryProperties",
1402 "vkGetPhysicalDeviceFormatProperties",
1403 "vkGetPhysicalDeviceImageFormatProperties",
1405 "vkGetBufferMemoryRequirements",
1406 "vkGetBufferMemoryRequirements2KHR",
1407 "vkGetImageMemoryRequirements",
1408 "vkGetImageMemoryRequirements2KHR",
1412 "vkAllocateDescriptorSets",
1413 "vkFreeDescriptorSets",
1414 "vkResetDescriptorPool",
1415 "vkAllocateCommandBuffers",
1416 "vkFreeCommandBuffers",
1417 "vkCreateDisplayModeKHR",
1418 "vkCreateSharedSwapchainsKHR",
1419 "vkGetPhysicalDeviceExternalBufferPropertiesKHR",
1420 "vkGetPhysicalDeviceImageFormatProperties2KHR",
1421 "vkGetMemoryAndroidHardwareBufferANDROID",
1424 coreFunctions = [f for f in api.functions if not f.isAlias]
1425 specialFuncs = [f for f in coreFunctions if f.name in specialFuncNames]
1426 createFuncs = [f for f in coreFunctions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs]
1427 destroyFuncs = [f for f in coreFunctions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs]
1428 dummyFuncs = [f for f in coreFunctions if f not in specialFuncs + createFuncs + destroyFuncs]
1430 def getHandle (name):
1431 for handle in api.handles:
1432 if handle.name == name[0]:
1434 raise Exception("No such handle: %s" % name)
1436 for function in createFuncs:
1437 objectType = function.arguments[-1].type[:-1]
1438 argsStr = ", ".join([a.name for a in function.arguments[:-1]])
1440 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1442 yield "\tDE_UNREF(%s);" % function.arguments[-2].name
1444 if getHandle(objectType).type == Handle.TYPE_NONDISP:
1445 yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[0][2:], objectType[0], argsStr)
1447 yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[0][2:], objectType[0], argsStr)
1451 for function in destroyFuncs:
1452 objectArg = function.arguments[-2]
1454 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1456 for arg in function.arguments[:-2]:
1457 yield "\tDE_UNREF(%s);" % arg.name
1459 if getHandle(objectArg.type).type == Handle.TYPE_NONDISP:
1460 yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.getType()[2:], objectArg.getType(), objectArg.name, function.arguments[-1].name)
1462 yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.getType()[2:], objectArg.getType(), objectArg.name, function.arguments[-1].name)
1467 for function in dummyFuncs:
1468 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1470 for arg in function.arguments:
1471 yield "\tDE_UNREF(%s);" % arg.name
1472 if function.returnType != "void":
1473 yield "\treturn VK_SUCCESS;"
1477 def genFuncEntryTable (type, name):
1478 funcs = [f for f in api.functions if f.getType() == type]
1480 for f in api.functions:
1482 refFuncs[f.alias] = f
1484 yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name
1486 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]):
1492 for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"):
1495 for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"):
1498 for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"):
1501 writeInlFile(filename, INL_HEADER, genNullDriverImpl())
1503 def writeTypeUtil (api, filename):
1504 # Structs filled by API queries are not often used in test code
1505 QUERY_RESULT_TYPES = set([
1506 "VkPhysicalDeviceFeatures",
1507 "VkPhysicalDeviceLimits",
1508 "VkFormatProperties",
1509 "VkImageFormatProperties",
1510 "VkPhysicalDeviceSparseProperties",
1511 "VkQueueFamilyProperties",
1514 "StdVideoH264SpsVuiFlags",
1515 "StdVideoH264SpsFlags",
1516 "StdVideoH264PpsFlags",
1517 "StdVideoDecodeH264PictureInfoFlags",
1518 "StdVideoDecodeH264ReferenceInfoFlags",
1519 "StdVideoDecodeH264MvcElementFlags",
1520 "StdVideoEncodeH264SliceHeaderFlags",
1521 "StdVideoEncodeH264PictureInfoFlags",
1522 "StdVideoEncodeH264RefMgmtFlags",
1523 "StdVideoEncodeH264ReferenceInfoFlags",
1524 "StdVideoH265HrdFlags",
1525 "StdVideoH265VpsFlags",
1526 "StdVideoH265SpsVuiFlags",
1527 "StdVideoH265SpsFlags",
1528 "StdVideoH265PpsFlags",
1529 "StdVideoDecodeH265PictureInfoFlags",
1530 "StdVideoDecodeH265ReferenceInfoFlags",
1531 "StdVideoEncodeH265PictureInfoFlags",
1532 "StdVideoEncodeH265SliceHeaderFlags",
1533 "StdVideoEncodeH265ReferenceModificationFlags",
1534 "StdVideoEncodeH265ReferenceInfoFlags",
1535 "StdVideoEncodeH265SliceSegmentHeaderFlags",
1537 COMPOSITE_TYPES = set([t.name for t in api.compositeTypes if not t.isAlias])
1539 def isSimpleStruct (type):
1540 def hasArrayMember (type):
1541 for member in type.members:
1542 if member.arraySize != '':
1546 def hasCompositeMember (type):
1547 for member in type.members:
1548 if member.getType() in COMPOSITE_TYPES:
1552 return type.typeClass == CompositeType.CLASS_STRUCT and \
1553 type.members[0].getType() != "VkStructureType" and \
1554 not type.name in QUERY_RESULT_TYPES and \
1555 not hasArrayMember(type) and \
1556 not hasCompositeMember(type)
1559 for type in api.compositeTypes:
1560 if not isSimpleStruct(type) or type.isAlias:
1563 name = type.name[2:] if type.name[:2].lower() == "vk" else type.name
1566 yield "inline %s make%s (%s)" % (type.name, name, argListToStr(type.members))
1568 yield "\t%s res;" % type.name
1569 for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]):
1571 yield "\treturn res;"
1574 writeInlFile(filename, INL_HEADER, gen())
1576 def writeDriverIds(filename):
1578 driverIdsString = []
1579 driverIdsString.append("static const struct\n"
1581 "\tstd::string driver;\n"
1583 "} driverIds [] =\n"
1586 vulkanCore = readFile(os.path.join(VULKAN_HEADERS_INCLUDE_DIR, "vulkan", "vulkan_core.h"))
1588 items = re.search(r'(?:typedef\s+enum\s+VkDriverId\s*{)((.*\n)*)(?:}\s*VkDriverId\s*;)', vulkanCore).group(1).split(',')
1589 driverItems = dict()
1592 splitted = item.split('=')
1593 key = splitted[0].strip()
1594 value_str = splitted[1].strip()
1595 try: # is this previously defined value?
1596 value = driverItems[value_str]
1601 value_str = "\t// " + value_str
1602 driverItems[key] = value
1603 if not item == items[-1]:
1604 driverIdsString.append("\t{\"" + key + "\"" + ", " + value + "}," + value_str)
1606 driverIdsString.append("\t{\"" + key + "\"" + ", " + value + "}" + value_str)
1607 driverItems[key] = value
1609 driverIdsString.append("};")
1611 writeInlFile(filename, INL_HEADER, driverIdsString)
1614 def writeSupportedExtenions(api, filename):
1616 def writeExtensionsForVersions(map):
1619 result.append(" if (coreVersion >= " + str(version) + ")")
1621 for extension in map[version]:
1622 result.append(' dst.push_back("' + extension.name + '");')
1631 for ext in api.extensions:
1632 if ext.versionInCore != None:
1633 if ext.versionInCore[0] == 'instance':
1634 list = instanceMap.get(Version(ext.versionInCore[1:]))
1635 instanceMap[Version(ext.versionInCore[1:])] = list + [ext] if list else [ext]
1637 list = deviceMap.get(Version(ext.versionInCore[1:]))
1638 deviceMap[Version(ext.versionInCore[1:])] = list + [ext] if list else [ext]
1639 versionSet.add(Version(ext.versionInCore[1:]))
1641 lines = addVersionDefines(versionSet) + [
1643 "void getCoreDeviceExtensionsImpl (uint32_t coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(deviceMap) != 0 else ""),
1644 "{"] + writeExtensionsForVersions(deviceMap) + [
1647 "void getCoreInstanceExtensionsImpl (uint32_t coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(instanceMap) != 0 else ""),
1648 "{"] + writeExtensionsForVersions(instanceMap) + [
1650 ""] + removeVersionDefines(versionSet)
1651 writeInlFile(filename, INL_HEADER, lines)
1653 def writeExtensionFunctions (api, filename):
1655 def isInstanceExtension (ext):
1656 if ext.name and ext.functions:
1657 if ext.functions[0].getType() == Function.TYPE_INSTANCE:
1662 def isDeviceExtension (ext):
1663 if ext.name and ext.functions:
1664 if ext.functions[0].getType() == Function.TYPE_DEVICE:
1669 def writeExtensionNameArrays ():
1670 instanceExtensionNames = []
1671 deviceExtensionNames = []
1672 for ext in api.extensions:
1673 if ext.name and isInstanceExtension(ext):
1674 instanceExtensionNames += [ext.name]
1675 elif ext.name and isDeviceExtension(ext):
1676 deviceExtensionNames += [ext.name]
1677 yield '::std::string instanceExtensionNames[] =\n{'
1678 for instanceExtName in instanceExtensionNames:
1679 if (instanceExtName == instanceExtensionNames[len(instanceExtensionNames) - 1]):
1680 yield '\t"%s"' % instanceExtName
1682 yield '\t"%s",' % instanceExtName
1684 yield '::std::string deviceExtensionNames[] =\n{'
1685 for deviceExtName in deviceExtensionNames:
1686 if (deviceExtName == deviceExtensionNames[len(deviceExtensionNames) - 1]):
1687 yield '\t"%s"' % deviceExtName
1689 yield '\t"%s",' % deviceExtName
1692 def writeExtensionFunctions (functionType):
1694 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
1695 if functionType == Function.TYPE_INSTANCE:
1696 yield 'void getInstanceExtensionFunctions (uint32_t apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{'
1697 dg_list = ["vkGetPhysicalDevicePresentRectanglesKHR"]
1698 elif functionType == Function.TYPE_DEVICE:
1699 yield 'void getDeviceExtensionFunctions (uint32_t apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{'
1700 dg_list = ["vkGetDeviceGroupPresentCapabilitiesKHR", "vkGetDeviceGroupSurfacePresentModesKHR", "vkAcquireNextImage2KHR"]
1701 for ext in api.extensions:
1704 for func in ext.functions:
1705 if func.getType() == functionType:
1706 # only add functions with same vendor as extension
1707 # this is a workaroudn for entrypoints requiring more
1708 # than one excetions and lack of the dependency in vulkan_core.h
1709 vendor = ext.name.split('_')[1]
1710 if func.name.endswith(vendor):
1711 funcNames.append(func.name)
1713 yield '\tif (extName == "%s")' % ext.name
1715 for funcName in funcNames:
1716 if funcName in dg_list:
1717 yield '\t\tif(apiVersion >= VK_API_VERSION_1_1) functions.push_back("%s");' % funcName
1719 yield '\t\tfunctions.push_back("%s");' % funcName
1720 if ext.name == "VK_KHR_device_group":
1721 for dg_func in dg_list:
1722 yield '\t\tif(apiVersion < VK_API_VERSION_1_1) functions.push_back("%s");' % dg_func
1725 isFirstWrite = False
1726 if not isFirstWrite:
1727 yield '\tDE_FATAL("Extension name not found");'
1731 for line in writeExtensionFunctions(Function.TYPE_INSTANCE):
1734 for line in writeExtensionFunctions(Function.TYPE_DEVICE):
1737 for line in writeExtensionNameArrays():
1740 writeInlFile(filename, INL_HEADER, lines)
1742 def writeCoreFunctionalities(api, filename):
1743 functionOriginValues = ["FUNCTIONORIGIN_PLATFORM", "FUNCTIONORIGIN_INSTANCE", "FUNCTIONORIGIN_DEVICE"]
1744 lines = addVersionDefines(api.versions) + [
1746 'enum FunctionOrigin', '{'] + [line for line in indentLines([
1747 '\t' + functionOriginValues[0] + '\t= 0,',
1748 '\t' + functionOriginValues[1] + ',',
1749 '\t' + functionOriginValues[2]])] + [
1752 "typedef ::std::pair<const char*, FunctionOrigin> FunctionInfo;",
1753 "typedef ::std::vector<FunctionInfo> FunctionInfosList;",
1754 "typedef ::std::map<uint32_t, FunctionInfosList> ApisMap;",
1756 "void initApisMap (ApisMap& apis)",
1758 " apis.clear();"] + [
1759 " apis.insert(::std::pair<uint32_t, FunctionInfosList>(" + str(v) + ", FunctionInfosList()));" for v in api.versions] + [
1763 for index, v in enumerate(api.versions):
1765 apiVersions.append("VK_VERSION_{0}_{1}".format(v.major, v.minor))
1766 # iterate over all functions that are core in latest vulkan version
1767 # note that first item in api.extension array are actually all definitions that are in vulkan.h.in before section with extensions
1768 for fun in api.extensions[0].functions:
1769 if fun.apiVersion in apiVersions:
1770 funcs.append(' apis[' + str(v) + '].push_back(FunctionInfo("' + fun.name + '",\t' + functionOriginValues[fun.getType()] + '));')
1771 lines = lines + [line for line in indentLines(funcs)] + [""]
1773 lines = lines + ["}", ""] + removeVersionDefines(api.versions)
1774 writeInlFile(filename, INL_HEADER, lines)
1776 def writeDeviceFeatures2(api, filename):
1777 # list of structures that should be tested with getPhysicalDeviceFeatures2
1778 # this is not posible to determine from vulkan_core.h, if new feature structures
1779 # are added they should be manualy added to this list
1780 testedStructures = [
1781 'VkPhysicalDevice4444FormatsFeaturesEXT',
1782 'VkPhysicalDevice8BitStorageFeatures',
1783 'VkPhysicalDevice16BitStorageFeatures',
1784 'VkPhysicalDeviceAccelerationStructureFeaturesKHR',
1785 'VkPhysicalDeviceASTCDecodeFeaturesEXT',
1786 'VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT',
1787 'VkPhysicalDeviceBufferDeviceAddressFeaturesEXT',
1788 'VkPhysicalDeviceBufferDeviceAddressFeatures',
1789 'VkPhysicalDeviceConditionalRenderingFeaturesEXT',
1790 'VkPhysicalDeviceCustomBorderColorFeaturesEXT',
1791 'VkPhysicalDeviceColorWriteEnableFeaturesEXT',
1792 'VkPhysicalDeviceDescriptorIndexingFeatures',
1793 'VkPhysicalDeviceDepthClipEnableFeaturesEXT',
1794 'VkPhysicalDeviceDynamicRenderingFeatures',
1795 'VkPhysicalDeviceExtendedDynamicStateFeaturesEXT',
1796 'VkPhysicalDeviceExtendedDynamicState2FeaturesEXT',
1797 'VkPhysicalDeviceFragmentDensityMapFeaturesEXT',
1798 'VkPhysicalDeviceFragmentDensityMap2FeaturesEXT',
1799 'VkPhysicalDeviceFragmentShadingRateFeaturesKHR',
1800 'VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR',
1801 'VkPhysicalDeviceInlineUniformBlockFeatures',
1802 'VkPhysicalDeviceIndexTypeUint8FeaturesEXT',
1803 'VkPhysicalDeviceImagelessFramebufferFeatures',
1804 'VkPhysicalDeviceImageRobustnessFeatures',
1805 'VkPhysicalDeviceHostQueryResetFeatures',
1806 'VkPhysicalDeviceLineRasterizationFeaturesEXT',
1807 'VkPhysicalDeviceMaintenance4Features',
1808 'VkPhysicalDeviceMultiviewFeatures',
1809 'VkPhysicalDeviceMultiDrawFeaturesEXT',
1810 'VkPhysicalDeviceMemoryPriorityFeaturesEXT',
1811 'VkPhysicalDeviceDeviceMemoryReportFeaturesEXT',
1812 'VkPhysicalDevicePerformanceQueryFeaturesKHR',
1813 'VkPhysicalDevicePipelineCreationCacheControlFeatures',
1814 'VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR',
1815 'VkPhysicalDevicePresentIdFeaturesKHR',
1816 'VkPhysicalDevicePresentWaitFeaturesKHR',
1817 'VkPhysicalDeviceProtectedMemoryFeatures',
1818 'VkPhysicalDeviceProvokingVertexFeaturesEXT',
1819 'VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT',
1820 'VkPhysicalDevicePrivateDataFeatures',
1821 'VkPhysicalDeviceRayTracingPipelineFeaturesKHR',
1822 'VkPhysicalDeviceRayQueryFeaturesKHR',
1823 'VkPhysicalDeviceRobustness2FeaturesEXT',
1824 'VkPhysicalDeviceSamplerYcbcrConversionFeatures',
1825 'VkPhysicalDeviceScalarBlockLayoutFeatures',
1826 'VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures',
1827 'VkPhysicalDeviceShaderAtomicInt64Features',
1828 'VkPhysicalDeviceShaderAtomicFloatFeaturesEXT',
1829 'VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT',
1830 'VkPhysicalDeviceShaderFloat16Int8Features',
1831 'VkPhysicalDeviceShaderClockFeaturesKHR',
1832 'VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures',
1833 'VkPhysicalDeviceShaderDrawParametersFeatures',
1834 'VkPhysicalDeviceShaderIntegerDotProductFeatures',
1835 'VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures',
1836 'VkPhysicalDeviceShaderTerminateInvocationFeatures',
1837 'VkPhysicalDeviceSubgroupSizeControlFeatures',
1838 'VkPhysicalDeviceSynchronization2Features',
1839 'VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT',
1840 'VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT',
1841 'VkPhysicalDeviceTextureCompressionASTCHDRFeatures',
1842 'VkPhysicalDeviceTimelineSemaphoreFeatures',
1843 'VkPhysicalDeviceTransformFeedbackFeaturesEXT',
1844 'VkPhysicalDeviceUniformBufferStandardLayoutFeatures',
1845 'VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR',
1846 'VkPhysicalDeviceVariablePointersFeatures',
1847 'VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT',
1848 'VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT',
1849 'VkPhysicalDeviceVulkanMemoryModelFeaturesKHR',
1850 'VkPhysicalDeviceYcbcrImageArraysFeaturesEXT',
1851 'VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT',
1852 'VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures',
1855 # helper class used to encapsulate all data needed during generation
1856 class StructureDetail:
1857 def __init__ (self, name):
1858 nameResult = re.search('(.*)Features(.*)', name[len('VkPhysicalDevice'):])
1860 # generate structure type name from structure name
1861 # note that sometimes digits are separated with '_':
1862 # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT
1863 # but mostly they are not:
1864 # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES
1866 'FragmentDensityMap2' : ['FRAGMENT', 'DENSITY', 'MAP', '2'],
1867 'Ycbcr2Plane444Formats' : ['YCBCR', '2', 'PLANE', '444', 'FORMATS'],
1868 'ASTCDecode' : ['ASTC', 'DECODE'],
1869 '4444Formats' : ['4444', 'FORMATS'],
1870 'TextureCompressionASTCHDR' : ['TEXTURE', 'COMPRESSION', 'ASTC', 'HDR'],
1871 'Synchronization2' : ['SYNCHRONIZATION', '2'],
1872 'ShaderAtomicFloat2' : ['SHADER', 'ATOMIC', 'FLOAT', '2'],
1873 'Robustness2' : ['ROBUSTNESS', '2'],
1874 'Maintenance4' : ['MAINTENANCE', '4'],
1875 'ExtendedDynamicState2' : ['EXTENDED', 'DYNAMIC', 'STATE', '2'],
1877 nameSplitUp = specialCaseDict.get(nameResult.group(1))
1878 if nameSplitUp == None:
1879 nameSplit = re.findall(r'[1-9A-Z]+(?:[a-z1-9]+|[A-Z]*(?=[A-Z]|$))', nameResult.group(1))
1880 nameSplitUp = map(str.upper, nameSplit)
1881 nameSplitUp = list(nameSplitUp) + ['FEATURES']
1882 # check if there is extension suffix
1883 if (len(nameResult.group(2)) != 0):
1884 nameSplitUp.append(nameResult.group(2))
1886 self.sType = 'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_' + '_'.join(nameSplitUp)
1887 self.instanceName = 'd' + name[11:]
1888 self.flagName = 'is' + name[16:]
1889 self.extension = None
1893 # helper extension class used in algorith below
1894 class StructureFoundContinueToNextOne(Exception):
1896 testedStructureDetail = [StructureDetail(struct) for struct in testedStructures]
1897 # iterate over all searched structures and find extensions that enable them
1898 for structureDetail in testedStructureDetail:
1900 # iterate over all extensions
1901 for extension in api.extensions[1:]:
1902 # check composite types and typedefs in case extension is part of core
1903 for structureList in [extension.compositeTypes, extension.typedefs]:
1904 # iterate over all structures added by extension
1905 for extensionStructure in structureList:
1906 # compare checked structure name to name of structure from extension
1907 if structureDetail.name == extensionStructure.name:
1908 structureDetail.extension = extension.name
1909 if extension.versionInCore is not None:
1910 structureDetail.major = extension.versionInCore[1]
1911 structureDetail.minor = extension.versionInCore[2]
1912 raise StructureFoundContinueToNextOne
1913 except StructureFoundContinueToNextOne:
1915 for structureDetail in testedStructureDetail:
1916 for compositeType in api.compositeTypes:
1917 if structureDetail.name != compositeType.name:
1919 structureMembers = compositeType.members[2:]
1920 structureDetail.members = [m.name for m in structureMembers]
1921 if structureDetail.major is not None:
1923 # if structure was not added with extension then check if
1924 # it was added directly with one of vulkan versions
1925 apiVersion = compositeType.apiVersion
1926 if apiVersion is None:
1928 structureDetail.major = apiVersion.major
1929 structureDetail.minor = apiVersion.minor
1931 # generate file content
1932 structureDefinitions = []
1933 featureEnabledFlags = []
1934 clearStructures = []
1937 verifyStructures = []
1938 for index, structureDetail in enumerate(testedStructureDetail):
1939 # create two instances of each structure
1940 nameSpacing = '\t' * int((67 - len(structureDetail.name)) / 4)
1941 structureDefinitions.append(structureDetail.name + nameSpacing + structureDetail.instanceName + '[count];')
1942 # create flags that check if proper extension or vulkan version is available
1944 extension = structureDetail.extension
1945 major = structureDetail.major
1946 if extension is not None:
1947 condition = ' checkExtension(properties, "' + extension + '")'
1948 if major is not None:
1950 condition += '\t' * int((47 - len(extension)) / 4) + '|| '
1952 condition += '\t' * 19 + ' '
1953 condition += 'context.contextSupports(vk::ApiVersion(' + str(major) + ', ' + str(structureDetail.minor) + ', 0))'
1955 nameSpacing = '\t' * int((48 - len(structureDetail.flagName)) / 4)
1956 featureEnabledFlags.append('const bool ' + structureDetail.flagName + nameSpacing + '=' + condition)
1957 # clear memory of each structure
1958 nameSpacing = '\t' * int((51 - len(structureDetail.instanceName)) / 4)
1959 clearStructures.append('\tdeMemset(&' + structureDetail.instanceName + '[ndx],' + nameSpacing + '0xFF * ndx, sizeof(' + structureDetail.name + '));')
1960 # construct structure chain
1961 nextInstanceName = 'DE_NULL';
1962 if index < len(testedStructureDetail)-1:
1963 nextInstanceName = '&' + testedStructureDetail[index+1].instanceName + '[ndx]'
1964 structureChain.append('\t' + structureDetail.instanceName + '[ndx].sType = ' + structureDetail.flagName + ' ? ' + structureDetail.sType + ' : VK_STRUCTURE_TYPE_MAX_ENUM;')
1965 structureChain.append('\t' + structureDetail.instanceName + '[ndx].pNext = ' + nextInstanceName + ';\n')
1966 # construct log section
1967 logStructures.append('if (' + structureDetail.flagName + ')')
1968 logStructures.append('\tlog << TestLog::Message << ' + structureDetail.instanceName + '[0] << TestLog::EndMessage;')
1969 #construct verification section
1970 verifyStructures.append('if (' + structureDetail.flagName + ' &&')
1971 for index, m in enumerate(structureDetail.members):
1972 prefix = '\t(' if index == 0 else '\t '
1973 postfix = '))' if index == len(structureDetail.members)-1 else ' ||'
1974 verifyStructures.append(prefix + structureDetail.instanceName + '[0].' + m + ' != ' + structureDetail.instanceName + '[1].' + m + postfix)
1975 verifyStructures.append('{\n\t\tTCU_FAIL("Mismatch between ' + structureDetail.name + '");\n}')
1976 # construct file content
1978 stream.extend(structureDefinitions)
1980 stream.extend(featureEnabledFlags)
1981 stream.append('\nfor (int ndx = 0; ndx < count; ++ndx)\n{')
1982 stream.extend(clearStructures)
1984 stream.extend(structureChain)
1985 stream.append('\tdeMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));\n'
1986 '\textFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;\n'
1987 '\textFeatures.pNext = &' + testedStructureDetail[0].instanceName + '[ndx];\n'
1988 '\tvki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);\n}\n')
1989 stream.extend(logStructures)
1991 stream.extend(verifyStructures)
1992 writeInlFile(filename, INL_HEADER, stream)
1994 def generateDeviceFeaturesDefs(src):
1995 # look for definitions
1996 ptrnSType = r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_FEATURES(\w*)\s*='
1997 matches = re.findall(ptrnSType, src, re.M)
1998 matches = sorted(matches, key=lambda m: m[0])
1999 # construct final list
2001 for sType, sSuffix in matches:
2002 structName = re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '')
2003 ptrnStructName = r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Features' + sSuffix.replace('_', '') + ')'
2004 matchStructName = re.search(ptrnStructName, src, re.IGNORECASE)
2006 # handle special cases
2007 if sType == "EXCLUSIVE_SCISSOR":
2008 sType = "SCISSOR_EXCLUSIVE"
2009 elif sType == "ASTC_DECODE":
2010 sType = "ASTC_DECODE_MODE"
2011 elif sType == "MAINTENANCE_4":
2012 sType = "MAINTENANCE4"
2013 elif sType == "YCBCR_2_PLANE_444_FORMATS":
2014 sType = "YCBCR_2PLANE_444_FORMATS"
2015 elif sType in {'VULKAN_1_1', 'VULKAN_1_2', 'VULKAN_1_3'}:
2017 elif sType == 'RASTERIZATION_ORDER_ATTACHMENT_ACCESS':
2018 # skip case that has const pNext pointer
2020 # skip cases that have const pNext pointer
2021 if sType == 'RASTERIZATION_ORDER_ATTACHMENT_ACCESS':
2023 # skip cases that have const pNext pointer
2024 if sType == 'RASTERIZATION_ORDER_ATTACHMENT_ACCESS':
2026 # end handling special cases
2027 ptrnExtensionName = r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_EXTENSION_NAME).+$'
2028 matchExtensionName = re.search(ptrnExtensionName, src, re.M)
2029 ptrnSpecVersion = r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_SPEC_VERSION).+$'
2030 matchSpecVersion = re.search(ptrnSpecVersion, src, re.M)
2031 defs.append( (sType, '', sSuffix, matchStructName.group(1), \
2032 matchExtensionName.group(0) if matchExtensionName else None,
2033 matchExtensionName.group(1) if matchExtensionName else None,
2034 matchSpecVersion.group(1) if matchSpecVersion else '0') )
2037 def generateDevicePropertiesDefs(src):
2038 # look for definitions
2039 ptrnSType = r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_PROPERTIES(\w*)\s*='
2040 matches = re.findall(ptrnSType, src, re.M)
2041 matches = sorted(matches, key=lambda m: m[0])
2042 # construct final list
2044 for sType, sSuffix in matches:
2045 # handle special cases
2046 if sType in {'VULKAN_1_1', 'VULKAN_1_2', 'VULKAN_1_3', 'GROUP', 'MEMORY_BUDGET', 'MEMORY', 'TOOL'}:
2048 # there are cases like VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD
2049 # where 2 is after PROPERTIES - to handle this we need to split suffix to two parts
2051 sExtSuffix = sSuffix
2052 suffixStart = sSuffix.rfind('_')
2054 sVerSuffix = sSuffix[:suffixStart]
2055 sExtSuffix = sSuffix[suffixStart:]
2056 # handle special case
2060 structName = re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '')
2061 ptrnStructName = r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Properties' + sSuffix.replace('_', '') + ')'
2062 matchStructName = re.search(ptrnStructName, src, re.M)
2065 if extType == "DISCARD_RECTANGLE":
2066 extType = "DISCARD_RECTANGLES"
2067 elif extType == "DRIVER":
2068 extType = "DRIVER_PROPERTIES"
2069 elif extType == "POINT_CLIPPING":
2070 extType = "MAINTENANCE_2"
2071 elif extType == "SHADER_CORE":
2072 extType = "SHADER_CORE_PROPERTIES"
2073 elif extType == "DRM":
2074 extType = "PHYSICAL_DEVICE_DRM"
2075 # end handling special cases
2076 ptrnExtensionName = r'^\s*#define\s+(\w+' + sExtSuffix + '_' + extType + sVerSuffix +'[_0-9]*_EXTENSION_NAME).+$'
2077 matchExtensionName = re.search(ptrnExtensionName, src, re.M)
2078 ptrnSpecVersion = r'^\s*#define\s+(\w+' + sExtSuffix + '_' + extType + sVerSuffix + '[_0-9]*_SPEC_VERSION).+$'
2079 matchSpecVersion = re.search(ptrnSpecVersion, src, re.M)
2080 defs.append( (sType, sVerSuffix, sExtSuffix, matchStructName.group(1), \
2081 matchExtensionName.group(0) if matchExtensionName else None,
2082 matchExtensionName.group(1) if matchExtensionName else None,
2083 matchSpecVersion.group (1) if matchSpecVersion else '0') )
2086 def writeDeviceFeatures(api, dfDefs, filename):
2087 # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs
2088 # and construct dictionary with all of their attributes
2091 blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$")
2092 for structureType in api.compositeTypes:
2093 match = blobPattern.match(structureType.name)
2095 allMembers = [member.name for member in structureType.members]
2096 vkVersion = match.group(1)
2097 blobMembers[vkVersion] = allMembers[2:]
2098 blobStructs[vkVersion] = set()
2099 initFromBlobDefinitions = []
2100 emptyInitDefinitions = []
2101 # iterate over all feature structures
2102 allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*")
2103 nonExtFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*$")
2104 for structureType in api.compositeTypes:
2105 # skip structures that are not feature structures
2106 if not allFeaturesPattern.match(structureType.name):
2108 # skip structures that were previously identified as blobs
2109 if blobPattern.match(structureType.name):
2111 if structureType.isAlias:
2113 # skip sType and pNext and just grab third and next attributes
2114 structureMembers = structureType.members[2:]
2115 notPartOfBlob = True
2116 if nonExtFeaturesPattern.match(structureType.name):
2117 # check if this member is part of any of the blobs
2118 for blobName, blobMemberList in blobMembers.items():
2119 # if just one member is not part of this blob go to the next blob
2120 # (we asume that all members are part of blob - no need to check all)
2121 if structureMembers[0].name not in blobMemberList:
2123 # add another feature structure name to this blob
2124 blobStructs[blobName].add(structureType)
2125 # add specialization for this feature structure
2127 for member in structureMembers:
2128 memberCopying += "\tfeatureType.{0} = allFeaturesBlobs.vk{1}.{0};\n".format(member.name, blobName)
2130 "template<> void initFeatureFromBlob<{0}>({0}& featureType, const AllFeaturesBlobs& allFeaturesBlobs)\n" \
2133 "}}".format(structureType.name, memberCopying)
2134 initFromBlobDefinitions.append(wholeFunction)
2135 notPartOfBlob = False
2136 # assuming that all members are part of blob, goto next
2138 # add empty template definition as on Fedora there are issue with
2139 # linking using just generic template - all specializations are needed
2141 emptyFunction = "template<> void initFeatureFromBlob<{0}>({0}&, const AllFeaturesBlobs&) {{}}"
2142 emptyInitDefinitions.append(emptyFunction.format(structureType.name))
2143 extensionDefines = []
2144 makeFeatureDescDefinitions = []
2145 featureStructWrappers = []
2146 for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extLine, extName, specVer) in enumerate(dfDefs):
2147 extensionNameDefinition = extName
2148 if not extensionNameDefinition:
2149 extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType)
2150 # construct defines with names
2152 extensionDefines.append(extLine)
2154 extensionDefines.append('#define {0} "not_existent_feature"'.format(extensionNameDefinition))
2155 # handle special cases
2156 if sType == "SCISSOR_EXCLUSIVE":
2157 sType = "EXCLUSIVE_SCISSOR"
2158 elif sType == "ASTC_DECODE_MODE":
2159 sType = "ASTC_DECODE"
2160 elif sType == "MAINTENANCE4":
2161 sType = "MAINTENANCE_4"
2162 elif sType == "YCBCR_2PLANE_444_FORMATS":
2163 sType = "YCBCR_2_PLANE_444_FORMATS"
2164 # end handling special cases
2165 # construct makeFeatureDesc template function definitions
2166 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sVerSuffix + sExtSuffix)
2167 makeFeatureDescDefinitions.append("template<> FeatureDesc makeFeatureDesc<{0}>(void) " \
2168 "{{ return FeatureDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dfDefs)-idx))
2169 # construct CreateFeatureStruct wrapper block
2170 featureStructWrappers.append("\t{{ createFeatureStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer))
2171 # construct function that will check for which vk version structure sType is part of blob
2172 blobChecker = "deUint32 getBlobFeaturesVersion (VkStructureType sType)\n{\n" \
2173 "\tconst std::map<VkStructureType, deUint32> sTypeBlobMap\n" \
2175 # iterate over blobs with list of structures
2176 for blobName in sorted(blobStructs.keys()):
2177 blobChecker += "\t\t// Vulkan{0}\n".format(blobName)
2178 # iterate over all feature structures in current blob
2179 structuresList = list(blobStructs[blobName])
2180 structuresList = sorted(structuresList, key=lambda s: s.name)
2181 for structType in structuresList:
2182 # find definition of this structure in dfDefs
2183 structName = structType.name
2184 # handle special cases
2185 if structName == 'VkPhysicalDeviceShaderDrawParameterFeatures':
2186 structName = 'VkPhysicalDeviceShaderDrawParametersFeatures'
2187 # end handling special cases
2188 structDef = [s for s in dfDefs if s[3] == structName][0]
2189 sType = structDef[0]
2190 sSuffix = structDef[1] + structDef[2]
2191 # handle special cases
2192 if sType == "SCISSOR_EXCLUSIVE":
2193 sType = "EXCLUSIVE_SCISSOR"
2194 elif sType == "MAINTENANCE4":
2195 sType = "MAINTENANCE_4"
2196 # end handling special cases
2197 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sSuffix)
2198 tabs = "\t" * int((88 - len(sTypeName)) / 4)
2199 blobChecker += "\t\t{{ {0},{1}VK_API_VERSION_{2}_{3} }},\n".format(sTypeName, tabs, blobName[0], blobName[1])
2200 blobChecker += "\t};\n\n" \
2201 "\tauto it = sTypeBlobMap.find(sType);\n" \
2202 "\tif(it == sTypeBlobMap.end())\n" \
2204 "\treturn it->second;\n" \
2206 # combine all definition lists
2208 '#include "vkDeviceFeatures.hpp"\n',
2210 stream.extend(extensionDefines)
2212 stream.extend(initFromBlobDefinitions)
2213 stream.append('\n// generic template is not enough for some compilers')
2214 stream.extend(emptyInitDefinitions)
2216 stream.extend(makeFeatureDescDefinitions)
2218 stream.append('static const FeatureStructCreationData featureStructCreationArray[]\n{')
2219 stream.extend(featureStructWrappers)
2220 stream.append('};\n')
2221 stream.append(blobChecker)
2222 stream.append('} // vk\n')
2223 writeInlFile(filename, INL_HEADER, stream)
2225 def writeDeviceFeatureTest(api, filename):
2227 coreFeaturesPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$")
2229 # iterate over all feature structures
2230 allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*")
2231 for structureType in api.compositeTypes:
2232 # skip structures that are not feature structures
2233 if not allFeaturesPattern.match(structureType.name):
2235 # skip alias structures
2236 if structureType.isAlias:
2238 # skip sType and pNext and just grab third and next attributes
2239 structureMembers = structureType.members[2:]
2242 for member in structureMembers:
2243 items.append(" FEATURE_ITEM ({0}, {1}),".format(structureType.name, member.name))
2246 "if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<{0}>()))\n" \
2248 " static const Feature features[] =\n" \
2252 " auto* supportedFeatures = reinterpret_cast<const {0}*>(featuresStruct);\n" \
2253 " checkFeatures(vkp, instance, instanceDriver, physicalDevice, {2}, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, {3}, emptyDeviceFeatures);\n" \
2255 featureItems.append(testBlock.format(structureType.name, "\n".join(items), len(items), ("DE_NULL" if coreFeaturesPattern.match(structureType.name) else "&extensionNames")))
2258 stream.extend(featureItems)
2259 writeInlFile(filename, INL_HEADER, stream)
2261 def writeDeviceProperties(api, dpDefs, filename):
2262 # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs
2263 # and construct dictionary with all of their attributes
2266 blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Properties[0-9]*$")
2267 for structureType in api.compositeTypes:
2268 match = blobPattern.match(structureType.name)
2270 allMembers = [member.name for member in structureType.members]
2271 vkVersion = match.group(1)
2272 blobMembers[vkVersion] = allMembers[2:]
2273 blobStructs[vkVersion] = set()
2274 initFromBlobDefinitions = []
2275 emptyInitDefinitions = []
2276 # iterate over all property structures
2277 allPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*")
2278 nonExtPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*$")
2279 for structureType in api.compositeTypes:
2280 # skip structures that are not property structures
2281 if not allPropertiesPattern.match(structureType.name):
2283 # skip structures that were previously identified as blobs
2284 if blobPattern.match(structureType.name):
2286 if structureType.isAlias:
2288 # skip sType and pNext and just grab third and next attributes
2289 structureMembers = structureType.members[2:]
2290 notPartOfBlob = True
2291 if nonExtPropertiesPattern.match(structureType.name):
2292 # check if this member is part of any of the blobs
2293 for blobName, blobMemberList in blobMembers.items():
2294 # if just one member is not part of this blob go to the next blob
2295 # (we asume that all members are part of blob - no need to check all)
2296 if structureMembers[0].name not in blobMemberList:
2298 # add another property structure name to this blob
2299 blobStructs[blobName].add(structureType)
2300 # add specialization for this property structure
2302 for member in structureMembers:
2303 if not member.arraySize:
2304 # handle special case
2305 if structureType.name == "VkPhysicalDeviceSubgroupProperties" and "subgroup" not in member.name :
2306 blobMemberName = "subgroup" + member.name[0].capitalize() + member.name[1:]
2307 memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{2};\n".format(member.name, blobName, blobMemberName)
2308 # end handling special case
2310 memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{0};\n".format(member.name, blobName)
2312 memberCopying += "\tmemcpy(propertyType.{0}, allPropertiesBlobs.vk{1}.{0}, sizeof({2}) * {3});\n".format(member.name, blobName, member.type[0], member.arraySize[1:-1])
2314 "template<> void initPropertyFromBlob<{0}>({0}& propertyType, const AllPropertiesBlobs& allPropertiesBlobs)\n" \
2317 "}}".format(structureType.name, memberCopying)
2318 initFromBlobDefinitions.append(wholeFunction)
2319 notPartOfBlob = False
2320 # assuming that all members are part of blob, goto next
2322 # add empty template definition as on Fedora there are issue with
2323 # linking using just generic template - all specializations are needed
2325 emptyFunction = "template<> void initPropertyFromBlob<{0}>({0}&, const AllPropertiesBlobs&) {{}}"
2326 emptyInitDefinitions.append(emptyFunction.format(structureType.name))
2327 extensionDefines = []
2328 makePropertyDescDefinitions = []
2329 propertyStructWrappers = []
2330 for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extLine, extName, specVer) in enumerate(dpDefs):
2331 extensionNameDefinition = extName
2332 if not extensionNameDefinition:
2333 extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType)
2334 # construct defines with names
2336 extensionDefines.append(extLine)
2338 extensionDefines.append('#define {0} "core_property"'.format(extensionNameDefinition))
2339 # construct makePropertyDesc template function definitions
2340 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sVerSuffix + sExtSuffix)
2341 makePropertyDescDefinitions.append("template<> PropertyDesc makePropertyDesc<{0}>(void) " \
2342 "{{ return PropertyDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dpDefs)-idx))
2343 # construct CreateProperty struct wrapper block
2344 propertyStructWrappers.append("\t{{ createPropertyStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer))
2345 # construct method that will check if structure sType is part of blob
2346 blobChecker = "deUint32 getBlobPropertiesVersion (VkStructureType sType)\n{\n" \
2347 "\tconst std::map<VkStructureType, deUint32> sTypeBlobMap\n" \
2349 # iterate over blobs with list of structures
2350 for blobName in sorted(blobStructs.keys()):
2351 blobChecker += "\t\t// Vulkan{0}\n".format(blobName)
2352 # iterate over all feature structures in current blob
2353 structuresList = list(blobStructs[blobName])
2354 structuresList = sorted(structuresList, key=lambda s: s.name)
2355 for structType in structuresList:
2356 # find definition of this structure in dpDefs
2357 structName = structType.name
2358 structDef = [s for s in dpDefs if s[3] == structName][0]
2359 sType = structDef[0]
2360 sSuffix = structDef[1] + structDef[2]
2361 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sSuffix)
2362 tabs = "\t" * int((76 - len(sTypeName)) / 4)
2363 blobChecker += "\t\t{{ {0},{1}VK_API_VERSION_{2}_{3} }},\n".format(sTypeName, tabs, blobName[0], blobName[1])
2364 blobChecker += "\t};\n\n" \
2365 "\tauto it = sTypeBlobMap.find(sType);\n" \
2366 "\tif(it == sTypeBlobMap.end())\n" \
2368 "\treturn it->second;\n" \
2370 # combine all definition lists
2372 '#include "vkDeviceProperties.hpp"\n',
2374 stream.extend(extensionDefines)
2376 stream.extend(initFromBlobDefinitions)
2377 stream.append('\n// generic template is not enough for some compilers')
2378 stream.extend(emptyInitDefinitions)
2380 stream.extend(makePropertyDescDefinitions)
2382 stream.append('static const PropertyStructCreationData propertyStructCreationArray[] =\n{')
2383 stream.extend(propertyStructWrappers)
2384 stream.append('};\n')
2385 stream.append(blobChecker)
2386 stream.append('} // vk\n')
2387 writeInlFile(filename, INL_HEADER, stream)
2389 def genericDeviceFeaturesWriter(dfDefs, pattern, filename):
2391 for _, _, _, extStruct, _, _, _ in dfDefs:
2392 nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
2393 stream.append(pattern.format(extStruct, nameSubStr))
2394 writeInlFile(filename, INL_HEADER, indentLines(stream))
2396 def writeDeviceFeaturesDefaultDeviceDefs(dfDefs, filename):
2397 pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceFeatures.getFeatureType<{0}>();\t}}"
2398 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2400 def writeDeviceFeaturesContextDecl(dfDefs, filename):
2401 pattern = "const vk::{0}&\tget{1}\t(void) const;"
2402 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2404 def writeDeviceFeaturesContextDefs(dfDefs, filename):
2405 pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}"
2406 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2408 def genericDevicePropertiesWriter(dfDefs, pattern, filename):
2410 for _, _, _, extStruct, _, _, _ in dfDefs:
2411 nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
2412 if extStruct == "VkPhysicalDeviceRayTracingPropertiesNV":
2414 stream.append(pattern.format(extStruct, nameSubStr))
2415 writeInlFile(filename, INL_HEADER, indentLines(stream))
2417 def writeDevicePropertiesDefaultDeviceDefs(dfDefs, filename):
2418 pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceProperties.getPropertyType<{0}>();\t}}"
2419 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2421 def writeDevicePropertiesContextDecl(dfDefs, filename):
2422 pattern = "const vk::{0}&\tget{1}\t(void) const;"
2423 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2425 def writeDevicePropertiesContextDefs(dfDefs, filename):
2426 pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}"
2427 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2429 def writeMandatoryFeatures(api, filename):
2434 for _, data in api.additionalExtensionData:
2435 if 'mandatory_features' not in data.keys():
2437 # sort to have same results for py2 and py3
2438 listStructFeatures = sorted(data['mandatory_features'].items(), key=lambda tup: tup[0])
2439 for structure, featuresList in listStructFeatures:
2440 for featureData in featuresList:
2441 assert('features' in featureData.keys())
2442 assert('requirements' in featureData.keys())
2443 requirements = featureData['requirements']
2444 dictData.append( [ structure, featureData['features'], requirements ])
2445 if structure == 'VkPhysicalDeviceFeatures':
2447 # if structure is not in dict construct name of variable and add is as a first item
2448 if (structure not in dictStructs):
2449 dictStructs[structure] = [structure[2:3].lower() + structure[3:]]
2450 # add first requirement if it is unique
2451 if requirements and (requirements[0] not in dictStructs[structure]):
2452 dictStructs[structure].append(requirements[0])
2454 stream.extend(['bool checkMandatoryFeatures(const vkt::Context& context)\n{',
2455 '\tif (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))',
2456 '\t\tTCU_THROW(NotSupportedError, "Extension VK_KHR_get_physical_device_properties2 is not present");',
2458 '\tVkPhysicalDevice\t\t\t\t\tphysicalDevice\t\t= context.getPhysicalDevice();',
2459 '\tconst InstanceInterface&\t\t\tvki\t\t\t\t\t= context.getInstanceInterface();',
2460 '\tconst vector<VkExtensionProperties>\tdeviceExtensions\t= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);',
2462 '\ttcu::TestLog& log = context.getTestContext().getLog();',
2463 '\tvk::VkPhysicalDeviceFeatures2 coreFeatures;',
2464 '\tdeMemset(&coreFeatures, 0, sizeof(coreFeatures));',
2465 '\tcoreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;',
2466 '\tvoid** nextPtr = &coreFeatures.pNext;',
2469 listStruct = sorted(dictStructs.items(), key=lambda tup: tup[0]) # sort to have same results for py2 and py3
2470 for k, v in listStruct:
2471 if (v[1].startswith("ApiVersion")):
2472 cond = '\tif (context.contextSupports(vk::' + v[1] + '))'
2474 cond = '\tif (vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "' + v[1] + '"))'
2475 stream.extend(['\tvk::' + k + ' ' + v[0]+ ';',
2476 '\tdeMemset(&' + v[0] + ', 0, sizeof(' + v[0] + '));',
2481 for i, req in enumerate(reqs) :
2482 if (req.startswith("ApiVersion")):
2483 cond = cond + 'context.contextSupports(vk::' + req + ')'
2485 cond = cond + 'isExtensionSupported(deviceExtensions, RequiredExtension("' + req + '"))'
2486 if i+1 < len(reqs) :
2487 cond = cond + ' || '
2489 stream.append('\t' + cond)
2490 stream.extend(['\t{',
2491 '\t\t' + v[0] + '.sType = getStructureType<' + k + '>();',
2492 '\t\t*nextPtr = &' + v[0] + ';',
2493 '\t\tnextPtr = &' + v[0] + '.pNext;',
2496 stream.extend(['\tcontext.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &coreFeatures);',
2497 '\tbool result = true;',
2502 structName = 'coreFeatures.features';
2503 if v[0] != 'VkPhysicalDeviceFeatures' :
2504 structName = dictStructs[v[0]][0]
2507 for i, req in enumerate(v[2]) :
2508 if (req.startswith("ApiVersion")):
2509 condition = condition + 'context.contextSupports(vk::' + req + ')'
2511 condition = condition + req
2513 condition = condition + 'isExtensionSupported(deviceExtensions, RequiredExtension("' + req + '"))'
2514 if i+1 < len(v[2]) :
2515 condition = condition + ' && '
2516 condition = condition + ' )'
2517 stream.append('\t' + condition)
2518 stream.append('\t{')
2519 # Don't need to support an AND case since that would just be another line in the .txt
2521 stream.append('\t\tif ( ' + structName + '.' + v[1][0] + ' == VK_FALSE )')
2524 for i, feature in enumerate(v[1]):
2526 condition = condition + ' && '
2527 condition = condition + '( ' + structName + '.' + feature + ' == VK_FALSE )'
2528 condition = condition + ' )'
2529 stream.append('\t\t' + condition)
2530 featureSet = " or ".join(v[1])
2531 stream.extend(['\t\t{',
2532 '\t\t\tlog << tcu::TestLog::Message << "Mandatory feature ' + featureSet + ' not supported" << tcu::TestLog::EndMessage;',
2533 '\t\t\tresult = false;',
2537 stream.append('\treturn result;')
2538 stream.append('}\n')
2539 writeInlFile(filename, INL_HEADER, stream)
2541 def writeExtensionList(api, filename, extensionType):
2543 for extensionName, data in api.additionalExtensionData:
2544 # make sure extension name starts with VK_KHR
2545 if not extensionName.startswith('VK_KHR'):
2547 # make sure that this extension was registered
2548 if 'register_extension' not in data.keys():
2550 # make sure extension has proper type
2551 if extensionType == data['register_extension']['type']:
2552 extensionList.append(extensionName)
2553 extensionList.sort()
2554 # write list of all found extensions
2556 stream.append('static const char* s_allowed{0}KhrExtensions[] =\n{{'.format(extensionType.title()))
2557 for n in extensionList:
2558 stream.append('\t"' + n + '",')
2559 stream.append('};\n')
2560 writeInlFile(filename, INL_HEADER, stream)
2562 def preprocessTopInclude(src, dir):
2563 pattern = r'#include\s+"([^\n]+)"'
2565 inc = re.search(pattern, src)
2568 incFileName = inc.string[inc.start(1):inc.end(1)]
2569 patternIncNamed = r'#include\s+"' + incFileName + '"'
2570 incBody = readFile(os.path.join(dir, incFileName)) if incFileName != 'vk_platform.h' else ''
2571 incBodySanitized = re.sub(pattern, '', incBody)
2572 bodyEndSanitized = re.sub(patternIncNamed, '', src[inc.end(0):])
2573 src = src[0:inc.start(0)] + incBodySanitized + bodyEndSanitized
2576 if __name__ == "__main__":
2578 outputPath = os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan")
2579 # if argument was specified it is interpreted as a path to which .inl files will be written
2580 if len(sys.argv) > 1:
2581 outputPath = str(sys.argv[1])
2583 # Generate vulkan headers from vk.xml
2584 currentDir = os.getcwd()
2585 pythonExecutable = sys.executable or "python"
2586 os.chdir(os.path.join(VULKAN_HEADERS_INCLUDE_DIR, "..", "xml"))
2601 "vulkan_xlib_xrandr.h",
2603 for target in vkTargets:
2604 execute([pythonExecutable, "../scripts/genvk.py", "-o", "../include/vulkan", target])
2606 videoDir = "../include/vk_video"
2607 if (not os.path.isdir(videoDir)):
2611 'vulkan_video_codecs_common.h',
2612 'vulkan_video_codec_h264std.h',
2613 'vulkan_video_codec_h264std_decode.h',
2614 'vulkan_video_codec_h264std_encode.h',
2615 'vulkan_video_codec_h265std.h',
2616 'vulkan_video_codec_h265std_decode.h',
2617 'vulkan_video_codec_h265std_encode.h',
2619 for target in videoTargets:
2620 execute([pythonExecutable, "../scripts/genvk.py", "-registry", "video.xml", "-o", videoDir, target])
2622 os.chdir(currentDir)
2624 # Read all .h files and make sure vulkan_core.h is first out of vulkan files
2625 vkTargets.remove("vulkan_core.h")
2627 vkTargets.insert(0, "vulkan_core.h")
2628 vkFilesWithCatalog = [os.path.join("vulkan", f) for f in vkTargets]
2631 for file in vkFilesWithCatalog:
2632 src += preprocessTopInclude(readFile(os.path.join(VULKAN_HEADERS_INCLUDE_DIR,file)), VULKAN_HEADERS_INCLUDE_DIR)
2634 src = re.sub('\s*//[^\n]*', '', src)
2635 src = re.sub('\n\n', '\n', src)
2639 platformFuncs = [Function.TYPE_PLATFORM]
2640 instanceFuncs = [Function.TYPE_INSTANCE]
2641 deviceFuncs = [Function.TYPE_DEVICE]
2643 dfd = generateDeviceFeaturesDefs(src)
2644 writeDeviceFeatures (api, dfd, os.path.join(outputPath, "vkDeviceFeatures.inl"))
2645 writeDeviceFeaturesDefaultDeviceDefs (dfd, os.path.join(outputPath, "vkDeviceFeaturesForDefaultDeviceDefs.inl"))
2646 writeDeviceFeaturesContextDecl (dfd, os.path.join(outputPath, "vkDeviceFeaturesForContextDecl.inl"))
2647 writeDeviceFeaturesContextDefs (dfd, os.path.join(outputPath, "vkDeviceFeaturesForContextDefs.inl"))
2648 writeDeviceFeatureTest (api, os.path.join(outputPath, "vkDeviceFeatureTest.inl"))
2650 dpd = generateDevicePropertiesDefs(src)
2651 writeDeviceProperties (api, dpd, os.path.join(outputPath, "vkDeviceProperties.inl"))
2653 writeDevicePropertiesDefaultDeviceDefs (dpd, os.path.join(outputPath, "vkDevicePropertiesForDefaultDeviceDefs.inl"))
2654 writeDevicePropertiesContextDecl (dpd, os.path.join(outputPath, "vkDevicePropertiesForContextDecl.inl"))
2655 writeDevicePropertiesContextDefs (dpd, os.path.join(outputPath, "vkDevicePropertiesForContextDefs.inl"))
2657 writeHandleType (api, os.path.join(outputPath, "vkHandleType.inl"))
2658 writeBasicTypes (api, os.path.join(outputPath, "vkBasicTypes.inl"))
2659 writeCompositeTypes (api, os.path.join(outputPath, "vkStructTypes.inl"))
2660 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualPlatformInterface.inl"), platformFuncs, False)
2661 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualInstanceInterface.inl"), instanceFuncs, False)
2662 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualDeviceInterface.inl"), deviceFuncs, False)
2663 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcretePlatformInterface.inl"), platformFuncs, True)
2664 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcreteInstanceInterface.inl"), instanceFuncs, True)
2665 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcreteDeviceInterface.inl"), deviceFuncs, True)
2666 writeFunctionPtrTypes (api, os.path.join(outputPath, "vkFunctionPointerTypes.inl"))
2667 writeFunctionPointers (api, os.path.join(outputPath, "vkPlatformFunctionPointers.inl"), platformFuncs)
2668 writeFunctionPointers (api, os.path.join(outputPath, "vkInstanceFunctionPointers.inl"), instanceFuncs)
2669 writeFunctionPointers (api, os.path.join(outputPath, "vkDeviceFunctionPointers.inl"), deviceFuncs)
2670 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitPlatformFunctionPointers.inl"), platformFuncs, lambda f: f.name != "vkGetInstanceProcAddr")
2671 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitInstanceFunctionPointers.inl"), instanceFuncs)
2672 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitDeviceFunctionPointers.inl"), deviceFuncs)
2673 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkPlatformDriverImpl.inl"), platformFuncs, "PlatformDriver")
2674 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkInstanceDriverImpl.inl"), instanceFuncs, "InstanceDriver")
2675 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkDeviceDriverImpl.inl"), deviceFuncs, "DeviceDriver")
2676 writeStrUtilProto (api, os.path.join(outputPath, "vkStrUtil.inl"))
2677 writeStrUtilImpl (api, os.path.join(outputPath, "vkStrUtilImpl.inl"))
2678 writeRefUtilProto (api, os.path.join(outputPath, "vkRefUtil.inl"))
2679 writeRefUtilImpl (api, os.path.join(outputPath, "vkRefUtilImpl.inl"))
2680 writeStructTraitsImpl (api, os.path.join(outputPath, "vkGetStructureTypeImpl.inl"))
2681 writeNullDriverImpl (api, os.path.join(outputPath, "vkNullDriverImpl.inl"))
2682 writeTypeUtil (api, os.path.join(outputPath, "vkTypeUtil.inl"))
2683 writeSupportedExtenions (api, os.path.join(outputPath, "vkSupportedExtensions.inl"))
2684 writeCoreFunctionalities (api, os.path.join(outputPath, "vkCoreFunctionalities.inl"))
2685 writeExtensionFunctions (api, os.path.join(outputPath, "vkExtensionFunctions.inl"))
2686 writeDeviceFeatures2 (api, os.path.join(outputPath, "vkDeviceFeatures2.inl"))
2687 writeMandatoryFeatures (api, os.path.join(outputPath, "vkMandatoryFeatures.inl"))
2688 writeExtensionList (api, os.path.join(outputPath, "vkInstanceExtensions.inl"), 'instance')
2689 writeExtensionList (api, os.path.join(outputPath, "vkDeviceExtensions.inl"), 'device')
2690 writeDriverIds ( os.path.join(outputPath, "vkKnownDriverIds.inl"))
2691 writeObjTypeImpl (api, os.path.join(outputPath, "vkObjTypeImpl.inl"))
2692 # NOTE: when new files are generated then they should also be added to the
2693 # vk-gl-cts\external\vulkancts\framework\vulkan\CMakeLists.txt outputs list