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 #-------------------------------------------------------------------------
30 from itertools import chain
31 from collections import OrderedDict
33 sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..", "scripts"))
35 from build.common import DEQP_DIR, execute
36 from khr_util.format import indentLines, writeInlFile
38 VULKAN_HEADERS_INCLUDE_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "vulkan-docs", "src", "include")
39 SCRIPTS_SRC_DIR = os.path.join(os.path.dirname(__file__), "src")
40 DEFAULT_OUTPUT_DIR = { "" : os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan", "generated", "vulkan"),
41 "SC" : os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan", "generated", "vulkansc") }
44 /* WARNING: This is auto-generated file. Do not modify, since changes will
45 * be lost! Modify the generating script instead.
46 * This file was generated by /scripts/gen_framework.py
52 ("VK_MAX_PHYSICAL_DEVICE_NAME_SIZE", "size_t"),
53 ("VK_MAX_EXTENSION_NAME_SIZE", "size_t"),
54 ("VK_MAX_DRIVER_NAME_SIZE", "size_t"),
55 ("VK_MAX_DRIVER_INFO_SIZE", "size_t"),
56 ("VK_UUID_SIZE", "size_t"),
57 ("VK_LUID_SIZE", "size_t"),
58 ("VK_MAX_MEMORY_TYPES", "size_t"),
59 ("VK_MAX_MEMORY_HEAPS", "size_t"),
60 ("VK_MAX_DESCRIPTION_SIZE", "size_t"),
61 ("VK_MAX_DEVICE_GROUP_SIZE", "size_t"),
62 ("VK_ATTACHMENT_UNUSED", "uint32_t"),
63 ("VK_SUBPASS_EXTERNAL", "uint32_t"),
64 ("VK_QUEUE_FAMILY_IGNORED", "uint32_t"),
65 ("VK_QUEUE_FAMILY_EXTERNAL", "uint32_t"),
66 ("VK_REMAINING_MIP_LEVELS", "uint32_t"),
67 ("VK_REMAINING_ARRAY_LAYERS", "uint32_t"),
68 ("VK_WHOLE_SIZE", "vk::VkDeviceSize"),
69 ("VK_TRUE", "vk::VkBool32"),
70 ("VK_FALSE", "vk::VkBool32"),
75 (["Display","*"], ["XlibDisplayPtr"], "void*"),
76 (["Window"], ["XlibWindow"], "uintptr_t",),
77 (["VisualID"], ["XlibVisualID"], "uint32_t"),
80 (["xcb_connection_t", "*"], ["XcbConnectionPtr"], "void*"),
81 (["xcb_window_t"], ["XcbWindow"], "uintptr_t"),
82 (["xcb_visualid_t"], ["XcbVisualid"], "uint32_t"),
84 # VK_KHR_wayland_surface
85 (["struct", "wl_display","*"], ["WaylandDisplayPtr"], "void*"),
86 (["struct", "wl_surface", "*"], ["WaylandSurfacePtr"], "void*"),
89 (["MirConnection", "*"], ["MirConnectionPtr"], "void*"),
90 (["MirSurface", "*"], ["MirSurfacePtr"], "void*"),
92 # VK_KHR_android_surface
93 (["ANativeWindow", "*"], ["AndroidNativeWindowPtr"], "void*"),
95 # VK_KHR_win32_surface
96 (["HINSTANCE"], ["Win32InstanceHandle"], "void*"),
97 (["HWND"], ["Win32WindowHandle"], "void*"),
98 (["HANDLE"], ["Win32Handle"], "void*"),
99 (["const", "SECURITY_ATTRIBUTES", "*"], ["Win32SecurityAttributesPtr"], "const void*"),
100 (["AHardwareBuffer", "*"], ["AndroidHardwareBufferPtr"], "void*"),
101 (["HMONITOR"], ["Win32MonitorHandle"], "void*"),
102 (["LPCWSTR"], ["Win32LPCWSTR"], "const void*"),
104 # VK_EXT_acquire_xlib_display
105 (["RROutput"], ["RROutput"], "void*"),
107 (["zx_handle_t"], ["zx_handle_t"], "uint32_t"),
108 (["GgpFrameToken"], ["GgpFrameToken"], "int32_t"),
109 (["GgpStreamDescriptor"], ["GgpStreamDescriptor"], "int32_t"),
110 (["CAMetalLayer"], ["CAMetalLayer"], "void*"),
112 # VK_EXT_metal_objects
113 (["MTLDevice_id"], ["MTLDevice_id"], "void*"),
114 (["MTLCommandQueue_id"], ["MTLCommandQueue_id"], "void*"),
115 (["MTLBuffer_id"], ["MTLBuffer_id"], "void*"),
116 (["MTLTexture_id"], ["MTLTexture_id"], "void*"),
117 (["IOSurfaceRef"], ["IOSurfaceRef"], "void*"),
118 (["MTLSharedEvent_id"], ["MTLSharedEvent_id"], "void*"),
121 PLATFORM_TYPE_NAMESPACE = "pt"
123 TYPE_SUBSTITUTIONS = [
125 ("DWORD", "uint32_t"),
126 ("HANDLE*", PLATFORM_TYPE_NAMESPACE + "::" + "Win32Handle*"),
129 EXTENSION_POSTFIXES = ["KHR", "EXT", "NV", "NVX", "KHX", "NN", "MVK", "FUCHSIA", "GGP", "AMD", "QNX"]
130 EXTENSION_POSTFIXES_STANDARD = ["KHR", "EXT"]
132 def prefixName (prefix, name):
133 name = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', name[2:])
134 name = re.sub(r'([a-zA-Z])([0-9])', r'\1_\2', name)
137 name = name.replace("YCB_CR_", "YCBCR_")
138 name = name.replace("WIN_32_", "WIN32_")
139 name = name.replace("8_BIT_", "8BIT_")
140 name = name.replace("16_BIT_", "16BIT_")
141 name = name.replace("INT_64_", "INT64_")
142 name = name.replace("D_3_D_12_", "D3D12_")
143 name = name.replace("IOSSURFACE_", "IOS_SURFACE_")
144 name = name.replace("MAC_OS", "MACOS_")
145 name = name.replace("TEXTURE_LOD", "TEXTURE_LOD_")
146 name = name.replace("VIEWPORT_W", "VIEWPORT_W_")
147 name = name.replace("_IDPROPERTIES", "_ID_PROPERTIES")
148 name = name.replace("PHYSICAL_DEVICE_SHADER_FLOAT_16_INT_8_FEATURES", "PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES")
149 name = name.replace("PHYSICAL_DEVICE_RGBA_10_X_6_FORMATS_FEATURES_EXT", "PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT")
150 name = name.replace("_PCIBUS_", "_PCI_BUS_")
151 name = name.replace("ASTCD", "ASTC_D")
152 name = name.replace("AABBNV", "AABB_NV")
153 name = name.replace("IMAGE_PIPE", "IMAGEPIPE")
154 name = name.replace("SMBUILTINS", "SM_BUILTINS")
155 name = name.replace("ASTCHDRFEATURES", "ASTC_HDR_FEATURES")
156 name = name.replace("UINT_8", "UINT8")
157 name = name.replace("VULKAN_11_FEATURES", "VULKAN_1_1_FEATURES")
158 name = name.replace("VULKAN_11_PROPERTIES", "VULKAN_1_1_PROPERTIES")
159 name = name.replace("VULKAN_12_FEATURES", "VULKAN_1_2_FEATURES")
160 name = name.replace("VULKAN_12_PROPERTIES", "VULKAN_1_2_PROPERTIES")
161 name = name.replace("VULKAN_13_FEATURES", "VULKAN_1_3_FEATURES")
162 name = name.replace("VULKAN_13_PROPERTIES", "VULKAN_1_3_PROPERTIES")
163 name = name.replace("VULKAN_SC_10_FEATURES", "VULKAN_SC_1_0_FEATURES")
164 name = name.replace("VULKAN_SC_10_PROPERTIES", "VULKAN_SC_1_0_PROPERTIES")
165 name = name.replace("INT_8_", "INT8_")
166 name = name.replace("AABBNV", "AABB_NV")
167 name = name.replace("_H_264_", "_H264_")
168 name = name.replace("_H_265_", "_H265_")
169 name = name.replace("RDMAFEATURES", "RDMA_FEATURES")
170 name = name.replace("RGBA_10_X_6", "RGBA10X6")
171 name = name.replace("2_D", "2D_")
172 name = name.replace("3_D", "3D_")
173 name = name.replace("IOSURFACE", "IO_SURFACE")
177 def getApiVariantIndexByName(variantName):
183 return apiVariant[variantName]
185 def getApiVariantNameByIndex(variantIndex):
191 return apiVariant[variantIndex]
194 def __init__ (self, versionTuple):
195 self.api = versionTuple[0]
196 self.major = versionTuple[1]
197 self.minor = versionTuple[2]
198 self.patch = versionTuple[3]
202 return "VK%s_API_VERSION_%d_%d" % (getApiVariantNameByIndex(self.api), self.major, self.minor)
203 return '0x%Xu' % (hash(self))
205 def isStandardVersion (self):
212 def getBestRepresentation (self):
213 if self.isStandardVersion():
214 return self.getInHex()
215 return self.getDefineName()
217 def getDefineName (self):
218 return 'VERSION_%d_%d_%d' % (self.major, self.minor, self.patch)
221 return (self.api << 29) | (self.major << 22) | (self.minor << 12) | self.patch
223 def __eq__ (self, other):
224 return self.api == other.api and self.major == other.major and self.minor == other.minor and self.patch == other.patch
227 return self.getBestRepresentation()
233 def __init__ (self, type, name):
239 def getHandleType (self):
240 return prefixName("HANDLE_TYPE_", self.name)
242 def checkAliasValidity (self):
246 return '%s (%s, %s)' % (self.name, self.alias, self.isAlias)
249 def __init__ (self, type, name, value):
257 return '%s = %s (%s)' % (self.name, self.value, self.type)
260 def __init__ (self, name, values):
266 def checkAliasValidity (self):
267 if self.alias != None:
268 if len(self.values) != len(self.alias.values):
269 raise Exception("%s has different number of flags than its alias %s." % (self.name, self.alias.name))
270 for index, value in enumerate(self.values):
271 aliasVal = self.alias.values[index]
272 if value[1] != aliasVal[1] or not (value[0].startswith(aliasVal[0]) or aliasVal[0].startswith(value[0])):
273 raise Exception("Flag %s of %s has different value than %s of %s." % (self.alias.values[index], self.alias.name, value, self.name))
276 return '%s (%s) %s' % (self.name, self.alias, self.values)
279 def __init__ (self, name, values):
285 def checkAliasValidity (self):
286 if self.alias != None:
287 if len(self.values) != len(self.alias.values):
288 raise Exception("%s has different number of flags than its alias %s." % (self.name, self.alias.name))
289 for index, value in enumerate(self.values):
290 aliasVal = self.alias.values[index]
291 if value[1] != aliasVal[1] or not (value[0].startswith(aliasVal[0]) or aliasVal[0].startswith(value[0])):
292 raise Exception("Flag %s of %s has different value than %s of %s." % (self.alias.values[index], self.alias.name, value, self.name))
295 return '%s (%s)' % (self.name, self.alias)
298 def __init__ (self, type, name, arraySizeOrFieldWidth):
299 type = type.replace('*',' *').replace('&',' &')
300 for src, dst in TYPE_SUBSTITUTIONS:
301 type = type.replace(src, dst)
302 self.type = type.split(' ')
303 for platformType, substitute, compat in PLATFORM_TYPES:
304 range = self.contains(self.type, platformType)
306 self.type = self.type[:range[0]]+[PLATFORM_TYPE_NAMESPACE + '::' + substitute[0]] + substitute[1:] + self.type[range[1]:]
309 if len(arraySizeOrFieldWidth) > 0 and arraySizeOrFieldWidth[0] == ':':
311 self.fieldWidth = arraySizeOrFieldWidth
313 self.arraySize = arraySizeOrFieldWidth
316 def contains(self, big, small):
317 for i in range(len(big)-len(small)+1):
318 for j in range(len(small)):
319 if big[i+j] != small[j]:
322 return i, i+len(small)
326 return ' '.join(self.type).replace(' *','*').replace(' &','&')
328 def getAsString (self, separator):
329 return '%s%s%s%s%s' % (self.getType(), separator, self.name, self.arraySize, self.fieldWidth)
331 def getAsStringForArgumentList (self, separator):
332 return '%s%s%s%s' % (self.getType(), separator, self.name, self.arraySize)
335 return '<%s> <%s> <%s>' % (self.type, self.name, self.arraySize)
337 def __eq__ (self, other):
338 if len(self.type) != len(other.type):
340 for index, type in enumerate(self.type):
341 if "*" == type or "&" == type or "const" == type or "volatile" == type:
342 if type != other.type[index]:
344 elif type != other.type[index] and \
345 type not in map(lambda ext: other.type[index] + ext, EXTENSION_POSTFIXES_STANDARD) and \
346 other.type[index] not in map(lambda ext: type + ext, EXTENSION_POSTFIXES_STANDARD):
348 return self.arraySize == other.arraySize
350 def __ne__ (self, other):
351 return not self == other
357 def __init__ (self, typeClass, name, members, apiVersion = None):
358 self.typeClass = typeClass
360 self.members = members
363 self.apiVersion = apiVersion
365 def getClassName (self):
366 names = {CompositeType.CLASS_STRUCT: 'struct', CompositeType.CLASS_UNION: 'union'}
367 return names[self.typeClass]
369 def checkAliasValidity (self):
370 if self.alias != None:
371 if len(self.members) != len(self.alias.members):
372 raise Exception("%s has different number of members than its alias %s." % (self.name, self.alias.name))
373 for index, member in enumerate(self.members ):
375 #if member != self.alias.members[index]:
376 #raise Exception("Member %s of %s is different than core member %s in %s." % (self.alias.members[index], self.alias.name, member, self.name))
377 #raise Exception("Member ",str(self.alias.members[index])," of ", str(self.alias.name)," is different than core member ", str(member)," in ", str(self.name),".")
379 return '%s (%s)' % (self.name, self.alias)
382 TYPE_PLATFORM = 0 # Not bound to anything
383 TYPE_INSTANCE = 1 # Bound to VkInstance
384 TYPE_DEVICE = 2 # Bound to VkDevice
386 def __init__ (self, name, returnType, arguments, apiVersion = None):
388 self.returnType = returnType
389 self.arguments = arguments
392 self.apiVersion = apiVersion
396 if self.name == "vkGetInstanceProcAddr":
397 return Function.TYPE_PLATFORM
398 assert len(self.arguments) > 0
399 firstArgType = self.arguments[0].getType()
400 if firstArgType in ["VkInstance", "VkPhysicalDevice"]:
401 return Function.TYPE_INSTANCE
402 elif firstArgType in ["VkDevice", "VkCommandBuffer", "VkQueue"]:
403 return Function.TYPE_DEVICE
405 return Function.TYPE_PLATFORM
407 def checkAliasValidity (self):
408 if self.alias != None:
409 if len(self.arguments) != len(self.alias.arguments):
410 raise Exception("%s has different number of arguments than its alias %s." % (self.name, self.alias.name))
411 if self.returnType != self.alias.returnType or not (self.returnType.startswith(self.alias.returnType) or self.alias.returnType.startswith(self.returnType)):
412 raise Exception("%s has different return value's type than its alias %s." % (self.name, self.alias.name))
413 for index, argument in enumerate(self.arguments):
414 if argument != self.alias.arguments[index]:
415 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))
418 return '%s (%s)' % (self.name, self.alias)
421 def __init__ (self, name, handles, enums, bitfields, compositeTypes, functions, definitions, additionalDefinitions, typedefs, versionInCore):
423 self.definitions = definitions
424 self.additionalDefs = additionalDefinitions
425 self.handles = handles
427 self.bitfields = bitfields
428 self.compositeTypes = compositeTypes
429 self.functions = functions
430 self.typedefs = typedefs
431 self.versionInCore = versionInCore
434 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)
437 def __init__ (self, versions, definitions, handles, enums, bitfields, bitfields64, compositeTypes, functions, extensions, additionalExtensionData):
438 self.versions = versions
439 self.definitions = definitions
440 self.handles = handles
442 self.bitfields = bitfields
443 self.bitfields64 = bitfields64
444 self.compositeTypes = compositeTypes
445 self.functions = functions # \note contains extension functions as well
446 self.extensions = extensions
447 self.additionalExtensionData = additionalExtensionData # \note contains mandatory features and information about promotion
449 def readFile (filename):
450 with open(filename, 'rt') as f:
453 IDENT_PTRN = r'[a-zA-Z_][a-zA-Z0-9_]*'
454 WIDTH_PTRN = r'[:0-9]*'
455 TYPE_PTRN = r'[a-zA-Z_][a-zA-Z0-9_ \t*&]*'
457 def getInterfaceName (function):
458 assert function.name[:2] == "vk"
459 return function.name[2].lower() + function.name[3:]
461 def getFunctionTypeName (function):
462 assert function.name[:2] == "vk"
463 return function.name[2:] + "Func"
465 def endsWith (str, postfix):
466 return str[-len(postfix):] == postfix
468 def splitNameExtPostfix (name):
469 knownExtPostfixes = EXTENSION_POSTFIXES
470 for postfix in knownExtPostfixes:
471 if endsWith(name, postfix):
472 return (name[:-len(postfix)], postfix)
475 def getBitEnumNameForBitfield (bitfieldName):
476 bitfieldName, postfix = splitNameExtPostfix(bitfieldName)
477 assert bitfieldName[-1] == "s"
478 return bitfieldName[:-1] + "Bits" + postfix
480 def getBitfieldNameForBitEnum (bitEnumName):
481 bitEnumName, postfix = splitNameExtPostfix(bitEnumName)
482 assert bitEnumName[-4:] == "Bits"
483 return bitEnumName[:-4] + "s" + postfix
485 def parsePreprocDefinedValue (src, name):
486 value = parsePreprocDefinedValueOptional(src, name)
488 raise Exception("No such definition: %s" % name)
491 def parsePreprocDefinedValueOptional (src, name):
492 definition = re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src)
493 if definition is None:
495 value = definition.group(1).strip()
496 if value == "UINT32_MAX":
500 def parseEnum (name, src):
501 keyValuePtrn = '(' + IDENT_PTRN + r')\s*=\s*([^\s,\n}]+)\s*[,\n}]'
502 return Enum(name, re.findall(keyValuePtrn, src))
504 # \note Parses raw enums, some are mapped to bitfields later
505 def parseEnums (src):
506 matches = re.findall(r'typedef enum(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
508 for enumname, contents, typename in matches:
509 enums.append(parseEnum(typename, contents))
512 def parseCompositeType (type, name, src):
513 typeNamePtrn = r'(' + TYPE_PTRN + r')(\s+' + IDENT_PTRN + r')((\[[^\]]+\]|\s*:\s*[0-9]+)*)\s*;'
514 matches = re.findall(typeNamePtrn, src)
515 members = [Variable(t.strip(), n.strip(), a.replace(' ', '')) for t, n, a, _ in matches]
516 return CompositeType(type, name, members)
518 def parseCompositeTypes (src):
519 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
520 matches = re.findall(r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
522 for type, structname, contents, typename in matches:
523 types.append(parseCompositeType(typeMap[type], typename, contents))
526 def parseCompositeTypesByVersion (src, versionsData):
528 # find occurence of extension is a place where
529 # we cant assign apiVersion to found structures
530 extPtrn = r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"'
531 versionEnd = re.search(extPtrn, src)
532 versions = [Version((v[2], v[3], v[4], 0)) for v in versionsData]
533 versions.append(None)
535 # construct list of locations where version definitions start, and add the end of the file to it
536 sectionLocations = [versionDef[1] for versionDef in versionsData]
537 sectionLocations.append(versionEnd.start())
538 sectionLocations.append(len(src))
540 # construct function declaration pattern
541 ptrn = r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;'
542 regPtrn = re.compile(ptrn)
544 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
546 # iterate over all versions and find all structure definitions
547 for index, v in enumerate(versions):
548 matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1])
549 for type, structname, contents, typename in matches:
550 compositeType = parseCompositeType(typeMap[type], typename, contents)
551 compositeType.apiVersion = v
552 types.append(compositeType)
555 def parseVersions (src):
556 # returns list of tuples each with four items:
557 # 1. string with version token (without ' 1' at the end)
558 # 2. starting point off version specific definitions in vulkan.h.in
559 # 3. major version number
560 # 4. minor version number
561 return [(m.group()[:-2], m.start(), getApiVariantIndexByName(m.group(1)), int(m.group(2)), int(m.group(3))) for m in re.finditer('VK(SC)?_VERSION_([1-9])_([0-9]) 1', src)]
564 def parseHandles (src):
565 matches = re.findall(r'VK_DEFINE(_NON_DISPATCHABLE|)_HANDLE\((' + IDENT_PTRN + r')\)[ \t]*[\n\r]', src)
567 typeMap = {'': Handle.TYPE_DISP, '_NON_DISPATCHABLE': Handle.TYPE_NONDISP}
568 for type, name in matches:
569 handle = Handle(typeMap[type], name)
570 handles.append(handle)
573 def parseArgList (src):
574 typeNamePtrn = r'(' + TYPE_PTRN + r')(\s+' + IDENT_PTRN + r')((\[[^\]]+\])*)\s*'
576 for rawArg in src.split(','):
577 m = re.search(typeNamePtrn, rawArg)
578 args.append(Variable(m.group(1).strip(), m.group(2).strip(), m.group(3)))
581 def removeTypeExtPostfix (name):
582 for extPostfix in EXTENSION_POSTFIXES_STANDARD:
583 if endsWith(name, extPostfix):
584 return name[0:-len(extPostfix)]
587 def populateExtensionAliases(allObjects, extensionObjects):
588 for object in extensionObjects:
589 withoutPostfix = removeTypeExtPostfix(object.name)
590 if withoutPostfix != None and withoutPostfix in allObjects:
591 # max 1 alias is assumed by functions in this file
592 assert allObjects[withoutPostfix].alias == None
593 allObjects[withoutPostfix].alias = object
594 object.isAlias = True
595 for object in extensionObjects:
596 object.checkAliasValidity()
598 def populateAliasesWithTypedefs (objects, src):
600 for object in objects:
601 objectsByName[object.name] = object
602 ptrn = r'\s*typedef\s+' + object.name + r'\s+([^;]+)'
603 stash = re.findall(ptrn, src)
605 objExt = copy.deepcopy(object)
606 objExt.name = stash[0]
607 object.alias = objExt
608 objExt.isAlias = True
609 objects.append(objExt)
611 def removeAliasedValues (enum):
613 for name, value in enum.values:
614 valueByName[name] = value
616 def removeDefExtPostfix (name):
617 for extPostfix in EXTENSION_POSTFIXES:
618 if endsWith(name, "_" + extPostfix):
619 return name[0:-(len(extPostfix)+1)]
623 for name, value in enum.values:
624 withoutPostfix = removeDefExtPostfix(name)
625 if withoutPostfix != None and withoutPostfix in valueByName and valueByName[withoutPostfix] == value:
627 newValues.append((name, value))
628 enum.values = newValues
630 def parseFunctions (src):
631 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
632 matches = re.findall(ptrn, src)
634 for returnType, name, argList in matches:
635 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList)))
638 def parseFunctionsByVersion (src, versions):
639 # construct list of locations where version definitions start, and add the end of the file to it
640 sectionLocations = [versionDef[1] for versionDef in versions]
641 sectionLocations.append(len(src))
643 # construct function declaration pattern
644 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
645 regPtrn = re.compile(ptrn)
648 # iterate over all versions and find all function definitions
649 for index, v in enumerate(versions):
650 matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1])
651 for returnType, name, argList in matches:
652 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList), v[0]))
655 def splitByExtension (src):
656 ptrn = r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"'
657 # Construct long pattern that will be used to split whole source by extensions
658 match = "#define\s+("
659 for part in re.finditer(ptrn, src):
660 match += part.group(1)+"|"
661 match = match[:-1] + ")\s+1"
662 parts = re.split(match, src)
664 # First part is core, following tuples contain extension name and all its definitions
665 byExtension = [(None, parts[0])]
666 for ndx in range(1, len(parts), 2):
667 byExtension.append((parts[ndx], parts[ndx+1]))
670 def parseDefinitions (extensionName, src):
672 def skipDefinition (extensionName, definition):
673 if extensionName == None:
675 extNameUpper = extensionName.upper()
676 extNameUpper = extNameUpper.replace("VK_KHR_SYNCHRONIZATION2", "VK_KHR_SYNCHRONIZATION_2")
677 extNameUpper = extNameUpper.replace("VK_INTEL_SHADER_INTEGER_FUNCTIONS2", "VK_INTEL_SHADER_INTEGER_FUNCTIONS_2")
678 extNameUpper = extNameUpper.replace("VK_EXT_ROBUSTNESS2", "VK_EXT_ROBUSTNESS_2")
679 extNameUpper = extNameUpper.replace("VK_EXT_FRAGMENT_DENSITY_MAP2", "VK_EXT_FRAGMENT_DENSITY_MAP_2")
680 extNameUpper = extNameUpper.replace("VK_EXT_SHADER_ATOMIC_FLOAT2", "VK_EXT_SHADER_ATOMIC_FLOAT_2")
681 extNameUpper = extNameUpper.replace("VK_AMD_SHADER_CORE_PROPERTIES2", "VK_AMD_SHADER_CORE_PROPERTIES_2")
682 extNameUpper = extNameUpper.replace("VK_EXT_EXTENDED_DYNAMIC_STATE2", "VK_EXT_EXTENDED_DYNAMIC_STATE_2")
684 if definition[0].startswith(extNameUpper) and definition[1].isdigit():
686 if definition[0].startswith(extNameUpper):
688 if definition[0].endswith("_H_"):
692 ptrn = r'#define\s+([^\s]+)\s+([^\r\n]+)'
693 matches = re.findall(ptrn, src)
695 return [Definition(None, match[0], match[1]) for match in matches if not skipDefinition(extensionName, match)]
697 def parseTypedefs (src):
699 ptrn = r'typedef\s+([^\s]+)\s+([^\r\n]+);'
700 matches = re.findall(ptrn, src)
702 return [Definition(None, match[0], match[1]) for match in matches]
704 def parseExtensions (src, versions, allFunctions, allCompositeTypes, allEnums, allBitfields, allHandles, allDefinitions, additionalExtensionData):
706 # note registeredExtensionDict is also executed for vulkan 1.0 source for which extension name is None
707 registeredExtensionDict = {None: None}
708 for extensionName, data in additionalExtensionData:
709 # make sure that this extension was registered
710 if 'register_extension' not in data.keys():
712 # save array containing 'device' or 'instance' string followed by the optional vulkan version in which this extension is core;
713 # note that register_extension section is also required for partialy promoted extensions like VK_EXT_extended_dynamic_state2
714 # but those extensions should not fill 'core' tag
715 registeredExtensionDict[extensionName] = [ data['register_extension']['type'] ]
716 match = re.match("(\d).(\d).(\d).(\d)", data['register_extension']['core'])
718 registeredExtensionDict[extensionName].extend( [ int(match.group(1)), int(match.group(2)), int(match.group(3)), int(match.group(4)) ] )
720 splitSrc = splitByExtension(src)
722 functionsByName = {function.name: function for function in allFunctions}
723 compositeTypesByName = {compType.name: compType for compType in allCompositeTypes}
724 enumsByName = {enum.name: enum for enum in allEnums}
725 bitfieldsByName = {bitfield.name: bitfield for bitfield in allBitfields}
726 handlesByName = {handle.name: handle for handle in allHandles}
727 definitionsByName = {definition.name: definition for definition in allDefinitions}
729 for extensionName, extensionSrc in splitSrc:
730 definitions = [Definition("uint32_t", v.getInHex(), parsePreprocDefinedValueOptional(extensionSrc, v.getInHex())) for v in versions]
731 definitions.extend([Definition(type, name, parsePreprocDefinedValueOptional(extensionSrc, name)) for name, type in DEFINITIONS])
732 definitions = [definition for definition in definitions if definition.value != None]
733 additionalDefinitions = parseDefinitions(extensionName, extensionSrc)
734 handles = parseHandles(extensionSrc)
735 functions = parseFunctions(extensionSrc)
736 compositeTypes = parseCompositeTypes(extensionSrc)
737 rawEnums = parseEnums(extensionSrc)
738 bitfieldNames = parse32bitBitfieldNames(extensionSrc)
739 typedefs = parseTypedefs(extensionSrc)
740 enumBitfieldNames = [getBitEnumNameForBitfield(name) for name in bitfieldNames]
741 enums = [enum for enum in rawEnums if enum.name not in enumBitfieldNames]
743 extCoreVersion = None
744 extData = registeredExtensionDict.get(extensionName, None)
745 extFunctions = [functionsByName[function.name] for function in functions]
746 extCompositeTypes = [compositeTypesByName[compositeType.name] for compositeType in compositeTypes]
747 extEnums = [enumsByName[enum.name] for enum in enums]
748 extBitfields = [bitfieldsByName[bitfieldName] for bitfieldName in bitfieldNames]
749 extHandles = [handlesByName[handle.name] for handle in handles]
750 extDefinitions = [definitionsByName[definition.name] for definition in definitions]
753 populateExtensionAliases(functionsByName, extFunctions)
754 populateExtensionAliases(handlesByName, extHandles)
755 populateExtensionAliases(enumsByName, extEnums)
756 populateExtensionAliases(bitfieldsByName, extBitfields)
757 populateExtensionAliases(compositeTypesByName, extCompositeTypes)
759 extCoreVersion = extData
761 extensions.append(Extension(extensionName, extHandles, extEnums, extBitfields, extCompositeTypes, extFunctions, extDefinitions, additionalDefinitions, typedefs, extCoreVersion))
764 def parse32bitBitfieldNames (src):
765 ptrn = r'typedef\s+VkFlags\s(' + IDENT_PTRN + r')\s*;'
766 matches = re.findall(ptrn, src)
770 def parse64bitBitfieldNames (src):
771 ptrn = r'typedef\s+VkFlags64\s(' + IDENT_PTRN + r')\s*;'
772 matches = re.findall(ptrn, src)
776 def parse64bitBitfieldValues (src, bitfieldNamesList):
779 for bitfieldName in bitfieldNamesList:
780 ptrn = r'static const ' + bitfieldName + r'\s*(' + IDENT_PTRN + r')\s*=\s*([a-zA-Z0-9_]+)\s*;'
781 matches = re.findall(ptrn, src)
782 bitfields64.append(Bitfield(bitfieldName, matches))
787 versionsData = parseVersions(src)
788 versions = [Version((v[2], v[3], v[4], 0)) for v in versionsData]
789 definitions = [Definition("uint32_t", v.getInHex(), parsePreprocDefinedValue(src, v.getInHex())) for v in versions] +\
790 [Definition(type, name, parsePreprocDefinedValue(src, name)) for name, type in DEFINITIONS]
792 handles = parseHandles(src)
793 rawEnums = parseEnums(src)
794 bitfieldNames = parse32bitBitfieldNames(src)
795 bitfieldEnums = set([getBitEnumNameForBitfield(n) for n in bitfieldNames if getBitEnumNameForBitfield(n) in [enum.name for enum in rawEnums]])
796 bitfield64Names = parse64bitBitfieldNames(src)
797 bitfields64 = parse64bitBitfieldValues(src, bitfield64Names)
800 compositeTypes = parseCompositeTypesByVersion(src, versionsData)
801 allFunctions = parseFunctionsByVersion(src, versionsData)
802 additionalExtensionData = {}
804 # read all files from extensions directory
805 for fileName in glob.glob(os.path.join(SCRIPTS_SRC_DIR, "extensions", "*.json")):
806 extensionName = os.path.basename(fileName)[:-5]
807 fileContent = readFile(fileName)
809 additionalExtensionData[extensionName] = json.loads(fileContent)
810 except ValueError as err:
811 print("Error in %s: %s" % (os.path.basename(fileName), str(err)))
813 additionalExtensionData = sorted(additionalExtensionData.items(), key=lambda e: e[0])
815 for enum in rawEnums:
816 if enum.name in bitfieldEnums:
817 bitfields.append(Bitfield(getBitfieldNameForBitEnum(enum.name), enum.values))
821 for bitfieldName in bitfieldNames:
822 if not bitfieldName in [bitfield.name for bitfield in bitfields]:
824 bitfields.append(Bitfield(bitfieldName, []))
826 extensions = parseExtensions(src, versions, allFunctions, compositeTypes, enums, bitfields, handles, definitions, additionalExtensionData)
828 # Populate alias fields
829 populateAliasesWithTypedefs(compositeTypes, src)
830 populateAliasesWithTypedefs(enums, src)
831 populateAliasesWithTypedefs(bitfields, src)
832 populateAliasesWithTypedefs(bitfields64, src)
833 populateAliasesWithTypedefs(handles, src)
836 removeAliasedValues(enum)
838 # Make generator to create Deleter<VkAccelerationStructureNV>
839 for f in allFunctions:
840 if (f.name == 'vkDestroyAccelerationStructureNV'):
841 f.arguments[1].type[0] = 'VkAccelerationStructureNV'
843 # Dealias handles VkAccelerationStructureNV and VkAccelerationStructureKHR
844 for handle in handles:
845 if handle.name == 'VkAccelerationStructureKHR':
847 if handle.name == 'VkAccelerationStructureNV':
848 handle.isAlias = False
852 definitions = definitions,
855 bitfields = bitfields,
856 bitfields64 = bitfields64,
857 compositeTypes = compositeTypes,
858 functions = allFunctions,
859 extensions = extensions,
860 additionalExtensionData = additionalExtensionData)
862 def splitUniqueAndDuplicatedEntries (handles):
863 listOfUniqueHandles = []
864 duplicates = OrderedDict()
865 for handle in handles:
866 if handle.alias != None:
867 duplicates[handle.alias] = handle
868 if not handle.isAlias:
869 listOfUniqueHandles.append(handle)
870 return listOfUniqueHandles, duplicates
872 def writeHandleType (api, filename):
873 uniqeHandles, duplicatedHandles = splitUniqueAndDuplicatedEntries(api.handles)
876 yield "\t%s\t= 0," % uniqeHandles[0].getHandleType()
877 for handle in uniqeHandles[1:]:
878 yield "\t%s," % handle.getHandleType()
879 for duplicate in duplicatedHandles:
880 yield "\t%s\t= %s," % (duplicate.getHandleType(), duplicatedHandles[duplicate].getHandleType())
881 yield "\tHANDLE_TYPE_LAST\t= %s + 1" % (uniqeHandles[-1].getHandleType())
883 def genHandlesBlock ():
884 yield "enum HandleType"
887 for line in indentLines(genHandles()):
893 writeInlFile(filename, INL_HEADER, genHandlesBlock())
895 def getEnumValuePrefix (enum):
896 prefix = enum.name[0]
897 for i in range(1, len(enum.name)):
898 if enum.name[i].isupper() and not enum.name[i-1].isupper():
900 prefix += enum.name[i].upper()
903 def parseInt (value):
904 if value[:2] == "0x":
905 return int(value, 16)
907 return int(value, 10)
909 def areEnumValuesLinear (enum):
912 for name, value in enum.values:
913 if value[:2] != "VK":
914 intValue = parseInt(value)
915 if intValue != curIndex:
916 # enum is linear when all items are in order
917 if intValue != 0x7FFFFFFF:
919 # count number of items with 0x7FFFFFFF value;
920 # enum containing single 0x7FFFFFFF item are also
921 # considered as linear (this is usualy *_MAX_ENUM item)
923 # enums containing more then one 0x7FFFFFFF value
924 # are not considered as linear (vulkan video enums)
930 def genEnumSrc (enum):
931 yield "enum %s" % enum.name
935 if areEnumValuesLinear(enum):
936 hasMaxItem = parseInt(enum.values[-1][1]) == 0x7FFFFFFF
938 values = enum.values[:-1] if hasMaxItem else enum.values
939 lastItem = "\t%s_LAST," % getEnumValuePrefix(enum)
941 # linear values first, followed by *_LAST
942 lines += ["\t%s\t= %s," % v for v in values if v[1][:2] != "VK"]
943 lines.append(lastItem)
945 # equivalence enums and *_MAX_ENUM
946 lines += ["\t%s\t= %s," % v for v in values if v[1][:2] == "VK"]
948 lines.append("\t%s\t= %s," % enum.values[-1])
950 lines += ["\t%s\t= %s," % v for v in enum.values]
952 for line in indentLines(lines):
957 def genBitfieldSrc (bitfield):
958 if len(bitfield.values) > 0:
959 yield "enum %s" % getBitEnumNameForBitfield(bitfield.name)
961 for line in indentLines(["\t%s\t= %s," % v for v in bitfield.values]):
964 yield "typedef uint32_t %s;" % bitfield.name
966 def genBitfield64Src (bitfield64):
967 yield "typedef uint64_t %s;" % bitfield64.name
968 if len(bitfield64.values) > 0:
969 ptrn = "static const " + bitfield64.name + " %s\t= %s;"
970 for line in indentLines([ptrn % v for v in bitfield64.values]):
974 def genCompositeTypeSrc (type):
975 yield "%s %s" % (type.getClassName(), type.name)
977 for line in indentLines(['\t'+m.getAsString('\t')+';' for m in type.members]):
981 def genHandlesSrc (handles):
982 uniqeHandles, duplicatedHandles = splitUniqueAndDuplicatedEntries(handles)
984 def genLines (handles):
985 for handle in uniqeHandles:
986 if handle.type == Handle.TYPE_DISP:
987 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
988 elif handle.type == Handle.TYPE_NONDISP:
989 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
991 for duplicate in duplicatedHandles:
992 if duplicate.type == Handle.TYPE_DISP:
993 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (duplicate.name, duplicatedHandles[duplicate].getHandleType())
994 elif duplicate.type == Handle.TYPE_NONDISP:
995 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (duplicate.name, duplicatedHandles[duplicate].getHandleType())
997 for line in indentLines(genLines(handles)):
1000 def stripTrailingComment(str):
1001 index = str.find("//")
1006 def genDefinitionsSrc (definitions):
1007 for line in ["#define %s\t(static_cast<%s>\t(%s))" % (definition.name, definition.type, stripTrailingComment(definition.value)) for definition in definitions]:
1010 def genDefinitionsAliasSrc (definitions):
1011 for line in ["#define %s\t%s" % (definition.name, definitions[definition].name) for definition in definitions]:
1012 if definition.value != definitions[definition].value and definition.value != definitions[definition].name:
1013 raise Exception("Value of %s (%s) is different than core definition value %s (%s)." % (definition.name, definition.value, definitions[definition].name, definitions[definition].value))
1016 def genMaxFrameworkVersion (definitions):
1017 maxApiVersionMajor = 1
1018 maxApiVersionMinor = 0
1019 for definition in definitions:
1020 match = re.match("VK_API_VERSION_(\d+)_(\d+)", definition.name)
1022 apiVersionMajor = int(match.group(1))
1023 apiVersionMinor = int(match.group(2))
1024 if apiVersionMajor > maxApiVersionMajor:
1025 maxApiVersionMajor = apiVersionMajor
1026 maxApiVersionMinor = apiVersionMinor
1027 elif apiVersionMajor == maxApiVersionMajor and apiVersionMinor > maxApiVersionMinor:
1028 maxApiVersionMinor = apiVersionMinor
1029 yield "#define VK_API_MAX_FRAMEWORK_VERSION\tVK_API_VERSION_%d_%d" % (maxApiVersionMajor, maxApiVersionMinor)
1031 def genMaxFrameworkVersionSC (definitions):
1032 maxApiVersionMajor = 1
1033 maxApiVersionMinor = 0
1034 for definition in definitions:
1035 match = re.match("VKSC_API_VERSION_(\d+)_(\d+)", definition.name)
1037 apiVersionMajor = int(match.group(1))
1038 apiVersionMinor = int(match.group(2))
1039 if apiVersionMajor > maxApiVersionMajor:
1040 maxApiVersionMajor = apiVersionMajor
1041 maxApiVersionMinor = apiVersionMinor
1042 elif apiVersionMajor == maxApiVersionMajor and apiVersionMinor > maxApiVersionMinor:
1043 maxApiVersionMinor = apiVersionMinor
1044 yield "#define VKSC_API_MAX_FRAMEWORK_VERSION\tVKSC_API_VERSION_%d_%d" % (maxApiVersionMajor, maxApiVersionMinor)
1046 def writeBasicTypes (apiName, api, filename):
1049 definitionsCore, definitionDuplicates = splitUniqueAndDuplicatedEntries(api.definitions)
1052 for line in indentLines(chain(genDefinitionsSrc(definitionsCore), genMaxFrameworkVersion(definitionsCore), genDefinitionsAliasSrc(definitionDuplicates))):
1055 elif apiName == 'SC':
1056 for line in indentLines(chain(genDefinitionsSrc(definitionsCore), genMaxFrameworkVersion(definitionsCore), genMaxFrameworkVersionSC(definitionsCore), genDefinitionsAliasSrc(definitionDuplicates))):
1060 for line in genHandlesSrc(api.handles):
1064 for enum in api.enums:
1065 if not enum.isAlias:
1066 for line in genEnumSrc(enum):
1069 for enum2 in api.enums:
1070 if enum2.alias == enum:
1071 yield "typedef %s %s;" % (enum2.name, enum.name)
1074 for bitfield in api.bitfields:
1075 if not bitfield.isAlias:
1076 for line in genBitfieldSrc(bitfield):
1079 for bitfield2 in api.bitfields:
1080 if bitfield2.alias == bitfield:
1081 yield "typedef %s %s;" % (bitfield2.name, bitfield.name)
1084 for bitfield in api.bitfields64:
1085 if not bitfield.isAlias:
1086 for line in genBitfield64Src(bitfield):
1089 for bitfield2 in api.bitfields64:
1090 if bitfield2.alias == bitfield:
1091 yield "typedef %s %s;" % (bitfield2.name, bitfield.name)
1094 for line in indentLines(["VK_DEFINE_PLATFORM_TYPE(%s,\t%s)" % (s[0], c) for n, s, c in PLATFORM_TYPES]):
1097 for ext in api.extensions:
1098 if ext.additionalDefs != None:
1099 for definition in ext.additionalDefs:
1100 yield "#define " + definition.name + " " + definition.value
1102 writeInlFile(filename, INL_HEADER, gen())
1104 def writeCompositeTypes (api, filename):
1106 for type in api.compositeTypes:
1107 type.checkAliasValidity()
1109 if not type.isAlias:
1110 for line in genCompositeTypeSrc(type):
1113 for type2 in api.compositeTypes:
1114 if type2.alias == type:
1115 yield "typedef %s %s;" % (type2.name, type.name)
1118 writeInlFile(filename, INL_HEADER, gen())
1120 def argListToStr (args):
1121 return ", ".join(v.getAsStringForArgumentList(' ') for v in args)
1123 def writeInterfaceDecl (api, filename, functionTypes, concrete):
1125 postfix = "" if concrete else " = 0"
1126 for function in api.functions:
1127 if not function.getType() in functionTypes:
1129 if not function.isAlias:
1130 yield "virtual %s\t%s\t(%s) const%s;" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments), postfix)
1132 writeInlFile(filename, INL_HEADER, indentLines(genProtos()))
1134 def writeFunctionPtrTypes (api, filename):
1136 for function in api.functions:
1137 yield "typedef VKAPI_ATTR %s\t(VKAPI_CALL* %s)\t(%s);" % (function.returnType, getFunctionTypeName(function), argListToStr(function.arguments))
1139 writeInlFile(filename, INL_HEADER, indentLines(genTypes()))
1141 def writeFunctionPointers (api, filename, functionTypes):
1142 def FunctionsYielder ():
1143 for function in api.functions:
1144 if function.getType() in functionTypes:
1145 if function.isAlias:
1146 if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice":
1147 yield "%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function))
1149 yield "%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function))
1151 writeInlFile(filename, INL_HEADER, indentLines(FunctionsYielder()))
1153 def writeInitFunctionPointers (api, filename, functionTypes, cond = None):
1154 def makeInitFunctionPointers ():
1155 for function in api.functions:
1156 if function.getType() in functionTypes and (cond == None or cond(function)):
1157 interfaceName = getInterfaceName(function)
1158 if function.isAlias:
1159 if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice":
1160 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
1162 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
1163 if function.alias != None:
1164 yield "if (!m_vk.%s)" % (getInterfaceName(function))
1165 yield " m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.alias.name)
1166 lines = [line.replace(' ', '\t') for line in indentLines(makeInitFunctionPointers())]
1167 writeInlFile(filename, INL_HEADER, lines)
1169 def writeFuncPtrInterfaceImpl (api, filename, functionTypes, className):
1170 def makeFuncPtrInterfaceImpl ():
1171 for function in api.functions:
1172 if function.getType() in functionTypes and not function.isAlias:
1174 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments))
1176 if function.name == "vkEnumerateInstanceVersion":
1177 yield " if (m_vk.enumerateInstanceVersion)"
1178 yield " return m_vk.enumerateInstanceVersion(pApiVersion);"
1180 yield " *pApiVersion = VK_API_VERSION_1_0;"
1181 yield " return VK_SUCCESS;"
1182 elif function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice" and function.alias != None:
1183 yield " vk::VkPhysicalDeviceProperties props;"
1184 yield " m_vk.getPhysicalDeviceProperties(physicalDevice, &props);"
1185 yield " if (props.apiVersion >= VK_API_VERSION_1_1)"
1186 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
1188 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function.alias), ", ".join(a.name for a in function.arguments))
1190 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
1193 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceImpl())
1195 def writeFuncPtrInterfaceSCImpl (api, filename, functionTypes, className):
1197 "createGraphicsPipelines" : "\t\treturn createGraphicsPipelinesHandlerNorm(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);",
1198 "createComputePipelines" : "\t\treturn createComputePipelinesHandlerNorm(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);",
1199 "createSampler" : "\t\treturn createSamplerHandlerNorm(device, pCreateInfo, pAllocator, pSampler);",
1200 "createSamplerYcbcrConversion" : "\t\treturn createSamplerYcbcrConversionHandlerNorm(device, pCreateInfo, pAllocator, pYcbcrConversion);",
1201 "createDescriptorSetLayout" : "\t\treturn createDescriptorSetLayoutHandlerNorm(device, pCreateInfo, pAllocator, pSetLayout);",
1202 "createPipelineLayout" : "\t\treturn createPipelineLayoutHandlerNorm(device, pCreateInfo, pAllocator, pPipelineLayout);",
1203 "createRenderPass" : "\t\treturn createRenderPassHandlerNorm(device, pCreateInfo, pAllocator, pRenderPass);",
1204 "createRenderPass2" : "\t\treturn createRenderPass2HandlerNorm(device, pCreateInfo, pAllocator, pRenderPass);",
1205 "createCommandPool" : "\t\treturn createCommandPoolHandlerNorm(device, pCreateInfo, pAllocator, pCommandPool);",
1206 "resetCommandPool" : "\t\treturn resetCommandPoolHandlerNorm(device, commandPool, flags);",
1207 "createFramebuffer" : "\t\treturn createFramebufferHandlerNorm(device, pCreateInfo, pAllocator, pFramebuffer);",
1210 "destroyDevice" : "\t\tdestroyDeviceHandler(device, pAllocator);",
1211 "createDescriptorSetLayout" : "\t\tcreateDescriptorSetLayoutHandlerStat(device, pCreateInfo, pAllocator, pSetLayout);",
1212 "destroyDescriptorSetLayout" : "\t\tdestroyDescriptorSetLayoutHandler(device, descriptorSetLayout, pAllocator);",
1213 "createImageView" : "\t\tcreateImageViewHandler(device, pCreateInfo, pAllocator, pView);",
1214 "destroyImageView" : "\t\tdestroyImageViewHandler(device, imageView, pAllocator);",
1215 "createSemaphore" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(semaphoreRequestCount,1);\n\t\t*pSemaphore = Handle<HANDLE_TYPE_SEMAPHORE>(m_resourceInterface->incResourceCounter());\n\t}",
1216 "destroySemaphore" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(semaphore,semaphoreRequestCount,1);\n\t}",
1217 "createFence" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(fenceRequestCount,1);\n\t\t*pFence = Handle<HANDLE_TYPE_FENCE>(m_resourceInterface->incResourceCounter());\n\t}",
1218 "destroyFence" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(fence,fenceRequestCount,1);\n\t}",
1219 "allocateMemory" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(deviceMemoryRequestCount,1);\n\t\t*pMemory = Handle<HANDLE_TYPE_DEVICE_MEMORY>(m_resourceInterface->incResourceCounter());\n\t}",
1220 "createBuffer" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(bufferRequestCount,1);\n\t\t*pBuffer = Handle<HANDLE_TYPE_BUFFER>(m_resourceInterface->incResourceCounter());\n\t}",
1221 "destroyBuffer" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(buffer,bufferRequestCount,1);\n\t}",
1222 "createImage" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(imageRequestCount,1);\n\t\t*pImage = Handle<HANDLE_TYPE_IMAGE>(m_resourceInterface->incResourceCounter());\n\t}",
1223 "destroyImage" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(image,imageRequestCount,1);\n\t}",
1224 "createEvent" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(eventRequestCount,1);\n\t\t*pEvent = Handle<HANDLE_TYPE_EVENT>(m_resourceInterface->incResourceCounter());\n\t}",
1225 "destroyEvent" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(event,eventRequestCount,1);\n\t}",
1226 "createQueryPool" : "\t\tcreateQueryPoolHandler(device, pCreateInfo, pAllocator, pQueryPool);",
1227 "createBufferView" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(bufferViewRequestCount,1);\n\t\t*pView = Handle<HANDLE_TYPE_BUFFER_VIEW>(m_resourceInterface->incResourceCounter());\n\t}",
1228 "destroyBufferView" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(bufferView,bufferViewRequestCount,1);\n\t}",
1229 "createPipelineLayout" : "\t\tcreatePipelineLayoutHandlerStat(device, pCreateInfo, pAllocator, pPipelineLayout);",
1230 "destroyPipelineLayout" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(pipelineLayout,pipelineLayoutRequestCount,1);\n\t}",
1231 "createRenderPass" : "\t\tcreateRenderPassHandlerStat(device, pCreateInfo, pAllocator, pRenderPass);",
1232 "createRenderPass2" : "\t\tcreateRenderPass2HandlerStat(device, pCreateInfo, pAllocator, pRenderPass);",
1233 "destroyRenderPass" : "\t\tdestroyRenderPassHandler(device, renderPass, pAllocator);",
1234 "createGraphicsPipelines" : "\t\tcreateGraphicsPipelinesHandlerStat(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);",
1235 "createComputePipelines" : "\t\tcreateComputePipelinesHandlerStat(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);",
1236 "destroyPipeline" : "\t\tdestroyPipelineHandler(device, pipeline, pAllocator);",
1237 "createSampler" : "\t\tcreateSamplerHandlerStat(device, pCreateInfo, pAllocator, pSampler);",
1238 "destroySampler" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(sampler,samplerRequestCount,1);\n\t}",
1239 "createDescriptorPool" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(descriptorPoolRequestCount,1);\n\t\t*pDescriptorPool = Handle<HANDLE_TYPE_DESCRIPTOR_POOL>(m_resourceInterface->incResourceCounter());\n\t}",
1240 "resetDescriptorPool" : "\t\tresetDescriptorPoolHandlerStat(device, descriptorPool, flags);",
1241 "allocateDescriptorSets" : "\t\tallocateDescriptorSetsHandlerStat(device, pAllocateInfo, pDescriptorSets);",
1242 "freeDescriptorSets" : "\t\tfreeDescriptorSetsHandlerStat(device, descriptorPool, descriptorSetCount, pDescriptorSets);",
1243 "createFramebuffer" : "\t\tcreateFramebufferHandlerStat(device, pCreateInfo, pAllocator, pFramebuffer);",
1244 "destroyFramebuffer" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(framebuffer,framebufferRequestCount,1);\n\t}",
1245 "createCommandPool" : "\t\tcreateCommandPoolHandlerStat(device, pCreateInfo, pAllocator, pCommandPool);",
1246 "resetCommandPool" : "\t\tresetCommandPoolHandlerStat(device, commandPool, flags);",
1247 "allocateCommandBuffers" : "\t\tallocateCommandBuffersHandler(device, pAllocateInfo, pCommandBuffers);",
1248 "freeCommandBuffers" : "\t\tfreeCommandBuffersHandler(device, commandPool, commandBufferCount, pCommandBuffers);",
1249 "createSamplerYcbcrConversion" : "\t\tcreateSamplerYcbcrConversionHandlerStat(device, pCreateInfo, pAllocator, pYcbcrConversion);",
1250 "destroySamplerYcbcrConversion" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(ycbcrConversion,samplerYcbcrConversionRequestCount,1);\n\t}",
1251 "getDescriptorSetLayoutSupport" : "\t\tgetDescriptorSetLayoutSupportHandler(device, pCreateInfo, pSupport);",
1252 # "" : "surfaceRequestCount",
1253 # "" : "swapchainRequestCount",
1254 # "" : "displayModeRequestCount"
1255 "mapMemory" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tif(m_falseMemory.size() < (static_cast<std::size_t>(offset+size)))\n\t\t\tm_falseMemory.resize(static_cast<std::size_t>(offset+size));\n\t\t*ppData = (void*)m_falseMemory.data();\n\t}",
1256 "getBufferMemoryRequirements" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->size = 1048576U;\n\t\tpMemoryRequirements->alignment = 1U;\n\t\tpMemoryRequirements->memoryTypeBits = ~0U;\n\t}",
1257 "getImageMemoryRequirements" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->size = 1048576U;\n\t\tpMemoryRequirements->alignment = 1U;\n\t\tpMemoryRequirements->memoryTypeBits = ~0U;\n\t}",
1258 "getBufferMemoryRequirements2" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->memoryRequirements.size = 1048576U;\n\t\tpMemoryRequirements->memoryRequirements.alignment = 1U;\n\t\tpMemoryRequirements->memoryRequirements.memoryTypeBits = ~0U;\n\t}",
1259 "getImageMemoryRequirements2" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->memoryRequirements.size = 1048576U;\n\t\tpMemoryRequirements->memoryRequirements.alignment = 1U;\n\t\tpMemoryRequirements->memoryRequirements.memoryTypeBits = ~0U;\n\t}",
1260 "getImageSubresourceLayout" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpLayout->offset = 0U;\n\t\tpLayout->size = 1048576U;\n\t\tpLayout->rowPitch = 0U;\n\t\tpLayout->arrayPitch = 0U;\n\t\tpLayout->depthPitch = 0U;\n\t}",
1261 "createPipelineCache" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(pipelineCacheRequestCount,1);\n\t\t*pPipelineCache = Handle<HANDLE_TYPE_PIPELINE_CACHE>(m_resourceInterface->incResourceCounter());\n\t}",
1262 "destroyPipelineCache" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(pipelineCache,pipelineCacheRequestCount,1);\n\t}",
1263 "cmdUpdateBuffer" : "\t\tincreaseCommandBufferSize(commandBuffer, dataSize);",
1264 "getDeviceQueue" : "\t\tm_vk.getDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);",
1268 "VkResult" : "return VK_SUCCESS;",
1269 "VkDeviceAddress" : "return 0u;",
1270 "uint64_t" : "return 0u;",
1272 def makeFuncPtrInterfaceStatisticsImpl ():
1273 for function in api.functions:
1274 if function.getType() in functionTypes and not function.isAlias:
1276 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments))
1278 if ( getInterfaceName(function) in normFuncs ) or ( getInterfaceName(function) in statFuncs ):
1279 yield "\tstd::lock_guard<std::mutex> lock(functionMutex);"
1280 if getInterfaceName(function) != "getDeviceProcAddr" :
1281 yield "\tif (m_normalMode)"
1282 if getInterfaceName(function) in normFuncs :
1283 yield "%s" % ( normFuncs[getInterfaceName(function)] )
1285 yield "\t\t%sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
1286 if getInterfaceName(function) in statFuncs :
1288 yield "%s" % ( statFuncs[getInterfaceName(function)] )
1289 elif getInterfaceName(function)[:3] == "cmd" :
1291 yield "\t\tincreaseCommandBufferSize(commandBuffer, 0u);"
1292 if function.returnType in statReturns:
1293 yield "\t%s" % ( statReturns[function.returnType] )
1296 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceStatisticsImpl())
1298 def writeStrUtilProto (api, filename):
1299 def makeStrUtilProto ():
1300 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]):
1303 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]):
1306 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]):
1309 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']):
1312 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]):
1315 writeInlFile(filename, INL_HEADER, makeStrUtilProto())
1317 def writeStrUtilImpl (api, filename):
1318 def makeStrUtilImpl ():
1319 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]):
1323 yield "namespace %s" % PLATFORM_TYPE_NAMESPACE
1326 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):
1331 for enum in api.enums:
1335 yield "const char* get%sName (%s value)" % (enum.name[2:], enum.name)
1337 yield "\tswitch (value)"
1340 lastValue = 0x7FFFFFFF
1341 for n, v in enum.values:
1342 if (v[:2] != "VK") and (v != lastValue):
1343 enumValues.append(f"\t\tcase {n}:\treturn \"{n}\";")
1345 enumValues.append("\t\tdefault:\treturn DE_NULL;")
1346 for line in indentLines(enumValues):
1351 for bitfield in api.bitfields:
1352 if bitfield.isAlias:
1353 if bitfield.name != 'VkBuildAccelerationStructureFlagsNV':
1356 yield "tcu::Format::Bitfield<32> get%sStr (%s value)" % (bitfield.name[2:], bitfield.name)
1359 if len(bitfield.values) > 0:
1360 yield "\tstatic const tcu::Format::BitDesc s_desc[] ="
1362 for line in indentLines(["\t\ttcu::Format::BitDesc(%s,\t\"%s\")," % (n, n) for n, v in bitfield.values]):
1365 yield "\treturn tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));"
1367 yield "\treturn tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL);"
1370 bitfieldTypeNames = set([bitfield.name for bitfield in api.bitfields])
1372 for type in api.compositeTypes:
1373 if not type.isAlias:
1375 yield "std::ostream& operator<< (std::ostream& s, const %s& value)" % type.name
1377 yield "\ts << \"%s = {\\n\";" % type.name
1378 for member in type.members:
1379 memberName = member.name
1382 if member.getType() in bitfieldTypeNames:
1383 valFmt = "get%sStr(value.%s)" % (member.getType()[2:], member.name)
1384 elif member.getType() == "const char*" or member.getType() == "char*":
1385 valFmt = "getCharPtrStr(value.%s)" % member.name
1386 elif member.getType() == PLATFORM_TYPE_NAMESPACE + "::Win32LPCWSTR":
1387 valFmt = "getWStr(value.%s)" % member.name
1388 elif member.arraySize != '':
1389 singleDimensional = not '][' in member.arraySize
1390 if member.name in ["extensionName", "deviceName", "layerName", "description"]:
1391 valFmt = "(const char*)value.%s" % member.name
1392 elif singleDimensional and (member.getType() == 'char' or member.getType() == 'uint8_t'):
1393 newLine = "'\\n' << "
1394 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)
1396 if member.name == "memoryTypes" or member.name == "memoryHeaps":
1397 endIter = "DE_ARRAY_BEGIN(value.%s) + value.%sCount" % (member.name, member.name[:-1])
1399 endIter = "DE_ARRAY_END(value.%s)" % member.name
1400 newLine = "'\\n' << "
1401 valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), %s)" % (member.name, endIter)
1402 memberName = member.name
1404 valFmt = "value.%s" % member.name
1405 yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';"
1409 writeInlFile(filename, INL_HEADER, makeStrUtilImpl())
1412 def writeObjTypeImpl (api, filename):
1413 def makeObjTypeImpl ():
1415 yield "namespace vk"
1418 yield "template<typename T> VkObjectType getObjectType (void);"
1420 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]):
1425 writeInlFile(filename, INL_HEADER, makeObjTypeImpl())
1427 class ConstructorFunction:
1428 def __init__ (self, type, name, objectType, ifaceArgs, arguments):
1431 self.objectType = objectType
1432 self.ifaceArgs = ifaceArgs
1433 self.arguments = arguments
1435 def getConstructorFunctions (api):
1438 Function.TYPE_PLATFORM: [Variable("const PlatformInterface&", "vk", "")],
1439 Function.TYPE_INSTANCE: [Variable("const InstanceInterface&", "vk", "")],
1440 Function.TYPE_DEVICE: [Variable("const DeviceInterface&", "vk", "")]
1442 for function in api.functions:
1443 if function.isAlias:
1445 if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "createInfoCount" in [a.name for a in function.arguments]:
1446 if function.name == "vkCreateDisplayModeKHR":
1447 continue # No way to delete display modes (bug?)
1449 # \todo [pyry] Rather hacky
1450 ifaceArgs = ifacesDict[function.getType()]
1451 if function.name == "vkCreateDevice":
1452 ifaceArgs = [Variable("const PlatformInterface&", "vkp", ""), Variable("VkInstance", "instance", "")] + ifaceArgs
1454 assert (function.arguments[-2].type == ["const", "VkAllocationCallbacks", "*"])
1456 objectType = function.arguments[-1].type[0] #not getType() but type[0] on purpose
1457 arguments = function.arguments[:-1]
1458 funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function), objectType, ifaceArgs, arguments))
1461 def addVersionDefines(versionSpectrum):
1462 output = ["#define " + ver.getDefineName() + " " + ver.getInHex() for ver in versionSpectrum if not ver.isStandardVersion()]
1465 def removeVersionDefines(versionSpectrum):
1466 output = ["#undef " + ver.getDefineName() for ver in versionSpectrum if not ver.isStandardVersion()]
1469 def writeRefUtilProto (api, filename):
1470 functions = getConstructorFunctions(api)
1472 def makeRefUtilProto ():
1474 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]):
1477 writeInlFile(filename, INL_HEADER, makeRefUtilProto())
1479 def writeRefUtilImpl (api, filename):
1480 functions = getConstructorFunctions(api)
1482 def makeRefUtilImpl ():
1483 yield "namespace refdetails"
1487 for function in api.functions:
1488 if function.getType() == Function.TYPE_DEVICE \
1489 and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \
1490 and not function.name == "vkDestroyDevice" \
1491 and not function.isAlias:
1492 objectType = function.arguments[-2].getType()
1494 yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType)
1496 yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function))
1500 yield "} // refdetails"
1504 Function.TYPE_PLATFORM: "object",
1505 Function.TYPE_INSTANCE: "instance",
1506 Function.TYPE_DEVICE: "device"
1509 for function in functions:
1510 deleterArgsString = ''
1511 if function.name == "createDevice":
1512 # createDevice requires two additional parameters to setup VkDevice deleter
1513 deleterArgsString = "vkp, instance, object, " + function.arguments[-1].name
1515 deleterArgsString = "vk, %s, %s" % (dtorDict[function.type], function.arguments[-1].name)
1517 yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr(function.ifaceArgs + function.arguments))
1519 yield "\t%s object = 0;" % function.objectType
1520 yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"]))
1521 yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, deleterArgsString)
1525 writeInlFile(filename, INL_HEADER, makeRefUtilImpl())
1527 def writeStructTraitsImpl (api, filename):
1529 for type in api.compositeTypes:
1530 if type.getClassName() == "struct" and type.members[0].name == "sType" and not type.isAlias and type.name != "VkBaseOutStructure" and type.name != "VkBaseInStructure":
1531 yield "template<> VkStructureType getStructureType<%s> (void)" % type.name
1533 yield "\treturn %s;" % prefixName("VK_STRUCTURE_TYPE_", type.name)
1537 writeInlFile(filename, INL_HEADER, gen())
1539 def writeNullDriverImpl (api, filename):
1540 def genNullDriverImpl ():
1541 specialFuncNames = [
1542 "vkCreateGraphicsPipelines",
1543 "vkCreateComputePipelines",
1544 "vkCreateRayTracingPipelinesNV",
1545 "vkCreateRayTracingPipelinesKHR",
1546 "vkGetInstanceProcAddr",
1547 "vkGetDeviceProcAddr",
1548 "vkEnumeratePhysicalDevices",
1549 "vkEnumerateInstanceExtensionProperties",
1550 "vkEnumerateDeviceExtensionProperties",
1551 "vkGetPhysicalDeviceFeatures",
1552 "vkGetPhysicalDeviceFeatures2KHR",
1553 "vkGetPhysicalDeviceProperties",
1554 "vkGetPhysicalDeviceProperties2KHR",
1555 "vkGetPhysicalDeviceQueueFamilyProperties",
1556 "vkGetPhysicalDeviceMemoryProperties",
1557 "vkGetPhysicalDeviceFormatProperties",
1558 "vkGetPhysicalDeviceImageFormatProperties",
1560 "vkGetBufferMemoryRequirements",
1561 "vkGetBufferMemoryRequirements2KHR",
1562 "vkGetImageMemoryRequirements",
1563 "vkGetImageMemoryRequirements2KHR",
1567 "vkAllocateDescriptorSets",
1568 "vkFreeDescriptorSets",
1569 "vkResetDescriptorPool",
1570 "vkAllocateCommandBuffers",
1571 "vkFreeCommandBuffers",
1572 "vkCreateDisplayModeKHR",
1573 "vkCreateSharedSwapchainsKHR",
1574 "vkGetPhysicalDeviceExternalBufferPropertiesKHR",
1575 "vkGetPhysicalDeviceImageFormatProperties2KHR",
1576 "vkGetMemoryAndroidHardwareBufferANDROID",
1579 coreFunctions = [f for f in api.functions if not f.isAlias]
1580 specialFuncs = [f for f in coreFunctions if f.name in specialFuncNames]
1581 createFuncs = [f for f in coreFunctions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs]
1582 destroyFuncs = [f for f in coreFunctions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs]
1583 dummyFuncs = [f for f in coreFunctions if f not in specialFuncs + createFuncs + destroyFuncs]
1585 def getHandle (name):
1586 for handle in api.handles:
1587 if handle.name == name[0]:
1589 raise Exception("No such handle: %s" % name)
1591 for function in createFuncs:
1592 objectType = function.arguments[-1].type[:-1]
1593 argsStr = ", ".join([a.name for a in function.arguments[:-1]])
1595 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1597 yield "\tDE_UNREF(%s);" % function.arguments[-2].name
1599 if getHandle(objectType).type == Handle.TYPE_NONDISP:
1600 yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[0][2:], objectType[0], argsStr)
1602 yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[0][2:], objectType[0], argsStr)
1606 for function in destroyFuncs:
1607 objectArg = function.arguments[-2]
1609 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1611 for arg in function.arguments[:-2]:
1612 yield "\tDE_UNREF(%s);" % arg.name
1614 if getHandle(objectArg.type).type == Handle.TYPE_NONDISP:
1615 yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.getType()[2:], objectArg.getType(), objectArg.name, function.arguments[-1].name)
1617 yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.getType()[2:], objectArg.getType(), objectArg.name, function.arguments[-1].name)
1622 for function in dummyFuncs:
1623 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1625 for arg in function.arguments:
1626 yield "\tDE_UNREF(%s);" % arg.name
1627 if function.returnType != "void":
1628 yield "\treturn VK_SUCCESS;"
1632 def genFuncEntryTable (type, name):
1633 funcs = [f for f in api.functions if f.getType() == type]
1635 for f in api.functions:
1637 refFuncs[f.alias] = f
1639 yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name
1641 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]):
1647 for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"):
1650 for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"):
1653 for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"):
1656 writeInlFile(filename, INL_HEADER, genNullDriverImpl())
1658 def writeTypeUtil (api, filename):
1659 # Structs filled by API queries are not often used in test code
1660 QUERY_RESULT_TYPES = set([
1661 "VkPhysicalDeviceFeatures",
1662 "VkPhysicalDeviceLimits",
1663 "VkFormatProperties",
1664 "VkImageFormatProperties",
1665 "VkPhysicalDeviceSparseProperties",
1666 "VkQueueFamilyProperties",
1669 "StdVideoH264SpsVuiFlags",
1670 "StdVideoH264SpsFlags",
1671 "StdVideoH264PpsFlags",
1672 "StdVideoDecodeH264PictureInfoFlags",
1673 "StdVideoDecodeH264ReferenceInfoFlags",
1674 "StdVideoDecodeH264MvcElementFlags",
1675 "StdVideoEncodeH264SliceHeaderFlags",
1676 "StdVideoEncodeH264PictureInfoFlags",
1677 "StdVideoEncodeH264RefMgmtFlags",
1678 "StdVideoEncodeH264ReferenceInfoFlags",
1679 "StdVideoH265HrdFlags",
1680 "StdVideoH265VpsFlags",
1681 "StdVideoH265SpsVuiFlags",
1682 "StdVideoH265SpsFlags",
1683 "StdVideoH265PpsFlags",
1684 "StdVideoDecodeH265PictureInfoFlags",
1685 "StdVideoDecodeH265ReferenceInfoFlags",
1686 "StdVideoEncodeH265PictureInfoFlags",
1687 "StdVideoEncodeH265SliceHeaderFlags",
1688 "StdVideoEncodeH265ReferenceModificationFlags",
1689 "StdVideoEncodeH265ReferenceInfoFlags",
1690 "StdVideoEncodeH265SliceSegmentHeaderFlags",
1692 COMPOSITE_TYPES = set([t.name for t in api.compositeTypes if not t.isAlias])
1694 def isSimpleStruct (type):
1695 def hasArrayMember (type):
1696 for member in type.members:
1697 if member.arraySize != '':
1701 def hasCompositeMember (type):
1702 for member in type.members:
1703 if member.getType() in COMPOSITE_TYPES:
1707 return type.typeClass == CompositeType.CLASS_STRUCT and \
1708 type.members[0].getType() != "VkStructureType" and \
1709 not type.name in QUERY_RESULT_TYPES and \
1710 not hasArrayMember(type) and \
1711 not hasCompositeMember(type)
1714 for type in api.compositeTypes:
1715 if not isSimpleStruct(type) or type.isAlias:
1718 name = type.name[2:] if type.name[:2].lower() == "vk" else type.name
1721 yield "inline %s make%s (%s)" % (type.name, name, argListToStr(type.members))
1723 yield "\t%s res;" % type.name
1724 for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]):
1726 yield "\treturn res;"
1729 writeInlFile(filename, INL_HEADER, gen())
1731 def writeDriverIds(apiName, filename):
1733 driverIdsString = []
1734 driverIdsString.append("static const struct\n"
1736 "\tstd::string driver;\n"
1738 "} driverIds [] =\n"
1741 vulkanHeaderFile = { "" : os.path.join(VULKAN_HEADERS_INCLUDE_DIR, "vulkan", "vulkan_core.h"),
1742 "SC" : os.path.join(SCRIPTS_SRC_DIR, "vulkan_sc_core.h") }
1743 vulkanCore = readFile(vulkanHeaderFile[apiName])
1745 items = re.search(r'(?:typedef\s+enum\s+VkDriverId\s*{)((.*\n)*)(?:}\s*VkDriverId\s*;)', vulkanCore).group(1).split(',')
1746 driverItems = dict()
1749 splitted = item.split('=')
1750 key = splitted[0].strip()
1751 value_str = splitted[1].strip()
1752 try: # is this previously defined value?
1753 value = driverItems[value_str]
1758 value_str = "\t// " + value_str
1759 driverItems[key] = value
1760 if not item == items[-1]:
1761 driverIdsString.append("\t{\"" + key + "\"" + ", " + value + "}," + value_str)
1763 driverIdsString.append("\t{\"" + key + "\"" + ", " + value + "}" + value_str)
1764 driverItems[key] = value
1766 driverIdsString.append("};")
1768 writeInlFile(filename, INL_HEADER, driverIdsString)
1771 def writeSupportedExtensions(apiName, api, filename):
1773 def writeExtensionsForVersions(map):
1776 result.append(" if (coreVersion >= " + str(version) + ")")
1778 for extension in map[version]:
1779 result.append(' dst.push_back("' + extension.name + '");')
1783 result.append(" DE_UNREF(coreVersion);")
1791 for ext in api.extensions:
1792 if ext.versionInCore != None:
1793 currVersion = Version(ext.versionInCore[1:])
1794 # VulkanSC is based on Vulkan 1.2. Any Vulkan version greater than 1.2 should be excluded
1795 if apiName=='SC' and currVersion.api==0 and currVersion.major==1 and currVersion.minor>2:
1797 if ext.versionInCore[0] == 'instance':
1798 list = instanceMap.get(Version(ext.versionInCore[1:]))
1799 instanceMap[Version(ext.versionInCore[1:])] = list + [ext] if list else [ext]
1801 list = deviceMap.get(Version(ext.versionInCore[1:]))
1802 deviceMap[Version(ext.versionInCore[1:])] = list + [ext] if list else [ext]
1803 versionSet.add(Version(ext.versionInCore[1:]))
1805 # add list of extensions missing in Vulkan SC specification
1807 for extensionName, data in api.additionalExtensionData:
1808 # make sure that this extension was registered
1809 if 'register_extension' not in data.keys():
1811 # save array containing 'device' or 'instance' string followed by the optional vulkan version in which this extension is core;
1812 # note that register_extension section is also required for partialy promoted extensions like VK_EXT_extended_dynamic_state2
1813 # but those extensions should not fill 'core' tag
1814 match = re.match("(\d).(\d).(\d).(\d)", data['register_extension']['core'])
1816 currVersion = Version([int(match.group(1)), int(match.group(2)), int(match.group(3)), int(match.group(4))])
1817 ext = Extension(extensionName, 0, 0, 0, 0, 0, 0, 0, 0, 0)
1818 if currVersion.api==0 and currVersion.major==1 and currVersion.minor>2:
1820 if data['register_extension']['type'] == 'instance':
1821 list = instanceMap.get(currVersion)
1822 instanceMap[currVersion] = list + [ext] if list else [ext]
1824 list = deviceMap.get(currVersion)
1825 deviceMap[currVersion] = list + [ext] if list else [ext]
1826 versionSet.add(currVersion)
1828 lines = addVersionDefines(versionSet) + [
1830 "void getCoreDeviceExtensionsImpl (uint32_t coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(deviceMap) != 0 or apiName == 'SC' else ""),
1831 "{"] + writeExtensionsForVersions(deviceMap) + [
1834 "void getCoreInstanceExtensionsImpl (uint32_t coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(instanceMap) != 0 or apiName == 'SC' else ""),
1835 "{"] + writeExtensionsForVersions(instanceMap) + [
1837 ""] + removeVersionDefines(versionSet)
1838 writeInlFile(filename, INL_HEADER, lines)
1841 def writeExtensionFunctions (api, filename):
1843 def isInstanceExtension (ext):
1844 if ext.name and ext.functions:
1845 if ext.functions[0].getType() == Function.TYPE_INSTANCE:
1850 def isDeviceExtension (ext):
1851 if ext.name and ext.functions:
1852 if ext.functions[0].getType() == Function.TYPE_DEVICE:
1857 def writeExtensionNameArrays ():
1858 instanceExtensionNames = []
1859 deviceExtensionNames = []
1860 for ext in api.extensions:
1861 if ext.name and isInstanceExtension(ext):
1862 instanceExtensionNames += [ext.name]
1863 elif ext.name and isDeviceExtension(ext):
1864 deviceExtensionNames += [ext.name]
1865 yield '::std::string instanceExtensionNames[] =\n{'
1866 for instanceExtName in instanceExtensionNames:
1867 if (instanceExtName == instanceExtensionNames[len(instanceExtensionNames) - 1]):
1868 yield '\t"%s"' % instanceExtName
1870 yield '\t"%s",' % instanceExtName
1872 yield '::std::string deviceExtensionNames[] =\n{'
1873 for deviceExtName in deviceExtensionNames:
1874 if (deviceExtName == deviceExtensionNames[len(deviceExtensionNames) - 1]):
1875 yield '\t"%s"' % deviceExtName
1877 yield '\t"%s",' % deviceExtName
1880 def writeExtensionFunctions (functionType):
1882 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
1883 if functionType == Function.TYPE_INSTANCE:
1884 yield 'void getInstanceExtensionFunctions (uint32_t apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{'
1885 dg_list = ["vkGetPhysicalDevicePresentRectanglesKHR"]
1886 elif functionType == Function.TYPE_DEVICE:
1887 yield 'void getDeviceExtensionFunctions (uint32_t apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{'
1888 dg_list = ["vkGetDeviceGroupPresentCapabilitiesKHR", "vkGetDeviceGroupSurfacePresentModesKHR", "vkAcquireNextImage2KHR"]
1889 for ext in api.extensions:
1892 for func in ext.functions:
1893 if func.getType() == functionType:
1894 # only add functions with same vendor as extension
1895 # this is a workaroudn for entrypoints requiring more
1896 # than one excetions and lack of the dependency in vulkan_core.h
1897 vendor = ext.name.split('_')[1]
1898 if func.name.endswith(vendor):
1899 funcNames.append(func.name)
1901 yield '\tif (extName == "%s")' % ext.name
1903 for funcName in funcNames:
1904 if funcName in dg_list:
1905 yield '\t\tif(apiVersion >= VK_API_VERSION_1_1) functions.push_back("%s");' % funcName
1907 yield '\t\tfunctions.push_back("%s");' % funcName
1908 if ext.name == "VK_KHR_device_group":
1909 for dg_func in dg_list:
1910 yield '\t\tif(apiVersion < VK_API_VERSION_1_1) functions.push_back("%s");' % dg_func
1913 isFirstWrite = False
1914 if not isFirstWrite:
1915 yield '\tDE_FATAL("Extension name not found");'
1919 for line in writeExtensionFunctions(Function.TYPE_INSTANCE):
1922 for line in writeExtensionFunctions(Function.TYPE_DEVICE):
1925 for line in writeExtensionNameArrays():
1928 writeInlFile(filename, INL_HEADER, lines)
1930 def writeCoreFunctionalities(api, filename):
1931 functionOriginValues = ["FUNCTIONORIGIN_PLATFORM", "FUNCTIONORIGIN_INSTANCE", "FUNCTIONORIGIN_DEVICE"]
1932 lines = addVersionDefines(api.versions) + [
1934 'enum FunctionOrigin', '{'] + [line for line in indentLines([
1935 '\t' + functionOriginValues[0] + '\t= 0,',
1936 '\t' + functionOriginValues[1] + ',',
1937 '\t' + functionOriginValues[2]])] + [
1940 "typedef ::std::pair<const char*, FunctionOrigin> FunctionInfo;",
1941 "typedef ::std::vector<FunctionInfo> FunctionInfosList;",
1942 "typedef ::std::map<uint32_t, FunctionInfosList> ApisMap;",
1944 "void initApisMap (ApisMap& apis)",
1946 " apis.clear();"] + [
1947 " apis.insert(::std::pair<uint32_t, FunctionInfosList>(" + str(v) + ", FunctionInfosList()));" for v in api.versions] + [
1951 for index, v in enumerate(api.versions):
1953 apiVersions.append("VK_VERSION_{0}_{1}".format(v.major, v.minor))
1954 # iterate over all functions that are core in latest vulkan version
1955 # note that first item in api.extension array are actually all definitions that are in vulkan.h.in before section with extensions
1956 for fun in api.extensions[0].functions:
1957 if fun.apiVersion in apiVersions:
1958 funcs.append(' apis[' + str(v) + '].push_back(FunctionInfo("' + fun.name + '",\t' + functionOriginValues[fun.getType()] + '));')
1959 lines = lines + [line for line in indentLines(funcs)] + [""]
1961 lines = lines + ["}", ""] + removeVersionDefines(api.versions)
1962 writeInlFile(filename, INL_HEADER, lines)
1964 def camelToSnake(name):
1965 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
1966 return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()
1968 def writeDeviceFeatures2(api, filename):
1969 def structInAPI(name):
1970 for c in api.compositeTypes:
1975 # list of structures that should be tested with getPhysicalDeviceFeatures2
1976 # this is not posible to determine from vulkan_core.h, if new feature structures
1977 # are added they should be manualy added to this list
1978 testedStructures = [
1979 'VkPhysicalDevice4444FormatsFeaturesEXT',
1980 'VkPhysicalDevice8BitStorageFeatures',
1981 'VkPhysicalDevice16BitStorageFeatures',
1982 'VkPhysicalDeviceAccelerationStructureFeaturesKHR',
1983 'VkPhysicalDeviceASTCDecodeFeaturesEXT',
1984 'VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT',
1985 'VkPhysicalDeviceBufferDeviceAddressFeaturesEXT',
1986 'VkPhysicalDeviceBufferDeviceAddressFeatures',
1987 'VkPhysicalDeviceConditionalRenderingFeaturesEXT',
1988 'VkPhysicalDeviceCustomBorderColorFeaturesEXT',
1989 'VkPhysicalDeviceColorWriteEnableFeaturesEXT',
1990 'VkPhysicalDeviceDescriptorIndexingFeatures',
1991 'VkPhysicalDeviceDepthClipEnableFeaturesEXT',
1992 'VkPhysicalDeviceDynamicRenderingFeatures',
1993 'VkPhysicalDeviceExtendedDynamicStateFeaturesEXT',
1994 'VkPhysicalDeviceExtendedDynamicState2FeaturesEXT',
1995 'VkPhysicalDeviceFragmentDensityMapFeaturesEXT',
1996 'VkPhysicalDeviceFragmentDensityMap2FeaturesEXT',
1997 'VkPhysicalDeviceFragmentShadingRateFeaturesKHR',
1998 'VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR',
1999 'VkPhysicalDeviceInlineUniformBlockFeatures',
2000 'VkPhysicalDeviceIndexTypeUint8FeaturesEXT',
2001 'VkPhysicalDeviceImagelessFramebufferFeatures',
2002 'VkPhysicalDeviceImageRobustnessFeatures',
2003 'VkPhysicalDeviceHostQueryResetFeatures',
2004 'VkPhysicalDeviceLineRasterizationFeaturesEXT',
2005 'VkPhysicalDeviceMaintenance4Features',
2006 'VkPhysicalDeviceMultiviewFeatures',
2007 'VkPhysicalDeviceMultiDrawFeaturesEXT',
2008 'VkPhysicalDeviceMemoryPriorityFeaturesEXT',
2009 'VkPhysicalDeviceDeviceMemoryReportFeaturesEXT',
2010 'VkPhysicalDevicePerformanceQueryFeaturesKHR',
2011 'VkPhysicalDevicePipelineCreationCacheControlFeatures',
2012 'VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR',
2013 'VkPhysicalDevicePresentIdFeaturesKHR',
2014 'VkPhysicalDevicePresentWaitFeaturesKHR',
2015 'VkPhysicalDeviceProtectedMemoryFeatures',
2016 'VkPhysicalDeviceProvokingVertexFeaturesEXT',
2017 'VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT',
2018 'VkPhysicalDevicePrivateDataFeatures',
2019 'VkPhysicalDeviceRayTracingPipelineFeaturesKHR',
2020 'VkPhysicalDeviceRayQueryFeaturesKHR',
2021 'VkPhysicalDeviceRobustness2FeaturesEXT',
2022 'VkPhysicalDeviceSamplerYcbcrConversionFeatures',
2023 'VkPhysicalDeviceScalarBlockLayoutFeatures',
2024 'VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures',
2025 'VkPhysicalDeviceShaderAtomicInt64Features',
2026 'VkPhysicalDeviceShaderAtomicFloatFeaturesEXT',
2027 'VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT',
2028 'VkPhysicalDeviceShaderFloat16Int8Features',
2029 'VkPhysicalDeviceShaderClockFeaturesKHR',
2030 'VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures',
2031 'VkPhysicalDeviceShaderDrawParametersFeatures',
2032 'VkPhysicalDeviceShaderIntegerDotProductFeatures',
2033 'VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures',
2034 'VkPhysicalDeviceShaderTerminateInvocationFeatures',
2035 'VkPhysicalDeviceSubgroupSizeControlFeatures',
2036 'VkPhysicalDeviceSynchronization2Features',
2037 'VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT',
2038 'VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT',
2039 'VkPhysicalDeviceTextureCompressionASTCHDRFeatures',
2040 'VkPhysicalDeviceTimelineSemaphoreFeatures',
2041 'VkPhysicalDeviceTransformFeedbackFeaturesEXT',
2042 'VkPhysicalDeviceUniformBufferStandardLayoutFeatures',
2043 'VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR',
2044 'VkPhysicalDeviceVariablePointersFeatures',
2045 'VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT',
2046 'VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT',
2047 'VkPhysicalDeviceVulkanMemoryModelFeaturesKHR',
2048 'VkPhysicalDeviceYcbcrImageArraysFeaturesEXT',
2049 'VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT',
2050 'VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures',
2053 # helper class used to encapsulate all data needed during generation
2054 class StructureDetail:
2055 def __init__ (self, name):
2056 nameResult = re.search('(.*)Features(.*)', name[len('VkPhysicalDevice'):])
2058 # generate structure type name from structure name
2059 # note that sometimes digits are separated with '_':
2060 # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT
2061 # but mostly they are not:
2062 # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES
2064 'FragmentDensityMap2' : ['FRAGMENT', 'DENSITY', 'MAP', '2'],
2065 'Ycbcr2Plane444Formats' : ['YCBCR', '2', 'PLANE', '444', 'FORMATS'],
2066 'ASTCDecode' : ['ASTC', 'DECODE'],
2067 '4444Formats' : ['4444', 'FORMATS'],
2068 'TextureCompressionASTCHDR' : ['TEXTURE', 'COMPRESSION', 'ASTC', 'HDR'],
2069 'Synchronization2' : ['SYNCHRONIZATION', '2'],
2070 'ShaderAtomicFloat2' : ['SHADER', 'ATOMIC', 'FLOAT', '2'],
2071 'Robustness2' : ['ROBUSTNESS', '2'],
2072 'Maintenance4' : ['MAINTENANCE', '4'],
2073 'ExtendedDynamicState2' : ['EXTENDED', 'DYNAMIC', 'STATE', '2'],
2075 nameSplitUp = specialCaseDict.get(nameResult.group(1))
2076 if nameSplitUp == None:
2077 nameSplit = re.findall(r'[1-9A-Z]+(?:[a-z1-9]+|[A-Z]*(?=[A-Z]|$))', nameResult.group(1))
2078 nameSplitUp = map(str.upper, nameSplit)
2079 nameSplitUp = list(nameSplitUp) + ['FEATURES']
2080 # check if there is extension suffix
2081 if (len(nameResult.group(2)) != 0):
2082 nameSplitUp.append(nameResult.group(2))
2084 self.sType = 'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_' + '_'.join(nameSplitUp)
2085 self.instanceName = 'd' + name[11:]
2086 self.flagName = 'is' + name[16:]
2087 self.extension = None
2092 # helper extension class used in algorith below
2093 class StructureFoundContinueToNextOne(Exception):
2095 existingStructures = list(filter(structInAPI, testedStructures)) # remove features not found in API ( important for Vulkan SC )
2096 testedStructureDetail = [StructureDetail(struct) for struct in existingStructures]
2097 # iterate over all searched structures and find extensions that enable them
2098 for structureDetail in testedStructureDetail:
2100 # iterate over all extensions
2101 for extension in api.extensions[1:]:
2102 # check composite types and typedefs in case extension is part of core
2103 for structureList in [extension.compositeTypes, extension.typedefs]:
2104 # iterate over all structures added by extension
2105 for extensionStructure in structureList:
2106 # compare checked structure name to name of structure from extension
2107 if structureDetail.name == extensionStructure.name:
2108 structureDetail.extension = extension.name
2109 if extension.versionInCore is not None:
2110 structureDetail.api = extension.versionInCore[1]
2111 structureDetail.major = extension.versionInCore[2]
2112 structureDetail.minor = extension.versionInCore[3]
2113 raise StructureFoundContinueToNextOne
2114 except StructureFoundContinueToNextOne:
2116 for structureDetail in testedStructureDetail:
2117 for compositeType in api.compositeTypes:
2118 if structureDetail.name != compositeType.name:
2120 structureMembers = compositeType.members[2:]
2121 structureDetail.members = [m.name for m in structureMembers]
2122 if structureDetail.major is not None:
2124 # if structure was not added with extension then check if
2125 # it was added directly with one of vulkan versions
2126 apiVersion = compositeType.apiVersion
2127 if apiVersion is None:
2129 structureDetail.api = apiVersion.api
2130 structureDetail.major = apiVersion.major
2131 structureDetail.minor = apiVersion.minor
2133 # generate file content
2134 structureDefinitions = []
2135 featureEnabledFlags = []
2136 clearStructures = []
2139 verifyStructures = []
2140 for index, structureDetail in enumerate(testedStructureDetail):
2141 # create two instances of each structure
2143 structureDefinitions.append(structureDetail.name + nameSpacing + structureDetail.instanceName + '[count];')
2144 # create flags that check if proper extension or vulkan version is available
2146 extension = structureDetail.extension
2147 major = structureDetail.major
2148 if extension is not None:
2149 condition = ' checkExtension(properties, "' + extension + '")'
2150 if major is not None:
2155 condition += 'context.contextSupports(vk::ApiVersion(' + str(structureDetail.api) + ', ' + str(major) + ', ' + str(structureDetail.minor) + ', 0))'
2159 nameSpacing = '\t' * int((len(structureDetail.name) - 4) / 4)
2160 featureEnabledFlags.append('const bool' + nameSpacing + structureDetail.flagName + ' =' + condition)
2161 # clear memory of each structure
2162 clearStructures.append('\tdeMemset(&' + structureDetail.instanceName + '[ndx], 0xFF * ndx, sizeof(' + structureDetail.name + '));')
2163 # construct structure chain
2164 nextInstanceName = 'DE_NULL';
2165 if index < len(testedStructureDetail)-1:
2166 nextInstanceName = '&' + testedStructureDetail[index+1].instanceName + '[ndx]'
2167 structureChain.append([
2168 '\t\t' + structureDetail.instanceName + '[ndx].sType = ' + structureDetail.flagName + ' ? ' + structureDetail.sType + ' : VK_STRUCTURE_TYPE_MAX_ENUM;',
2169 '\t\t' + structureDetail.instanceName + '[ndx].pNext = DE_NULL;'])
2170 # construct log section
2171 logStructures.append([
2172 '\tif (' + structureDetail.flagName + ')',
2173 '\t\tlog << TestLog::Message << ' + structureDetail.instanceName + '[0] << TestLog::EndMessage;'
2175 #construct verification section
2176 verifyStructure = []
2177 verifyStructure.append('\tif (' + structureDetail.flagName + ' &&')
2178 for index, m in enumerate(structureDetail.members):
2179 prefix = '\t\t(' if index == 0 else '\t\t '
2180 postfix = '))' if index == len(structureDetail.members)-1 else ' ||'
2181 verifyStructure.append(prefix + structureDetail.instanceName + '[0].' + m + ' != ' + structureDetail.instanceName + '[1].' + m + postfix)
2182 if len(structureDetail.members) == 0:
2183 verifyStructure.append('\t\tfalse)')
2184 verifyStructure.append('\t{\n\t\tTCU_FAIL("Mismatch between ' + structureDetail.name + '");\n\t}')
2185 verifyStructures.append(verifyStructure)
2187 # construct file content
2190 # individual test functions
2191 for n, x in enumerate(testedStructureDetail):
2192 stream.append("tcu::TestStatus testPhysicalDeviceFeature" + x.instanceName[len('device'):]+" (Context& context)")
2194 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
2195 const CustomInstance instance (createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
2196 const InstanceDriver& vki (instance.getDriver());
2197 const int count = 2u;
2198 TestLog& log = context.getTestContext().getLog();
2199 VkPhysicalDeviceFeatures2 extFeatures;
2200 vector<VkExtensionProperties> properties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
2202 stream.append("\t"+structureDefinitions[n])
2203 stream.append("\t"+featureEnabledFlags[n])
2205 stream.append('\tfor (int ndx = 0; ndx < count; ++ndx)\n\t{')
2206 stream.append("\t" + clearStructures[n])
2207 stream.extend(structureChain[n])
2210 '\t\tdeMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));\n'
2211 '\t\textFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;\n'
2212 '\t\textFeatures.pNext = &' + testedStructureDetail[n].instanceName + '[ndx];\n\n'
2213 '\t\tvki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);')
2214 stream.append('\t}\n')
2215 stream.extend(logStructures[n])
2217 stream.extend(verifyStructures[n])
2218 stream.append('\treturn tcu::TestStatus::pass("Querying succeeded");')
2219 stream.append("}\n")
2221 # function to create tests
2223 void addSeparateFeatureTests (tcu::TestCaseGroup* testGroup)
2226 for x in testedStructureDetail:
2227 stream.append('\taddFunctionCase(testGroup, "' + camelToSnake(x.instanceName[len('device'):]) + '", "' + x.name + '", testPhysicalDeviceFeature' + x.instanceName[len('device'):] + ');')
2228 stream.append('}\n')
2231 writeInlFile(filename, INL_HEADER, stream)
2233 def generateDeviceFeaturesDefs(apiName, src):
2234 # look for definitions
2235 ptrnSType = r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_FEATURES(\w*)\s*='
2236 matches = re.findall(ptrnSType, src, re.M)
2237 matches = sorted(matches, key=lambda m: m[0])
2238 # hardcoded list of core extensions having features and missing from Vulkan SC
2239 missingVulkanSCExt = \
2240 '#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME \"VK_KHR_16bit_storage\"\n' \
2241 '#define VK_KHR_8BIT_STORAGE_EXTENSION_NAME \"VK_KHR_8bit_storage\"\n' \
2242 '#define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME \"VK_KHR_buffer_device_address\"\n' \
2243 '#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME \"VK_EXT_descriptor_indexing\"\n' \
2244 '#define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME \"VK_EXT_host_query_reset\"\n' \
2245 '#define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME \"VK_KHR_imageless_framebuffer\"\n' \
2246 '#define VK_KHR_MULTIVIEW_EXTENSION_NAME \"VK_KHR_multiview\"\n' \
2247 '#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME \"VK_KHR_sampler_ycbcr_conversion\"\n' \
2248 '#define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME \"VK_EXT_scalar_block_layout\"\n' \
2249 '#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME \"VK_KHR_separate_depth_stencil_layouts\"\n' \
2250 '#define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME \"VK_KHR_shader_atomic_int64\"\n' \
2251 '#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME \"VK_KHR_shader_draw_parameters\"\n' \
2252 '#define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME \"VK_KHR_shader_float16_int8\"\n' \
2253 '#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME \"VK_KHR_shader_subgroup_extended_types\"\n' \
2254 '#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME \"VK_KHR_timeline_semaphore\"\n' \
2255 '#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME \"VK_KHR_uniform_buffer_standard_layout\"\n' \
2256 '#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME \"VK_KHR_variable_pointers\"\n' \
2257 '#define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME \"VK_KHR_vulkan_memory_model\"\n'
2258 # construct final list
2260 for sType, sSuffix in matches:
2261 structName = re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '')
2262 ptrnStructName = r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Features' + sSuffix.replace('_', '') + ')'
2263 matchStructName = re.search(ptrnStructName, src, re.IGNORECASE)
2265 # handle special cases
2266 if sType == "EXCLUSIVE_SCISSOR":
2267 sType = "SCISSOR_EXCLUSIVE"
2268 elif sType == "ASTC_DECODE":
2269 sType = "ASTC_DECODE_MODE"
2270 elif sType == "MAINTENANCE_4":
2271 sType = "MAINTENANCE4"
2272 elif sType == "YCBCR_2_PLANE_444_FORMATS":
2273 sType = "YCBCR_2PLANE_444_FORMATS"
2274 elif sType in {'VULKAN_1_1', 'VULKAN_1_2', 'VULKAN_1_3'}:
2276 elif sType == 'RASTERIZATION_ORDER_ATTACHMENT_ACCESS':
2277 # skip case that has const pNext pointer
2279 # end handling special cases
2280 ptrnExtensionName = r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_EXTENSION_NAME).+$'
2281 matchExtensionName = re.search(ptrnExtensionName, src, re.M)
2282 if matchExtensionName is None and apiName=='SC':
2283 matchExtensionName = re.search(ptrnExtensionName, missingVulkanSCExt, re.M)
2284 ptrnSpecVersion = r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_SPEC_VERSION).+$'
2285 matchSpecVersion = re.search(ptrnSpecVersion, src, re.M)
2286 defs.append( (sType, '', sSuffix, matchStructName.group(1), \
2287 matchExtensionName.group(0) if matchExtensionName else None,
2288 matchExtensionName.group(1) if matchExtensionName else None,
2289 matchSpecVersion.group(1) if matchSpecVersion else '0') )
2292 def generateDevicePropertiesDefs(apiName, src):
2293 # look for definitions
2294 ptrnSType = r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_PROPERTIES(\w*)\s*='
2295 matches = re.findall(ptrnSType, src, re.M)
2296 matches = sorted(matches, key=lambda m: m[0])
2297 # hardcoded list of core extensions having properties and missing from Vulkan SC
2298 missingVulkanSCExt = \
2299 '#define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME \"VK_KHR_depth_stencil_resolve\"\n' \
2300 '#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME \"VK_EXT_descriptor_indexing\"\n' \
2301 '#define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME \"VK_KHR_driver_properties\"\n' \
2302 '#define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME \"VK_KHR_shader_float_controls\"\n' \
2303 '#define VK_KHR_MAINTENANCE3_EXTENSION_NAME \"VK_KHR_maintenance3\"\n' \
2304 '#define VK_KHR_MULTIVIEW_EXTENSION_NAME \"VK_KHR_multiview\"\n' \
2305 '#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME \"VK_EXT_sampler_filter_minmax\"\n' \
2306 '#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME \"VK_KHR_timeline_semaphore\"\n'
2307 # construct final list
2309 for sType, sSuffix in matches:
2310 # handle special cases
2311 if sType in {'VULKAN_1_1', 'VULKAN_1_2', 'VULKAN_1_3', 'VULKAN_SC_1_0', 'GROUP', 'MEMORY_BUDGET', 'MEMORY', 'TOOL'}:
2313 # there are cases like VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD
2314 # where 2 is after PROPERTIES - to handle this we need to split suffix to two parts
2316 sExtSuffix = sSuffix
2317 suffixStart = sSuffix.rfind('_')
2319 sVerSuffix = sSuffix[:suffixStart]
2320 sExtSuffix = sSuffix[suffixStart:]
2321 # handle special case
2325 structName = re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '')
2326 ptrnStructName = r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Properties' + sSuffix.replace('_', '') + ')'
2327 matchStructName = re.search(ptrnStructName, src, re.M)
2330 if extType == "DISCARD_RECTANGLE":
2331 extType = "DISCARD_RECTANGLES"
2332 elif extType == "DRIVER":
2333 extType = "DRIVER_PROPERTIES"
2334 elif extType == "POINT_CLIPPING":
2335 extType = "MAINTENANCE_2"
2336 elif extType == "SHADER_CORE":
2337 extType = "SHADER_CORE_PROPERTIES"
2338 elif extType == "DRM":
2339 extType = "PHYSICAL_DEVICE_DRM"
2341 if extType == "MAINTENANCE_3":
2342 extType = "MAINTENANCE3"
2343 elif extType == "MAINTENANCE_4":
2344 extType = "MAINTENANCE4"
2345 elif extType == "POINT_CLIPPING":
2346 extType = "MAINTENANCE2"
2347 # end handling special cases
2348 ptrnExtensionName = r'^\s*#define\s+(\w+' + sExtSuffix + '_' + extType + sVerSuffix +'[_0-9]*_EXTENSION_NAME).+$'
2349 matchExtensionName = re.search(ptrnExtensionName, src, re.M)
2350 if matchExtensionName is None and apiName=='SC':
2351 matchExtensionName = re.search(ptrnExtensionName, missingVulkanSCExt, re.M)
2352 ptrnSpecVersion = r'^\s*#define\s+(\w+' + sExtSuffix + '_' + extType + sVerSuffix + '[_0-9]*_SPEC_VERSION).+$'
2353 matchSpecVersion = re.search(ptrnSpecVersion, src, re.M)
2354 defs.append( (sType, sVerSuffix, sExtSuffix, matchStructName.group(1), \
2355 matchExtensionName.group(0) if matchExtensionName else None,
2356 matchExtensionName.group(1) if matchExtensionName else None,
2357 matchSpecVersion.group (1) if matchSpecVersion else '0') )
2360 def writeDeviceFeatures(api, dfDefs, filename):
2361 # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs
2362 # and construct dictionary with all of their attributes
2365 blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$")
2366 for structureType in api.compositeTypes:
2367 match = blobPattern.match(structureType.name)
2369 allMembers = [member.name for member in structureType.members]
2370 vkVersion = match.group(1)
2371 blobMembers[vkVersion] = allMembers[2:]
2372 blobStructs[vkVersion] = set()
2373 initFromBlobDefinitions = []
2374 emptyInitDefinitions = []
2375 # iterate over all feature structures
2376 allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*")
2377 nonExtFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*$")
2378 for structureType in api.compositeTypes:
2379 # skip structures that are not feature structures
2380 if not allFeaturesPattern.match(structureType.name):
2382 # skip structures that were previously identified as blobs
2383 if blobPattern.match(structureType.name):
2385 if structureType.isAlias:
2387 # skip sType and pNext and just grab third and next attributes
2388 structureMembers = structureType.members[2:]
2389 notPartOfBlob = True
2390 if nonExtFeaturesPattern.match(structureType.name):
2391 # check if this member is part of any of the blobs
2392 for blobName, blobMemberList in blobMembers.items():
2393 # if just one member is not part of this blob go to the next blob
2394 # (we asume that all members are part of blob - no need to check all)
2395 if structureMembers[0].name not in blobMemberList:
2397 # add another feature structure name to this blob
2398 blobStructs[blobName].add(structureType)
2399 # add specialization for this feature structure
2401 for member in structureMembers:
2402 memberCopying += "\tfeatureType.{0} = allFeaturesBlobs.vk{1}.{0};\n".format(member.name, blobName)
2404 "template<> void initFeatureFromBlob<{0}>({0}& featureType, const AllFeaturesBlobs& allFeaturesBlobs)\n" \
2407 "}}".format(structureType.name, memberCopying)
2408 initFromBlobDefinitions.append(wholeFunction)
2409 notPartOfBlob = False
2410 # assuming that all members are part of blob, goto next
2412 # add empty template definition as on Fedora there are issue with
2413 # linking using just generic template - all specializations are needed
2415 emptyFunction = "template<> void initFeatureFromBlob<{0}>({0}&, const AllFeaturesBlobs&) {{}}"
2416 emptyInitDefinitions.append(emptyFunction.format(structureType.name))
2417 extensionDefines = []
2418 makeFeatureDescDefinitions = []
2419 featureStructWrappers = []
2420 for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extLine, extName, specVer) in enumerate(dfDefs):
2421 extensionNameDefinition = extName
2422 if not extensionNameDefinition:
2423 extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType)
2424 # construct defines with names
2426 extensionDefines.append(extLine)
2428 extensionDefines.append('#define {0} "not_existent_feature"'.format(extensionNameDefinition))
2429 # handle special cases
2430 if sType == "SCISSOR_EXCLUSIVE":
2431 sType = "EXCLUSIVE_SCISSOR"
2432 elif sType == "ASTC_DECODE_MODE":
2433 sType = "ASTC_DECODE"
2434 elif sType == "MAINTENANCE4":
2435 sType = "MAINTENANCE_4"
2436 elif sType == "YCBCR_2PLANE_444_FORMATS":
2437 sType = "YCBCR_2_PLANE_444_FORMATS"
2438 # end handling special cases
2439 # construct makeFeatureDesc template function definitions
2440 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sVerSuffix + sExtSuffix)
2441 makeFeatureDescDefinitions.append("template<> FeatureDesc makeFeatureDesc<{0}>(void) " \
2442 "{{ return FeatureDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dfDefs)-idx))
2443 # construct CreateFeatureStruct wrapper block
2444 featureStructWrappers.append("\t{{ createFeatureStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer))
2445 # construct function that will check for which vk version structure sType is part of blob
2446 blobChecker = "deUint32 getBlobFeaturesVersion (VkStructureType sType)\n{\n" \
2447 "\tconst std::map<VkStructureType, deUint32> sTypeBlobMap\n" \
2449 # iterate over blobs with list of structures
2450 for blobName in sorted(blobStructs.keys()):
2451 blobChecker += "\t\t// Vulkan{0}\n".format(blobName)
2452 # iterate over all feature structures in current blob
2453 structuresList = list(blobStructs[blobName])
2454 structuresList = sorted(structuresList, key=lambda s: s.name)
2455 for structType in structuresList:
2456 # find definition of this structure in dfDefs
2457 structName = structType.name
2458 # handle special cases
2459 if structName == 'VkPhysicalDeviceShaderDrawParameterFeatures':
2460 structName = 'VkPhysicalDeviceShaderDrawParametersFeatures'
2461 # end handling special cases
2462 structDef = [s for s in dfDefs if s[3] == structName][0]
2463 sType = structDef[0]
2464 sSuffix = structDef[1] + structDef[2]
2465 # handle special cases
2466 if sType == "SCISSOR_EXCLUSIVE":
2467 sType = "EXCLUSIVE_SCISSOR"
2468 elif sType == "MAINTENANCE4":
2469 sType = "MAINTENANCE_4"
2470 # end handling special cases
2471 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sSuffix)
2472 tabs = "\t" * int((88 - len(sTypeName)) / 4)
2473 blobChecker += "\t\t{{ {0},{1}VK_API_VERSION_{2}_{3} }},\n".format(sTypeName, tabs, blobName[0], blobName[1])
2474 blobChecker += "\t};\n\n" \
2475 "\tauto it = sTypeBlobMap.find(sType);\n" \
2476 "\tif(it == sTypeBlobMap.end())\n" \
2478 "\treturn it->second;\n" \
2480 # combine all definition lists
2482 '#include "vkDeviceFeatures.hpp"\n',
2484 stream.extend(extensionDefines)
2486 stream.extend(initFromBlobDefinitions)
2487 stream.append('\n// generic template is not enough for some compilers')
2488 stream.extend(emptyInitDefinitions)
2490 stream.extend(makeFeatureDescDefinitions)
2492 stream.append('static const FeatureStructCreationData featureStructCreationArray[]\n{')
2493 stream.extend(featureStructWrappers)
2494 stream.append('};\n')
2495 stream.append(blobChecker)
2496 stream.append('} // vk\n')
2497 writeInlFile(filename, INL_HEADER, stream)
2499 def writeDeviceFeatureTest(apiName, api, filename):
2501 coreFeaturesPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$")
2504 # iterate over all feature structures
2505 allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*")
2506 for structureType in api.compositeTypes:
2507 # skip structures that are not feature structures
2508 if not allFeaturesPattern.match(structureType.name):
2510 # skip alias structures
2511 if structureType.isAlias:
2513 # skip sType and pNext and just grab third and next attributes
2514 structureMembers = structureType.members[2:]
2517 for member in structureMembers:
2518 items.append(" FEATURE_ITEM ({0}, {1}),".format(structureType.name, member.name))
2521 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest{4} (Context& context)
2523 const PlatformInterface& vkp = context.getPlatformInterface();
2524 tcu::TestLog& log = context.getTestContext().getLog();
2525 tcu::ResultCollector resultCollector (log);
2526 const CustomInstance instance (createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
2527 const InstanceDriver& instanceDriver (instance.getDriver());
2528 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
2529 const deUint32 queueFamilyIndex = 0;
2530 const deUint32 queueCount = 1;
2531 const float queuePriority = 1.0f;
2532 const DeviceFeatures deviceFeaturesAll (context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
2533 const VkPhysicalDeviceFeatures2 deviceFeatures2 = deviceFeaturesAll.getCoreFeatures2();
2535 bool isSubProcess = context.getTestContext().getCommandLine().isSubProcess();
2538 VkPhysicalDeviceFeatures emptyDeviceFeatures;
2539 deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));
2541 // Only non-core extensions will be used when creating the device.
2542 vector<const char*> coreExtensions;
2543 getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
2544 vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
2546 vector<const char*> extensionNames;
2547 extensionNames.reserve(nonCoreExtensions.size());
2548 for (const string& extension : nonCoreExtensions)
2549 extensionNames.push_back(extension.c_str());
2551 if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<{0}>()))
2553 static const Feature features[] =
2557 auto* supportedFeatures = reinterpret_cast<const {0}*>(featuresStruct);
2558 checkFeatures(vkp, instance, instanceDriver, physicalDevice, {2}, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, {3}, emptyDeviceFeatures, {5});
2562 return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
2564 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
2567 additionalParams = ( 'memReservationStatMax, isSubProcess' if apiName == 'SC' else 'isSubProcess' )
2568 additionalDefs = ( ' VkDeviceObjectReservationCreateInfo memReservationStatMax = context.getResourceInterface()->getStatMax();' if apiName == 'SC' else '')
2569 featureItems.append(testBlock.format(structureType.name, "\n".join(items), len(items), ("DE_NULL" if coreFeaturesPattern.match(structureType.name) else "&extensionNames"), structureType.name[len('VkPhysicalDevice'):], additionalParams, additionalDefs))
2571 testFunctions.append("createDeviceWithUnsupportedFeaturesTest" + structureType.name[len('VkPhysicalDevice'):])
2574 stream.extend(featureItems)
2576 void addSeparateUnsupportedFeatureTests (tcu::TestCaseGroup* testGroup)
2579 for x in testFunctions:
2580 stream.append('\taddFunctionCase(testGroup, "' + camelToSnake(x[len('createDeviceWithUnsupportedFeaturesTest'):]) + '", "' + x + '", ' + x + ');')
2581 stream.append('}\n')
2583 writeInlFile(filename, INL_HEADER, stream)
2585 def writeDeviceProperties(api, dpDefs, filename):
2586 # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs
2587 # and construct dictionary with all of their attributes
2590 blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Properties[0-9]*$")
2591 for structureType in api.compositeTypes:
2592 match = blobPattern.match(structureType.name)
2594 allMembers = [member.name for member in structureType.members]
2595 vkVersion = match.group(1)
2596 blobMembers[vkVersion] = allMembers[2:]
2597 blobStructs[vkVersion] = set()
2598 initFromBlobDefinitions = []
2599 emptyInitDefinitions = []
2600 # iterate over all property structures
2601 allPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*")
2602 nonExtPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*$")
2603 for structureType in api.compositeTypes:
2604 # skip structures that are not property structures
2605 if not allPropertiesPattern.match(structureType.name):
2607 # skip structures that were previously identified as blobs
2608 if blobPattern.match(structureType.name):
2610 if structureType.isAlias:
2612 # skip sType and pNext and just grab third and next attributes
2613 structureMembers = structureType.members[2:]
2614 notPartOfBlob = True
2615 if nonExtPropertiesPattern.match(structureType.name):
2616 # check if this member is part of any of the blobs
2617 for blobName, blobMemberList in blobMembers.items():
2618 # if just one member is not part of this blob go to the next blob
2619 # (we asume that all members are part of blob - no need to check all)
2620 if structureMembers[0].name not in blobMemberList:
2622 # add another property structure name to this blob
2623 blobStructs[blobName].add(structureType)
2624 # add specialization for this property structure
2626 for member in structureMembers:
2627 if not member.arraySize:
2628 # handle special case
2629 if structureType.name == "VkPhysicalDeviceSubgroupProperties" and "subgroup" not in member.name :
2630 blobMemberName = "subgroup" + member.name[0].capitalize() + member.name[1:]
2631 memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{2};\n".format(member.name, blobName, blobMemberName)
2632 # end handling special case
2634 memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{0};\n".format(member.name, blobName)
2636 memberCopying += "\tmemcpy(propertyType.{0}, allPropertiesBlobs.vk{1}.{0}, sizeof({2}) * {3});\n".format(member.name, blobName, member.type[0], member.arraySize[1:-1])
2638 "template<> void initPropertyFromBlob<{0}>({0}& propertyType, const AllPropertiesBlobs& allPropertiesBlobs)\n" \
2641 "}}".format(structureType.name, memberCopying)
2642 initFromBlobDefinitions.append(wholeFunction)
2643 notPartOfBlob = False
2644 # assuming that all members are part of blob, goto next
2646 # add empty template definition as on Fedora there are issue with
2647 # linking using just generic template - all specializations are needed
2649 emptyFunction = "template<> void initPropertyFromBlob<{0}>({0}&, const AllPropertiesBlobs&) {{}}"
2650 emptyInitDefinitions.append(emptyFunction.format(structureType.name))
2651 extensionDefines = []
2652 makePropertyDescDefinitions = []
2653 propertyStructWrappers = []
2654 for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extLine, extName, specVer) in enumerate(dpDefs):
2655 extensionNameDefinition = extName
2656 if not extensionNameDefinition:
2657 extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType)
2658 # construct defines with names
2660 extensionDefines.append(extLine)
2662 extensionDefines.append('#define {0} "core_property"'.format(extensionNameDefinition))
2663 # construct makePropertyDesc template function definitions
2664 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sVerSuffix + sExtSuffix)
2665 makePropertyDescDefinitions.append("template<> PropertyDesc makePropertyDesc<{0}>(void) " \
2666 "{{ return PropertyDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dpDefs)-idx))
2667 # construct CreateProperty struct wrapper block
2668 propertyStructWrappers.append("\t{{ createPropertyStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer))
2669 # construct method that will check if structure sType is part of blob
2670 blobChecker = "deUint32 getBlobPropertiesVersion (VkStructureType sType)\n{\n" \
2671 "\tconst std::map<VkStructureType, deUint32> sTypeBlobMap\n" \
2673 # iterate over blobs with list of structures
2674 for blobName in sorted(blobStructs.keys()):
2675 blobChecker += "\t\t// Vulkan{0}\n".format(blobName)
2676 # iterate over all feature structures in current blob
2677 structuresList = list(blobStructs[blobName])
2678 structuresList = sorted(structuresList, key=lambda s: s.name)
2679 for structType in structuresList:
2680 # find definition of this structure in dpDefs
2681 structName = structType.name
2682 structDef = [s for s in dpDefs if s[3] == structName][0]
2683 sType = structDef[0]
2684 sSuffix = structDef[1] + structDef[2]
2685 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sSuffix)
2686 tabs = "\t" * int((76 - len(sTypeName)) / 4)
2687 blobChecker += "\t\t{{ {0},{1}VK_API_VERSION_{2}_{3} }},\n".format(sTypeName, tabs, blobName[0], blobName[1])
2688 blobChecker += "\t};\n\n" \
2689 "\tauto it = sTypeBlobMap.find(sType);\n" \
2690 "\tif(it == sTypeBlobMap.end())\n" \
2692 "\treturn it->second;\n" \
2694 # combine all definition lists
2696 '#include "vkDeviceProperties.hpp"\n',
2698 stream.extend(extensionDefines)
2700 stream.extend(initFromBlobDefinitions)
2701 stream.append('\n// generic template is not enough for some compilers')
2702 stream.extend(emptyInitDefinitions)
2704 stream.extend(makePropertyDescDefinitions)
2706 stream.append('static const PropertyStructCreationData propertyStructCreationArray[] =\n{')
2707 stream.extend(propertyStructWrappers)
2708 stream.append('};\n')
2709 stream.append(blobChecker)
2710 stream.append('} // vk\n')
2711 writeInlFile(filename, INL_HEADER, stream)
2713 def genericDeviceFeaturesWriter(dfDefs, pattern, filename):
2715 for _, _, _, extStruct, _, _, _ in dfDefs:
2716 nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
2717 stream.append(pattern.format(extStruct, nameSubStr))
2718 writeInlFile(filename, INL_HEADER, indentLines(stream))
2720 def writeDeviceFeaturesDefaultDeviceDefs(dfDefs, filename):
2721 pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceFeatures.getFeatureType<{0}>();\t}}"
2722 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2724 def writeDeviceFeaturesContextDecl(dfDefs, filename):
2725 pattern = "const vk::{0}&\tget{1}\t(void) const;"
2726 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2728 def writeDeviceFeaturesContextDefs(dfDefs, filename):
2729 pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}"
2730 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2732 def genericDevicePropertiesWriter(dfDefs, pattern, filename):
2734 for _, _, _, extStruct, _, _, _ in dfDefs:
2735 nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
2736 if extStruct == "VkPhysicalDeviceRayTracingPropertiesNV":
2738 stream.append(pattern.format(extStruct, nameSubStr))
2739 writeInlFile(filename, INL_HEADER, indentLines(stream))
2741 def writeDevicePropertiesDefaultDeviceDefs(dfDefs, filename):
2742 pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceProperties.getPropertyType<{0}>();\t}}"
2743 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2745 def writeDevicePropertiesContextDecl(dfDefs, filename):
2746 pattern = "const vk::{0}&\tget{1}\t(void) const;"
2747 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2749 def writeDevicePropertiesContextDefs(dfDefs, filename):
2750 pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}"
2751 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2753 def writeMandatoryFeatures(api, filename):
2755 def structInAPI(name):
2756 for c in api.compositeTypes:
2764 for _, data in api.additionalExtensionData:
2765 if 'mandatory_features' not in data.keys():
2767 # sort to have same results for py2 and py3
2768 listStructFeatures = sorted(data['mandatory_features'].items(), key=lambda tup: tup[0])
2769 for structure, featuresList in listStructFeatures:
2770 for featureData in featuresList:
2771 # allow for featureless VKSC only extensions
2772 if not 'features' in featureData.keys() or 'requirements' not in featureData.keys():
2774 requirements = featureData['requirements']
2776 mandatory_variant = ''
2778 mandatory_variant = featureData['mandatory_variant']
2780 mandatory_variant = ''
2782 dictData.append( [ structure, featureData['features'], requirements, mandatory_variant] )
2784 if structure == 'VkPhysicalDeviceFeatures':
2786 # if structure is not in dict construct name of variable and add is as a first item
2787 if (structure not in dictStructs):
2788 dictStructs[structure] = ([structure[2:3].lower() + structure[3:]], mandatory_variant)
2789 # add first requirement if it is unique
2790 if requirements and (requirements[0] not in dictStructs[structure][0]):
2791 dictStructs[structure][0].append(requirements[0])
2794 stream.extend(['bool checkMandatoryFeatures(const vkt::Context& context)\n{',
2795 '\tif (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))',
2796 '\t\tTCU_THROW(NotSupportedError, "Extension VK_KHR_get_physical_device_properties2 is not present");',
2798 '\tVkPhysicalDevice\t\t\t\t\tphysicalDevice\t\t= context.getPhysicalDevice();',
2799 '\tconst InstanceInterface&\t\t\tvki\t\t\t\t\t= context.getInstanceInterface();',
2800 '\tconst vector<VkExtensionProperties>\tdeviceExtensions\t= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);',
2802 '\ttcu::TestLog& log = context.getTestContext().getLog();',
2803 '\tvk::VkPhysicalDeviceFeatures2 coreFeatures;',
2804 '\tdeMemset(&coreFeatures, 0, sizeof(coreFeatures));',
2805 '\tcoreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;',
2806 '\tvoid** nextPtr = &coreFeatures.pNext;',
2809 listStruct = sorted(dictStructs.items(), key=lambda tup: tup[0]) # sort to have same results for py2 and py3
2810 apiStruct = list( filter(lambda x : structInAPI(x[0]), listStruct)) # remove items not defined in current A
2812 for k, v in apiStruct:
2815 metaCondition = metaCondition + ' || defined(CTS_USES_' + v[1][0].upper() + ')'
2816 stream.extend(['#if ' + metaCondition[4:]])
2817 if (v[0][1].startswith("ApiVersion")):
2818 cond = '\tif (context.contextSupports(vk::' + v[0][1] + '))'
2820 cond = '\tif (vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "' + v[0][1] + '"))'
2821 stream.extend(['\tvk::' + k + ' ' + v[0][0]+ ';',
2822 '\tdeMemset(&' + v[0][0] + ', 0, sizeof(' + v[0][0] + '));',
2827 for i, req in enumerate(reqs) :
2828 if (req.startswith("ApiVersion")):
2829 cond = cond + 'context.contextSupports(vk::' + req + ')'
2831 cond = cond + 'isExtensionStructSupported(deviceExtensions, RequiredExtension("' + req + '"))'
2832 if i+1 < len(reqs) :
2833 cond = cond + ' || '
2835 stream.append('\t' + cond)
2836 stream.extend(['\t{',
2837 '\t\t' + v[0][0] + '.sType = getStructureType<' + k + '>();',
2838 '\t\t*nextPtr = &' + v[0][0] + ';',
2839 '\t\tnextPtr = &' + v[0][0] + '.pNext;',
2841 if metaCondition != '':
2842 stream.extend(['#endif // ' + metaCondition[4:],
2846 stream.extend(['\tcontext.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &coreFeatures);',
2847 '\tbool result = true;',
2852 if not structInAPI(v[0]): # remove items not defined in current API ( important for Vulkan SC )
2855 structName = 'coreFeatures.features';
2857 if len(v) == 4 and v[3] != '':
2858 # for x in v[3].split('_'):
2859 metaCondition = metaCondition + ' || defined(CTS_USES_' + v[3][0].upper() + ')'
2860 stream.extend(['#if ' + metaCondition[4:]])
2861 if v[0] != 'VkPhysicalDeviceFeatures' :
2862 structName = dictStructs[v[0]][0][0]
2865 for i, req in enumerate(v[2]) :
2866 if (req.startswith("ApiVersion")):
2867 condition = condition + 'context.contextSupports(vk::' + req + ')'
2869 condition = condition + req
2871 condition = condition + 'isExtensionStructSupported(deviceExtensions, RequiredExtension("' + req + '"))'
2872 if i+1 < len(v[2]) :
2873 condition = condition + ' && '
2874 condition = condition + ' )'
2875 stream.append('\t' + condition)
2876 stream.append('\t{')
2877 # Don't need to support an AND case since that would just be another line in the .txt
2879 stream.append('\t\tif ( ' + structName + '.' + v[1][0] + ' == VK_FALSE )')
2882 for i, feature in enumerate(v[1]):
2884 condition = condition + ' && '
2885 condition = condition + '( ' + structName + '.' + feature + ' == VK_FALSE )'
2886 condition = condition + ' )'
2887 stream.append('\t\t' + condition)
2888 featureSet = " or ".join(v[1])
2889 stream.extend(['\t\t{',
2890 '\t\t\tlog << tcu::TestLog::Message << "Mandatory feature ' + featureSet + ' not supported" << tcu::TestLog::EndMessage;',
2891 '\t\t\tresult = false;',
2894 if metaCondition != '':
2895 stream.extend(['#endif // ' + metaCondition[4:],
2900 stream.append('\treturn result;')
2901 stream.append('}\n')
2902 writeInlFile(filename, INL_HEADER, stream)
2904 def writeExtensionList(apiName, api, filename, extensionType):
2906 for extensionName, data in api.additionalExtensionData:
2907 # make sure extension name starts with VK_KHR
2908 if not extensionName.startswith('VK_KHR'):
2910 # make sure that this extension was registered
2911 if 'register_extension' not in data.keys():
2913 # make sure extension is intended for the vulkan variant
2917 if 'mandatory_features' in data.keys():
2918 for structure, listStruct in data['mandatory_features'].items():
2919 for featureData in listStruct:
2920 mandatory_variant = ''
2922 mandatory_variant = featureData['mandatory_variant']
2924 mandatory_variant = ''
2926 if 'vulkansc' in mandatory_variant:
2931 # make sure extension has proper type
2932 if extensionType == data['register_extension']['type']:
2933 extensionList.append(extensionName)
2934 extensionList.sort()
2935 # write list of all found extensions
2937 stream.append('static const char* s_allowed{0}KhrExtensions[] =\n{{'.format(extensionType.title()))
2938 for n in extensionList:
2939 stream.append('\t"' + n + '",')
2940 stream.append('};\n')
2941 writeInlFile(filename, INL_HEADER, stream)
2943 def parseCmdLineArgs():
2944 parser = argparse.ArgumentParser(description = "Generate Vulkan INL files",
2945 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
2946 parser.add_argument("-a",
2950 help="Choose between Vulkan and Vulkan SC")
2951 parser.add_argument("-o",
2955 help="Choose output directory")
2956 return parser.parse_args()
2958 def preprocessTopInclude(src, dir):
2959 pattern = r'#include\s+"([^\n]+)"'
2961 inc = re.search(pattern, src)
2964 incFileName = inc.string[inc.start(1):inc.end(1)]
2965 patternIncNamed = r'#include\s+"' + incFileName + '"'
2966 incBody = readFile(os.path.join(dir, incFileName)) if incFileName != 'vk_platform.h' else ''
2967 incBodySanitized = re.sub(pattern, '', incBody)
2968 bodyEndSanitized = re.sub(patternIncNamed, '', src[inc.end(0):])
2969 src = src[0:inc.start(0)] + incBodySanitized + bodyEndSanitized
2972 if __name__ == "__main__":
2973 args = parseCmdLineArgs()
2975 outputPath = DEFAULT_OUTPUT_DIR[args.api]
2976 # if argument was specified it is interpreted as a path to which .inl files will be written
2977 if args.outdir != '':
2978 outputPath = args.outdir
2984 # Generate vulkan headers from vk.xml
2985 currentDir = os.getcwd()
2986 pythonExecutable = sys.executable or "python"
2987 os.chdir(os.path.join(VULKAN_HEADERS_INCLUDE_DIR, "..", "xml"))
3002 "vulkan_xlib_xrandr.h",
3004 for target in vkTargets:
3005 execute([pythonExecutable, "../scripts/genvk.py", "-o", "../include/vulkan", target])
3007 videoDir = "../include/vk_video"
3008 if (not os.path.isdir(videoDir)):
3012 'vulkan_video_codecs_common.h',
3013 'vulkan_video_codec_h264std.h',
3014 'vulkan_video_codec_h264std_decode.h',
3015 'vulkan_video_codec_h264std_encode.h',
3016 'vulkan_video_codec_h265std.h',
3017 'vulkan_video_codec_h265std_decode.h',
3018 'vulkan_video_codec_h265std_encode.h',
3020 for target in videoTargets:
3021 execute([pythonExecutable, "../scripts/genvk.py", "-registry", "video.xml", "-o", videoDir, target])
3023 os.chdir(currentDir)
3025 # Read all .h files and make sure vulkan_core.h is first out of vulkan files
3026 vkTargets.remove("vulkan_core.h")
3028 vkTargets.insert(0, "vulkan_core.h")
3029 vkFilesWithCatalog = [os.path.join("vulkan", f) for f in vkTargets]
3031 for file in vkFilesWithCatalog:
3032 src += preprocessTopInclude(readFile(os.path.join(VULKAN_HEADERS_INCLUDE_DIR,file)), VULKAN_HEADERS_INCLUDE_DIR)
3033 elif args.api=='SC':
3034 # At the moment vulkan-docs does not have vulkan_sc_core.h. We will use a file from external/vulkancts/scripts/src
3035 src = preprocessTopInclude(readFile(os.path.join(os.path.dirname(__file__), "src", "vulkan_sc_core.h" )), VULKAN_HEADERS_INCLUDE_DIR)
3037 src = re.sub('\s*//[^\n]*', '', src)
3038 src = re.sub('\n\n', '\n', src)
3042 platformFuncs = [Function.TYPE_PLATFORM]
3043 instanceFuncs = [Function.TYPE_INSTANCE]
3044 deviceFuncs = [Function.TYPE_DEVICE]
3046 dfd = generateDeviceFeaturesDefs(args.api, src)
3047 writeDeviceFeatures (api, dfd, os.path.join(outputPath, "vkDeviceFeatures.inl"))
3048 writeDeviceFeaturesDefaultDeviceDefs (dfd, os.path.join(outputPath, "vkDeviceFeaturesForDefaultDeviceDefs.inl"))
3049 writeDeviceFeaturesContextDecl (dfd, os.path.join(outputPath, "vkDeviceFeaturesForContextDecl.inl"))
3050 writeDeviceFeaturesContextDefs (dfd, os.path.join(outputPath, "vkDeviceFeaturesForContextDefs.inl"))
3051 writeDeviceFeatureTest (args.api, api, os.path.join(outputPath, "vkDeviceFeatureTest.inl"))
3053 dpd = generateDevicePropertiesDefs(args.api, src)
3054 writeDeviceProperties (api, dpd, os.path.join(outputPath, "vkDeviceProperties.inl"))
3056 writeDevicePropertiesDefaultDeviceDefs (dpd, os.path.join(outputPath, "vkDevicePropertiesForDefaultDeviceDefs.inl"))
3057 writeDevicePropertiesContextDecl (dpd, os.path.join(outputPath, "vkDevicePropertiesForContextDecl.inl"))
3058 writeDevicePropertiesContextDefs (dpd, os.path.join(outputPath, "vkDevicePropertiesForContextDefs.inl"))
3060 writeHandleType (api, os.path.join(outputPath, "vkHandleType.inl"))
3061 writeBasicTypes (args.api, api, os.path.join(outputPath, "vkBasicTypes.inl"))
3062 writeCompositeTypes (api, os.path.join(outputPath, "vkStructTypes.inl"))
3063 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualPlatformInterface.inl"), platformFuncs, False)
3064 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualInstanceInterface.inl"), instanceFuncs, False)
3065 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualDeviceInterface.inl"), deviceFuncs, False)
3066 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcretePlatformInterface.inl"), platformFuncs, True)
3067 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcreteInstanceInterface.inl"), instanceFuncs, True)
3068 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcreteDeviceInterface.inl"), deviceFuncs, True)
3069 writeFunctionPtrTypes (api, os.path.join(outputPath, "vkFunctionPointerTypes.inl"))
3070 writeFunctionPointers (api, os.path.join(outputPath, "vkPlatformFunctionPointers.inl"), platformFuncs)
3071 writeFunctionPointers (api, os.path.join(outputPath, "vkInstanceFunctionPointers.inl"), instanceFuncs)
3072 writeFunctionPointers (api, os.path.join(outputPath, "vkDeviceFunctionPointers.inl"), deviceFuncs)
3073 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitPlatformFunctionPointers.inl"), platformFuncs, lambda f: f.name != "vkGetInstanceProcAddr")
3074 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitInstanceFunctionPointers.inl"), instanceFuncs)
3075 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitDeviceFunctionPointers.inl"), deviceFuncs)
3076 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkPlatformDriverImpl.inl"), platformFuncs, "PlatformDriver")
3077 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkInstanceDriverImpl.inl"), instanceFuncs, "InstanceDriver")
3078 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkDeviceDriverImpl.inl"), deviceFuncs, "DeviceDriver")
3080 writeFuncPtrInterfaceSCImpl (api, os.path.join(outputPath, "vkDeviceDriverSCImpl.inl"), deviceFuncs, "DeviceDriverSC")
3081 writeStrUtilProto (api, os.path.join(outputPath, "vkStrUtil.inl"))
3082 writeStrUtilImpl (api, os.path.join(outputPath, "vkStrUtilImpl.inl"))
3083 writeRefUtilProto (api, os.path.join(outputPath, "vkRefUtil.inl"))
3084 writeRefUtilImpl (api, os.path.join(outputPath, "vkRefUtilImpl.inl"))
3085 writeStructTraitsImpl (api, os.path.join(outputPath, "vkGetStructureTypeImpl.inl"))
3086 writeNullDriverImpl (api, os.path.join(outputPath, "vkNullDriverImpl.inl"))
3087 writeTypeUtil (api, os.path.join(outputPath, "vkTypeUtil.inl"))
3088 writeSupportedExtensions (args.api, api, os.path.join(outputPath, "vkSupportedExtensions.inl"))
3089 writeCoreFunctionalities (api, os.path.join(outputPath, "vkCoreFunctionalities.inl"))
3090 writeExtensionFunctions (api, os.path.join(outputPath, "vkExtensionFunctions.inl"))
3091 writeDeviceFeatures2 (api, os.path.join(outputPath, "vkDeviceFeatures2.inl"))
3092 writeMandatoryFeatures (api, os.path.join(outputPath, "vkMandatoryFeatures.inl"))
3093 writeExtensionList (args.api, api, os.path.join(outputPath, "vkInstanceExtensions.inl"), 'instance')
3094 writeExtensionList (args.api, api, os.path.join(outputPath, "vkDeviceExtensions.inl"), 'device')
3095 writeDriverIds (args.api, os.path.join(outputPath, "vkKnownDriverIds.inl"))
3096 writeObjTypeImpl (api, os.path.join(outputPath, "vkObjTypeImpl.inl"))
3097 # NOTE: when new files are generated then they should also be added to the
3098 # vk-gl-cts\external\vulkancts\framework\vulkan\CMakeLists.txt outputs list