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*"),
113 PLATFORM_TYPE_NAMESPACE = "pt"
115 TYPE_SUBSTITUTIONS = [
117 ("DWORD", "uint32_t"),
118 ("HANDLE*", PLATFORM_TYPE_NAMESPACE + "::" + "Win32Handle*"),
121 EXTENSION_POSTFIXES = ["KHR", "EXT", "NV", "NVX", "KHX", "NN", "MVK", "FUCHSIA", "GGP", "AMD", "QNX"]
122 EXTENSION_POSTFIXES_STANDARD = ["KHR", "EXT"]
124 def prefixName (prefix, name):
125 name = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', name[2:])
126 name = re.sub(r'([a-zA-Z])([0-9])', r'\1_\2', name)
129 name = name.replace("YCB_CR_", "YCBCR_")
130 name = name.replace("WIN_32_", "WIN32_")
131 name = name.replace("8_BIT_", "8BIT_")
132 name = name.replace("16_BIT_", "16BIT_")
133 name = name.replace("INT_64_", "INT64_")
134 name = name.replace("D_3_D_12_", "D3D12_")
135 name = name.replace("IOSSURFACE_", "IOS_SURFACE_")
136 name = name.replace("MAC_OS", "MACOS_")
137 name = name.replace("TEXTURE_LOD", "TEXTURE_LOD_")
138 name = name.replace("VIEWPORT_W", "VIEWPORT_W_")
139 name = name.replace("_IDPROPERTIES", "_ID_PROPERTIES")
140 name = name.replace("PHYSICAL_DEVICE_SHADER_FLOAT_16_INT_8_FEATURES", "PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES")
141 name = name.replace("PHYSICAL_DEVICE_RGBA_10_X_6_FORMATS_FEATURES_EXT", "PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT")
142 name = name.replace("_PCIBUS_", "_PCI_BUS_")
143 name = name.replace("ASTCD", "ASTC_D")
144 name = name.replace("AABBNV", "AABB_NV")
145 name = name.replace("IMAGE_PIPE", "IMAGEPIPE")
146 name = name.replace("SMBUILTINS", "SM_BUILTINS")
147 name = name.replace("ASTCHDRFEATURES", "ASTC_HDR_FEATURES")
148 name = name.replace("UINT_8", "UINT8")
149 name = name.replace("VULKAN_11_FEATURES", "VULKAN_1_1_FEATURES")
150 name = name.replace("VULKAN_11_PROPERTIES", "VULKAN_1_1_PROPERTIES")
151 name = name.replace("VULKAN_12_FEATURES", "VULKAN_1_2_FEATURES")
152 name = name.replace("VULKAN_12_PROPERTIES", "VULKAN_1_2_PROPERTIES")
153 name = name.replace("VULKAN_13_FEATURES", "VULKAN_1_3_FEATURES")
154 name = name.replace("VULKAN_13_PROPERTIES", "VULKAN_1_3_PROPERTIES")
155 name = name.replace("VULKAN_SC_10_FEATURES", "VULKAN_SC_1_0_FEATURES")
156 name = name.replace("VULKAN_SC_10_PROPERTIES", "VULKAN_SC_1_0_PROPERTIES")
157 name = name.replace("INT_8_", "INT8_")
158 name = name.replace("AABBNV", "AABB_NV")
159 name = name.replace("_H_264_", "_H264_")
160 name = name.replace("_H_265_", "_H265_")
161 name = name.replace("RDMAFEATURES", "RDMA_FEATURES")
162 name = name.replace("RGBA_10_X_6", "RGBA10X6")
163 name = name.replace("2_D", "2D_")
164 name = name.replace("3_D", "3D_")
169 def getApiVariantIndexByName(variantName):
175 return apiVariant[variantName]
177 def getApiVariantNameByIndex(variantIndex):
183 return apiVariant[variantIndex]
186 def __init__ (self, versionTuple):
187 self.api = versionTuple[0]
188 self.major = versionTuple[1]
189 self.minor = versionTuple[2]
190 self.patch = versionTuple[3]
194 return "VK%s_API_VERSION_%d_%d" % (getApiVariantNameByIndex(self.api), self.major, self.minor)
195 return '0x%Xu' % (hash(self))
197 def isStandardVersion (self):
204 def getBestRepresentation (self):
205 if self.isStandardVersion():
206 return self.getInHex()
207 return self.getDefineName()
209 def getDefineName (self):
210 return 'VERSION_%d_%d_%d' % (self.major, self.minor, self.patch)
213 return (self.api << 29) | (self.major << 22) | (self.minor << 12) | self.patch
215 def __eq__ (self, other):
216 return self.api == other.api and self.major == other.major and self.minor == other.minor and self.patch == other.patch
219 return self.getBestRepresentation()
225 def __init__ (self, type, name):
231 def getHandleType (self):
232 return prefixName("HANDLE_TYPE_", self.name)
234 def checkAliasValidity (self):
238 return '%s (%s, %s)' % (self.name, self.alias, self.isAlias)
241 def __init__ (self, type, name, value):
249 return '%s = %s (%s)' % (self.name, self.value, self.type)
252 def __init__ (self, name, values):
258 def checkAliasValidity (self):
259 if self.alias != None:
260 if len(self.values) != len(self.alias.values):
261 raise Exception("%s has different number of flags than its alias %s." % (self.name, self.alias.name))
262 for index, value in enumerate(self.values):
263 aliasVal = self.alias.values[index]
264 if value[1] != aliasVal[1] or not (value[0].startswith(aliasVal[0]) or aliasVal[0].startswith(value[0])):
265 raise Exception("Flag %s of %s has different value than %s of %s." % (self.alias.values[index], self.alias.name, value, self.name))
268 return '%s (%s) %s' % (self.name, self.alias, self.values)
271 def __init__ (self, name, values):
277 def checkAliasValidity (self):
278 if self.alias != None:
279 if len(self.values) != len(self.alias.values):
280 raise Exception("%s has different number of flags than its alias %s." % (self.name, self.alias.name))
281 for index, value in enumerate(self.values):
282 aliasVal = self.alias.values[index]
283 if value[1] != aliasVal[1] or not (value[0].startswith(aliasVal[0]) or aliasVal[0].startswith(value[0])):
284 raise Exception("Flag %s of %s has different value than %s of %s." % (self.alias.values[index], self.alias.name, value, self.name))
287 return '%s (%s)' % (self.name, self.alias)
290 def __init__ (self, type, name, arraySizeOrFieldWidth):
291 type = type.replace('*',' *').replace('&',' &')
292 for src, dst in TYPE_SUBSTITUTIONS:
293 type = type.replace(src, dst)
294 self.type = type.split(' ')
295 for platformType, substitute, compat in PLATFORM_TYPES:
296 range = self.contains(self.type, platformType)
298 self.type = self.type[:range[0]]+[PLATFORM_TYPE_NAMESPACE + '::' + substitute[0]] + substitute[1:] + self.type[range[1]:]
301 if len(arraySizeOrFieldWidth) > 0 and arraySizeOrFieldWidth[0] == ':':
303 self.fieldWidth = arraySizeOrFieldWidth
305 self.arraySize = arraySizeOrFieldWidth
308 def contains(self, big, small):
309 for i in range(len(big)-len(small)+1):
310 for j in range(len(small)):
311 if big[i+j] != small[j]:
314 return i, i+len(small)
318 return ' '.join(self.type).replace(' *','*').replace(' &','&')
320 def getAsString (self, separator):
321 return '%s%s%s%s%s' % (self.getType(), separator, self.name, self.arraySize, self.fieldWidth)
323 def getAsStringForArgumentList (self, separator):
324 return '%s%s%s%s' % (self.getType(), separator, self.name, self.arraySize)
327 return '<%s> <%s> <%s>' % (self.type, self.name, self.arraySize)
329 def __eq__ (self, other):
330 if len(self.type) != len(other.type):
332 for index, type in enumerate(self.type):
333 if "*" == type or "&" == type or "const" == type or "volatile" == type:
334 if type != other.type[index]:
336 elif type != other.type[index] and \
337 type not in map(lambda ext: other.type[index] + ext, EXTENSION_POSTFIXES_STANDARD) and \
338 other.type[index] not in map(lambda ext: type + ext, EXTENSION_POSTFIXES_STANDARD):
340 return self.arraySize == other.arraySize
342 def __ne__ (self, other):
343 return not self == other
349 def __init__ (self, typeClass, name, members, apiVersion = None):
350 self.typeClass = typeClass
352 self.members = members
355 self.apiVersion = apiVersion
357 def getClassName (self):
358 names = {CompositeType.CLASS_STRUCT: 'struct', CompositeType.CLASS_UNION: 'union'}
359 return names[self.typeClass]
361 def checkAliasValidity (self):
362 if self.alias != None:
363 if len(self.members) != len(self.alias.members):
364 raise Exception("%s has different number of members than its alias %s." % (self.name, self.alias.name))
365 for index, member in enumerate(self.members ):
367 #if member != self.alias.members[index]:
368 #raise Exception("Member %s of %s is different than core member %s in %s." % (self.alias.members[index], self.alias.name, member, self.name))
369 #raise Exception("Member ",str(self.alias.members[index])," of ", str(self.alias.name)," is different than core member ", str(member)," in ", str(self.name),".")
371 return '%s (%s)' % (self.name, self.alias)
374 TYPE_PLATFORM = 0 # Not bound to anything
375 TYPE_INSTANCE = 1 # Bound to VkInstance
376 TYPE_DEVICE = 2 # Bound to VkDevice
378 def __init__ (self, name, returnType, arguments, apiVersion = None):
380 self.returnType = returnType
381 self.arguments = arguments
384 self.apiVersion = apiVersion
388 if self.name == "vkGetInstanceProcAddr":
389 return Function.TYPE_PLATFORM
390 assert len(self.arguments) > 0
391 firstArgType = self.arguments[0].getType()
392 if firstArgType in ["VkInstance", "VkPhysicalDevice"]:
393 return Function.TYPE_INSTANCE
394 elif firstArgType in ["VkDevice", "VkCommandBuffer", "VkQueue"]:
395 return Function.TYPE_DEVICE
397 return Function.TYPE_PLATFORM
399 def checkAliasValidity (self):
400 if self.alias != None:
401 if len(self.arguments) != len(self.alias.arguments):
402 raise Exception("%s has different number of arguments than its alias %s." % (self.name, self.alias.name))
403 if self.returnType != self.alias.returnType or not (self.returnType.startswith(self.alias.returnType) or self.alias.returnType.startswith(self.returnType)):
404 raise Exception("%s has different return value's type than its alias %s." % (self.name, self.alias.name))
405 for index, argument in enumerate(self.arguments):
406 if argument != self.alias.arguments[index]:
407 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))
410 return '%s (%s)' % (self.name, self.alias)
413 def __init__ (self, name, handles, enums, bitfields, compositeTypes, functions, definitions, additionalDefinitions, typedefs, versionInCore):
415 self.definitions = definitions
416 self.additionalDefs = additionalDefinitions
417 self.handles = handles
419 self.bitfields = bitfields
420 self.compositeTypes = compositeTypes
421 self.functions = functions
422 self.typedefs = typedefs
423 self.versionInCore = versionInCore
426 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)
429 def __init__ (self, versions, definitions, handles, enums, bitfields, bitfields64, compositeTypes, functions, extensions, additionalExtensionData):
430 self.versions = versions
431 self.definitions = definitions
432 self.handles = handles
434 self.bitfields = bitfields
435 self.bitfields64 = bitfields64
436 self.compositeTypes = compositeTypes
437 self.functions = functions # \note contains extension functions as well
438 self.extensions = extensions
439 self.additionalExtensionData = additionalExtensionData # \note contains mandatory features and information about promotion
441 def readFile (filename):
442 with open(filename, 'rt') as f:
445 IDENT_PTRN = r'[a-zA-Z_][a-zA-Z0-9_]*'
446 WIDTH_PTRN = r'[:0-9]*'
447 TYPE_PTRN = r'[a-zA-Z_][a-zA-Z0-9_ \t*&]*'
449 def getInterfaceName (function):
450 assert function.name[:2] == "vk"
451 return function.name[2].lower() + function.name[3:]
453 def getFunctionTypeName (function):
454 assert function.name[:2] == "vk"
455 return function.name[2:] + "Func"
457 def endsWith (str, postfix):
458 return str[-len(postfix):] == postfix
460 def splitNameExtPostfix (name):
461 knownExtPostfixes = EXTENSION_POSTFIXES
462 for postfix in knownExtPostfixes:
463 if endsWith(name, postfix):
464 return (name[:-len(postfix)], postfix)
467 def getBitEnumNameForBitfield (bitfieldName):
468 bitfieldName, postfix = splitNameExtPostfix(bitfieldName)
469 assert bitfieldName[-1] == "s"
470 return bitfieldName[:-1] + "Bits" + postfix
472 def getBitfieldNameForBitEnum (bitEnumName):
473 bitEnumName, postfix = splitNameExtPostfix(bitEnumName)
474 assert bitEnumName[-4:] == "Bits"
475 return bitEnumName[:-4] + "s" + postfix
477 def parsePreprocDefinedValue (src, name):
478 value = parsePreprocDefinedValueOptional(src, name)
480 raise Exception("No such definition: %s" % name)
483 def parsePreprocDefinedValueOptional (src, name):
484 definition = re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src)
485 if definition is None:
487 value = definition.group(1).strip()
488 if value == "UINT32_MAX":
492 def parseEnum (name, src):
493 keyValuePtrn = '(' + IDENT_PTRN + r')\s*=\s*([^\s,\n}]+)\s*[,\n}]'
494 return Enum(name, re.findall(keyValuePtrn, src))
496 # \note Parses raw enums, some are mapped to bitfields later
497 def parseEnums (src):
498 matches = re.findall(r'typedef enum(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
500 for enumname, contents, typename in matches:
501 enums.append(parseEnum(typename, contents))
504 def parseCompositeType (type, name, src):
505 typeNamePtrn = r'(' + TYPE_PTRN + r')(\s+' + IDENT_PTRN + r')((\[[^\]]+\]|\s*:\s*[0-9]+)*)\s*;'
506 matches = re.findall(typeNamePtrn, src)
507 members = [Variable(t.strip(), n.strip(), a.replace(' ', '')) for t, n, a, _ in matches]
508 return CompositeType(type, name, members)
510 def parseCompositeTypes (src):
511 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
512 matches = re.findall(r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
514 for type, structname, contents, typename in matches:
515 types.append(parseCompositeType(typeMap[type], typename, contents))
518 def parseCompositeTypesByVersion (src, versionsData):
520 # find occurence of extension is a place where
521 # we cant assign apiVersion to found structures
522 extPtrn = r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"'
523 versionEnd = re.search(extPtrn, src)
524 versions = [Version((v[2], v[3], v[4], 0)) for v in versionsData]
525 versions.append(None)
527 # construct list of locations where version definitions start, and add the end of the file to it
528 sectionLocations = [versionDef[1] for versionDef in versionsData]
529 sectionLocations.append(versionEnd.start())
530 sectionLocations.append(len(src))
532 # construct function declaration pattern
533 ptrn = r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;'
534 regPtrn = re.compile(ptrn)
536 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
538 # iterate over all versions and find all structure definitions
539 for index, v in enumerate(versions):
540 matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1])
541 for type, structname, contents, typename in matches:
542 compositeType = parseCompositeType(typeMap[type], typename, contents)
543 compositeType.apiVersion = v
544 types.append(compositeType)
547 def parseVersions (src):
548 # returns list of tuples each with four items:
549 # 1. string with version token (without ' 1' at the end)
550 # 2. starting point off version specific definitions in vulkan.h.in
551 # 3. major version number
552 # 4. minor version number
553 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)]
556 def parseHandles (src):
557 matches = re.findall(r'VK_DEFINE(_NON_DISPATCHABLE|)_HANDLE\((' + IDENT_PTRN + r')\)[ \t]*[\n\r]', src)
559 typeMap = {'': Handle.TYPE_DISP, '_NON_DISPATCHABLE': Handle.TYPE_NONDISP}
560 for type, name in matches:
561 handle = Handle(typeMap[type], name)
562 handles.append(handle)
565 def parseArgList (src):
566 typeNamePtrn = r'(' + TYPE_PTRN + r')(\s+' + IDENT_PTRN + r')((\[[^\]]+\])*)\s*'
568 for rawArg in src.split(','):
569 m = re.search(typeNamePtrn, rawArg)
570 args.append(Variable(m.group(1).strip(), m.group(2).strip(), m.group(3)))
573 def removeTypeExtPostfix (name):
574 for extPostfix in EXTENSION_POSTFIXES_STANDARD:
575 if endsWith(name, extPostfix):
576 return name[0:-len(extPostfix)]
579 def populateExtensionAliases(allObjects, extensionObjects):
580 for object in extensionObjects:
581 withoutPostfix = removeTypeExtPostfix(object.name)
582 if withoutPostfix != None and withoutPostfix in allObjects:
583 # max 1 alias is assumed by functions in this file
584 assert allObjects[withoutPostfix].alias == None
585 allObjects[withoutPostfix].alias = object
586 object.isAlias = True
587 for object in extensionObjects:
588 object.checkAliasValidity()
590 def populateAliasesWithTypedefs (objects, src):
592 for object in objects:
593 objectsByName[object.name] = object
594 ptrn = r'\s*typedef\s+' + object.name + r'\s+([^;]+)'
595 stash = re.findall(ptrn, src)
597 objExt = copy.deepcopy(object)
598 objExt.name = stash[0]
599 object.alias = objExt
600 objExt.isAlias = True
601 objects.append(objExt)
603 def removeAliasedValues (enum):
605 for name, value in enum.values:
606 valueByName[name] = value
608 def removeDefExtPostfix (name):
609 for extPostfix in EXTENSION_POSTFIXES:
610 if endsWith(name, "_" + extPostfix):
611 return name[0:-(len(extPostfix)+1)]
615 for name, value in enum.values:
616 withoutPostfix = removeDefExtPostfix(name)
617 if withoutPostfix != None and withoutPostfix in valueByName and valueByName[withoutPostfix] == value:
619 newValues.append((name, value))
620 enum.values = newValues
622 def parseFunctions (src):
623 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
624 matches = re.findall(ptrn, src)
626 for returnType, name, argList in matches:
627 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList)))
630 def parseFunctionsByVersion (src, versions):
631 # construct list of locations where version definitions start, and add the end of the file to it
632 sectionLocations = [versionDef[1] for versionDef in versions]
633 sectionLocations.append(len(src))
635 # construct function declaration pattern
636 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')\s+VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
637 regPtrn = re.compile(ptrn)
640 # iterate over all versions and find all function definitions
641 for index, v in enumerate(versions):
642 matches = regPtrn.findall(src, sectionLocations[index], sectionLocations[index+1])
643 for returnType, name, argList in matches:
644 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList), v[0]))
647 def splitByExtension (src):
648 ptrn = r'#define\s+[A-Z0-9_]+_EXTENSION_NAME\s+"([^"]+)"'
649 # Construct long pattern that will be used to split whole source by extensions
650 match = "#define\s+("
651 for part in re.finditer(ptrn, src):
652 match += part.group(1)+"|"
653 match = match[:-1] + ")\s+1"
654 parts = re.split(match, src)
656 # First part is core, following tuples contain extension name and all its definitions
657 byExtension = [(None, parts[0])]
658 for ndx in range(1, len(parts), 2):
659 byExtension.append((parts[ndx], parts[ndx+1]))
662 def parseDefinitions (extensionName, src):
664 def skipDefinition (extensionName, definition):
665 if extensionName == None:
667 extNameUpper = extensionName.upper()
668 extNameUpper = extNameUpper.replace("VK_KHR_SYNCHRONIZATION2", "VK_KHR_SYNCHRONIZATION_2")
669 extNameUpper = extNameUpper.replace("VK_INTEL_SHADER_INTEGER_FUNCTIONS2", "VK_INTEL_SHADER_INTEGER_FUNCTIONS_2")
670 extNameUpper = extNameUpper.replace("VK_EXT_ROBUSTNESS2", "VK_EXT_ROBUSTNESS_2")
671 extNameUpper = extNameUpper.replace("VK_EXT_FRAGMENT_DENSITY_MAP2", "VK_EXT_FRAGMENT_DENSITY_MAP_2")
672 extNameUpper = extNameUpper.replace("VK_EXT_SHADER_ATOMIC_FLOAT2", "VK_EXT_SHADER_ATOMIC_FLOAT_2")
673 extNameUpper = extNameUpper.replace("VK_AMD_SHADER_CORE_PROPERTIES2", "VK_AMD_SHADER_CORE_PROPERTIES_2")
674 extNameUpper = extNameUpper.replace("VK_EXT_EXTENDED_DYNAMIC_STATE2", "VK_EXT_EXTENDED_DYNAMIC_STATE_2")
676 if definition[0].startswith(extNameUpper) and definition[1].isdigit():
678 if definition[0].startswith(extNameUpper):
680 if definition[0].endswith("_H_"):
684 ptrn = r'#define\s+([^\s]+)\s+([^\r\n]+)'
685 matches = re.findall(ptrn, src)
687 return [Definition(None, match[0], match[1]) for match in matches if not skipDefinition(extensionName, match)]
689 def parseTypedefs (src):
691 ptrn = r'typedef\s+([^\s]+)\s+([^\r\n]+);'
692 matches = re.findall(ptrn, src)
694 return [Definition(None, match[0], match[1]) for match in matches]
696 def parseExtensions (src, versions, allFunctions, allCompositeTypes, allEnums, allBitfields, allHandles, allDefinitions, additionalExtensionData):
698 # note registeredExtensionDict is also executed for vulkan 1.0 source for which extension name is None
699 registeredExtensionDict = {None: None}
700 for extensionName, data in additionalExtensionData:
701 # make sure that this extension was registered
702 if 'register_extension' not in data.keys():
704 # save array containing 'device' or 'instance' string followed by the optional vulkan version in which this extension is core;
705 # note that register_extension section is also required for partialy promoted extensions like VK_EXT_extended_dynamic_state2
706 # but those extensions should not fill 'core' tag
707 registeredExtensionDict[extensionName] = [ data['register_extension']['type'] ]
708 match = re.match("(\d).(\d).(\d).(\d)", data['register_extension']['core'])
710 registeredExtensionDict[extensionName].extend( [ int(match.group(1)), int(match.group(2)), int(match.group(3)), int(match.group(4)) ] )
712 splitSrc = splitByExtension(src)
714 functionsByName = {function.name: function for function in allFunctions}
715 compositeTypesByName = {compType.name: compType for compType in allCompositeTypes}
716 enumsByName = {enum.name: enum for enum in allEnums}
717 bitfieldsByName = {bitfield.name: bitfield for bitfield in allBitfields}
718 handlesByName = {handle.name: handle for handle in allHandles}
719 definitionsByName = {definition.name: definition for definition in allDefinitions}
721 for extensionName, extensionSrc in splitSrc:
722 definitions = [Definition("uint32_t", v.getInHex(), parsePreprocDefinedValueOptional(extensionSrc, v.getInHex())) for v in versions]
723 definitions.extend([Definition(type, name, parsePreprocDefinedValueOptional(extensionSrc, name)) for name, type in DEFINITIONS])
724 definitions = [definition for definition in definitions if definition.value != None]
725 additionalDefinitions = parseDefinitions(extensionName, extensionSrc)
726 handles = parseHandles(extensionSrc)
727 functions = parseFunctions(extensionSrc)
728 compositeTypes = parseCompositeTypes(extensionSrc)
729 rawEnums = parseEnums(extensionSrc)
730 bitfieldNames = parse32bitBitfieldNames(extensionSrc)
731 typedefs = parseTypedefs(extensionSrc)
732 enumBitfieldNames = [getBitEnumNameForBitfield(name) for name in bitfieldNames]
733 enums = [enum for enum in rawEnums if enum.name not in enumBitfieldNames]
735 extCoreVersion = None
736 extData = registeredExtensionDict.get(extensionName, None)
737 extFunctions = [functionsByName[function.name] for function in functions]
738 extCompositeTypes = [compositeTypesByName[compositeType.name] for compositeType in compositeTypes]
739 extEnums = [enumsByName[enum.name] for enum in enums]
740 extBitfields = [bitfieldsByName[bitfieldName] for bitfieldName in bitfieldNames]
741 extHandles = [handlesByName[handle.name] for handle in handles]
742 extDefinitions = [definitionsByName[definition.name] for definition in definitions]
745 populateExtensionAliases(functionsByName, extFunctions)
746 populateExtensionAliases(handlesByName, extHandles)
747 populateExtensionAliases(enumsByName, extEnums)
748 populateExtensionAliases(bitfieldsByName, extBitfields)
749 populateExtensionAliases(compositeTypesByName, extCompositeTypes)
751 extCoreVersion = extData
753 extensions.append(Extension(extensionName, extHandles, extEnums, extBitfields, extCompositeTypes, extFunctions, extDefinitions, additionalDefinitions, typedefs, extCoreVersion))
756 def parse32bitBitfieldNames (src):
757 ptrn = r'typedef\s+VkFlags\s(' + IDENT_PTRN + r')\s*;'
758 matches = re.findall(ptrn, src)
762 def parse64bitBitfieldNames (src):
763 ptrn = r'typedef\s+VkFlags64\s(' + IDENT_PTRN + r')\s*;'
764 matches = re.findall(ptrn, src)
768 def parse64bitBitfieldValues (src, bitfieldNamesList):
771 for bitfieldName in bitfieldNamesList:
772 ptrn = r'static const ' + bitfieldName + r'\s*(' + IDENT_PTRN + r')\s*=\s*([a-zA-Z0-9_]+)\s*;'
773 matches = re.findall(ptrn, src)
774 bitfields64.append(Bitfield(bitfieldName, matches))
779 versionsData = parseVersions(src)
780 versions = [Version((v[2], v[3], v[4], 0)) for v in versionsData]
781 definitions = [Definition("uint32_t", v.getInHex(), parsePreprocDefinedValue(src, v.getInHex())) for v in versions] +\
782 [Definition(type, name, parsePreprocDefinedValue(src, name)) for name, type in DEFINITIONS]
784 handles = parseHandles(src)
785 rawEnums = parseEnums(src)
786 bitfieldNames = parse32bitBitfieldNames(src)
787 bitfieldEnums = set([getBitEnumNameForBitfield(n) for n in bitfieldNames if getBitEnumNameForBitfield(n) in [enum.name for enum in rawEnums]])
788 bitfield64Names = parse64bitBitfieldNames(src)
789 bitfields64 = parse64bitBitfieldValues(src, bitfield64Names)
792 compositeTypes = parseCompositeTypesByVersion(src, versionsData)
793 allFunctions = parseFunctionsByVersion(src, versionsData)
794 additionalExtensionData = {}
796 # read all files from extensions directory
797 for fileName in glob.glob(os.path.join(SCRIPTS_SRC_DIR, "extensions", "*.json")):
798 extensionName = os.path.basename(fileName)[:-5]
799 fileContent = readFile(fileName)
801 additionalExtensionData[extensionName] = json.loads(fileContent)
802 except ValueError as err:
803 print("Error in %s: %s" % (os.path.basename(fileName), str(err)))
805 additionalExtensionData = sorted(additionalExtensionData.items(), key=lambda e: e[0])
807 for enum in rawEnums:
808 if enum.name in bitfieldEnums:
809 bitfields.append(Bitfield(getBitfieldNameForBitEnum(enum.name), enum.values))
813 for bitfieldName in bitfieldNames:
814 if not bitfieldName in [bitfield.name for bitfield in bitfields]:
816 bitfields.append(Bitfield(bitfieldName, []))
818 extensions = parseExtensions(src, versions, allFunctions, compositeTypes, enums, bitfields, handles, definitions, additionalExtensionData)
820 # Populate alias fields
821 populateAliasesWithTypedefs(compositeTypes, src)
822 populateAliasesWithTypedefs(enums, src)
823 populateAliasesWithTypedefs(bitfields, src)
824 populateAliasesWithTypedefs(bitfields64, src)
825 populateAliasesWithTypedefs(handles, src)
828 removeAliasedValues(enum)
830 # Make generator to create Deleter<VkAccelerationStructureNV>
831 for f in allFunctions:
832 if (f.name == 'vkDestroyAccelerationStructureNV'):
833 f.arguments[1].type[0] = 'VkAccelerationStructureNV'
835 # Dealias handles VkAccelerationStructureNV and VkAccelerationStructureKHR
836 for handle in handles:
837 if handle.name == 'VkAccelerationStructureKHR':
839 if handle.name == 'VkAccelerationStructureNV':
840 handle.isAlias = False
844 definitions = definitions,
847 bitfields = bitfields,
848 bitfields64 = bitfields64,
849 compositeTypes = compositeTypes,
850 functions = allFunctions,
851 extensions = extensions,
852 additionalExtensionData = additionalExtensionData)
854 def splitUniqueAndDuplicatedEntries (handles):
855 listOfUniqueHandles = []
856 duplicates = OrderedDict()
857 for handle in handles:
858 if handle.alias != None:
859 duplicates[handle.alias] = handle
860 if not handle.isAlias:
861 listOfUniqueHandles.append(handle)
862 return listOfUniqueHandles, duplicates
864 def writeHandleType (api, filename):
865 uniqeHandles, duplicatedHandles = splitUniqueAndDuplicatedEntries(api.handles)
868 yield "\t%s\t= 0," % uniqeHandles[0].getHandleType()
869 for handle in uniqeHandles[1:]:
870 yield "\t%s," % handle.getHandleType()
871 for duplicate in duplicatedHandles:
872 yield "\t%s\t= %s," % (duplicate.getHandleType(), duplicatedHandles[duplicate].getHandleType())
873 yield "\tHANDLE_TYPE_LAST\t= %s + 1" % (uniqeHandles[-1].getHandleType())
875 def genHandlesBlock ():
876 yield "enum HandleType"
879 for line in indentLines(genHandles()):
885 writeInlFile(filename, INL_HEADER, genHandlesBlock())
887 def getEnumValuePrefix (enum):
888 prefix = enum.name[0]
889 for i in range(1, len(enum.name)):
890 if enum.name[i].isupper() and not enum.name[i-1].isupper():
892 prefix += enum.name[i].upper()
895 def parseInt (value):
896 if value[:2] == "0x":
897 return int(value, 16)
899 return int(value, 10)
901 def areEnumValuesLinear (enum):
904 for name, value in enum.values:
905 if value[:2] != "VK":
906 intValue = parseInt(value)
907 if intValue != curIndex:
908 # enum is linear when all items are in order
909 if intValue != 0x7FFFFFFF:
911 # count number of items with 0x7FFFFFFF value;
912 # enum containing single 0x7FFFFFFF item are also
913 # considered as linear (this is usualy *_MAX_ENUM item)
915 # enums containing more then one 0x7FFFFFFF value
916 # are not considered as linear (vulkan video enums)
922 def genEnumSrc (enum):
923 yield "enum %s" % enum.name
927 if areEnumValuesLinear(enum):
928 hasMaxItem = parseInt(enum.values[-1][1]) == 0x7FFFFFFF
930 values = enum.values[:-1] if hasMaxItem else enum.values
931 lastItem = "\t%s_LAST," % getEnumValuePrefix(enum)
933 # linear values first, followed by *_LAST
934 lines += ["\t%s\t= %s," % v for v in values if v[1][:2] != "VK"]
935 lines.append(lastItem)
937 # equivalence enums and *_MAX_ENUM
938 lines += ["\t%s\t= %s," % v for v in values if v[1][:2] == "VK"]
940 lines.append("\t%s\t= %s," % enum.values[-1])
942 lines += ["\t%s\t= %s," % v for v in enum.values]
944 for line in indentLines(lines):
949 def genBitfieldSrc (bitfield):
950 if len(bitfield.values) > 0:
951 yield "enum %s" % getBitEnumNameForBitfield(bitfield.name)
953 for line in indentLines(["\t%s\t= %s," % v for v in bitfield.values]):
956 yield "typedef uint32_t %s;" % bitfield.name
958 def genBitfield64Src (bitfield64):
959 yield "typedef uint64_t %s;" % bitfield64.name
960 if len(bitfield64.values) > 0:
961 ptrn = "static const " + bitfield64.name + " %s\t= %s;"
962 for line in indentLines([ptrn % v for v in bitfield64.values]):
966 def genCompositeTypeSrc (type):
967 yield "%s %s" % (type.getClassName(), type.name)
969 for line in indentLines(['\t'+m.getAsString('\t')+';' for m in type.members]):
973 def genHandlesSrc (handles):
974 uniqeHandles, duplicatedHandles = splitUniqueAndDuplicatedEntries(handles)
976 def genLines (handles):
977 for handle in uniqeHandles:
978 if handle.type == Handle.TYPE_DISP:
979 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
980 elif handle.type == Handle.TYPE_NONDISP:
981 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
983 for duplicate in duplicatedHandles:
984 if duplicate.type == Handle.TYPE_DISP:
985 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (duplicate.name, duplicatedHandles[duplicate].getHandleType())
986 elif duplicate.type == Handle.TYPE_NONDISP:
987 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (duplicate.name, duplicatedHandles[duplicate].getHandleType())
989 for line in indentLines(genLines(handles)):
992 def stripTrailingComment(str):
993 index = str.find("//")
998 def genDefinitionsSrc (definitions):
999 for line in ["#define %s\t(static_cast<%s>\t(%s))" % (definition.name, definition.type, stripTrailingComment(definition.value)) for definition in definitions]:
1002 def genDefinitionsAliasSrc (definitions):
1003 for line in ["#define %s\t%s" % (definition.name, definitions[definition].name) for definition in definitions]:
1004 if definition.value != definitions[definition].value and definition.value != definitions[definition].name:
1005 raise Exception("Value of %s (%s) is different than core definition value %s (%s)." % (definition.name, definition.value, definitions[definition].name, definitions[definition].value))
1008 def genMaxFrameworkVersion (definitions):
1009 maxApiVersionMajor = 1
1010 maxApiVersionMinor = 0
1011 for definition in definitions:
1012 match = re.match("VK_API_VERSION_(\d+)_(\d+)", definition.name)
1014 apiVersionMajor = int(match.group(1))
1015 apiVersionMinor = int(match.group(2))
1016 if apiVersionMajor > maxApiVersionMajor:
1017 maxApiVersionMajor = apiVersionMajor
1018 maxApiVersionMinor = apiVersionMinor
1019 elif apiVersionMajor == maxApiVersionMajor and apiVersionMinor > maxApiVersionMinor:
1020 maxApiVersionMinor = apiVersionMinor
1021 yield "#define VK_API_MAX_FRAMEWORK_VERSION\tVK_API_VERSION_%d_%d" % (maxApiVersionMajor, maxApiVersionMinor)
1023 def genMaxFrameworkVersionSC (definitions):
1024 maxApiVersionMajor = 1
1025 maxApiVersionMinor = 0
1026 for definition in definitions:
1027 match = re.match("VKSC_API_VERSION_(\d+)_(\d+)", definition.name)
1029 apiVersionMajor = int(match.group(1))
1030 apiVersionMinor = int(match.group(2))
1031 if apiVersionMajor > maxApiVersionMajor:
1032 maxApiVersionMajor = apiVersionMajor
1033 maxApiVersionMinor = apiVersionMinor
1034 elif apiVersionMajor == maxApiVersionMajor and apiVersionMinor > maxApiVersionMinor:
1035 maxApiVersionMinor = apiVersionMinor
1036 yield "#define VKSC_API_MAX_FRAMEWORK_VERSION\tVKSC_API_VERSION_%d_%d" % (maxApiVersionMajor, maxApiVersionMinor)
1038 def writeBasicTypes (apiName, api, filename):
1041 definitionsCore, definitionDuplicates = splitUniqueAndDuplicatedEntries(api.definitions)
1044 for line in indentLines(chain(genDefinitionsSrc(definitionsCore), genMaxFrameworkVersion(definitionsCore), genDefinitionsAliasSrc(definitionDuplicates))):
1047 elif apiName == 'SC':
1048 for line in indentLines(chain(genDefinitionsSrc(definitionsCore), genMaxFrameworkVersion(definitionsCore), genMaxFrameworkVersionSC(definitionsCore), genDefinitionsAliasSrc(definitionDuplicates))):
1052 for line in genHandlesSrc(api.handles):
1056 for enum in api.enums:
1057 if not enum.isAlias:
1058 for line in genEnumSrc(enum):
1061 for enum2 in api.enums:
1062 if enum2.alias == enum:
1063 yield "typedef %s %s;" % (enum2.name, enum.name)
1066 for bitfield in api.bitfields:
1067 if not bitfield.isAlias:
1068 for line in genBitfieldSrc(bitfield):
1071 for bitfield2 in api.bitfields:
1072 if bitfield2.alias == bitfield:
1073 yield "typedef %s %s;" % (bitfield2.name, bitfield.name)
1076 for bitfield in api.bitfields64:
1077 if not bitfield.isAlias:
1078 for line in genBitfield64Src(bitfield):
1081 for bitfield2 in api.bitfields64:
1082 if bitfield2.alias == bitfield:
1083 yield "typedef %s %s;" % (bitfield2.name, bitfield.name)
1086 for line in indentLines(["VK_DEFINE_PLATFORM_TYPE(%s,\t%s)" % (s[0], c) for n, s, c in PLATFORM_TYPES]):
1089 for ext in api.extensions:
1090 if ext.additionalDefs != None:
1091 for definition in ext.additionalDefs:
1092 yield "#define " + definition.name + " " + definition.value
1094 writeInlFile(filename, INL_HEADER, gen())
1096 def writeCompositeTypes (api, filename):
1098 for type in api.compositeTypes:
1099 type.checkAliasValidity()
1101 if not type.isAlias:
1102 for line in genCompositeTypeSrc(type):
1105 for type2 in api.compositeTypes:
1106 if type2.alias == type:
1107 yield "typedef %s %s;" % (type2.name, type.name)
1110 writeInlFile(filename, INL_HEADER, gen())
1112 def argListToStr (args):
1113 return ", ".join(v.getAsStringForArgumentList(' ') for v in args)
1115 def writeInterfaceDecl (api, filename, functionTypes, concrete):
1117 postfix = "" if concrete else " = 0"
1118 for function in api.functions:
1119 if not function.getType() in functionTypes:
1121 if not function.isAlias:
1122 yield "virtual %s\t%s\t(%s) const%s;" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments), postfix)
1124 writeInlFile(filename, INL_HEADER, indentLines(genProtos()))
1126 def writeFunctionPtrTypes (api, filename):
1128 for function in api.functions:
1129 yield "typedef VKAPI_ATTR %s\t(VKAPI_CALL* %s)\t(%s);" % (function.returnType, getFunctionTypeName(function), argListToStr(function.arguments))
1131 writeInlFile(filename, INL_HEADER, indentLines(genTypes()))
1133 def writeFunctionPointers (api, filename, functionTypes):
1134 def FunctionsYielder ():
1135 for function in api.functions:
1136 if function.getType() in functionTypes:
1137 if function.isAlias:
1138 if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice":
1139 yield "%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function))
1141 yield "%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function))
1143 writeInlFile(filename, INL_HEADER, indentLines(FunctionsYielder()))
1145 def writeInitFunctionPointers (api, filename, functionTypes, cond = None):
1146 def makeInitFunctionPointers ():
1147 for function in api.functions:
1148 if function.getType() in functionTypes and (cond == None or cond(function)):
1149 interfaceName = getInterfaceName(function)
1150 if function.isAlias:
1151 if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice":
1152 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
1154 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
1155 if function.alias != None:
1156 yield "if (!m_vk.%s)" % (getInterfaceName(function))
1157 yield " m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.alias.name)
1158 lines = [line.replace(' ', '\t') for line in indentLines(makeInitFunctionPointers())]
1159 writeInlFile(filename, INL_HEADER, lines)
1161 def writeFuncPtrInterfaceImpl (api, filename, functionTypes, className):
1162 def makeFuncPtrInterfaceImpl ():
1163 for function in api.functions:
1164 if function.getType() in functionTypes and not function.isAlias:
1166 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments))
1168 if function.name == "vkEnumerateInstanceVersion":
1169 yield " if (m_vk.enumerateInstanceVersion)"
1170 yield " return m_vk.enumerateInstanceVersion(pApiVersion);"
1172 yield " *pApiVersion = VK_API_VERSION_1_0;"
1173 yield " return VK_SUCCESS;"
1174 elif function.getType() == Function.TYPE_INSTANCE and function.arguments[0].getType() == "VkPhysicalDevice" and function.alias != None:
1175 yield " vk::VkPhysicalDeviceProperties props;"
1176 yield " m_vk.getPhysicalDeviceProperties(physicalDevice, &props);"
1177 yield " if (props.apiVersion >= VK_API_VERSION_1_1)"
1178 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
1180 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function.alias), ", ".join(a.name for a in function.arguments))
1182 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
1185 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceImpl())
1187 def writeFuncPtrInterfaceSCImpl (api, filename, functionTypes, className):
1189 "createGraphicsPipelines" : "\t\treturn createGraphicsPipelinesHandlerNorm(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);",
1190 "createComputePipelines" : "\t\treturn createComputePipelinesHandlerNorm(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);",
1191 "createSampler" : "\t\treturn createSamplerHandlerNorm(device, pCreateInfo, pAllocator, pSampler);",
1192 "createSamplerYcbcrConversion" : "\t\treturn createSamplerYcbcrConversionHandlerNorm(device, pCreateInfo, pAllocator, pYcbcrConversion);",
1193 "createDescriptorSetLayout" : "\t\treturn createDescriptorSetLayoutHandlerNorm(device, pCreateInfo, pAllocator, pSetLayout);",
1194 "createPipelineLayout" : "\t\treturn createPipelineLayoutHandlerNorm(device, pCreateInfo, pAllocator, pPipelineLayout);",
1195 "createRenderPass" : "\t\treturn createRenderPassHandlerNorm(device, pCreateInfo, pAllocator, pRenderPass);",
1196 "createRenderPass2" : "\t\treturn createRenderPass2HandlerNorm(device, pCreateInfo, pAllocator, pRenderPass);",
1197 "createCommandPool" : "\t\treturn createCommandPoolHandlerNorm(device, pCreateInfo, pAllocator, pCommandPool);",
1198 "resetCommandPool" : "\t\treturn resetCommandPoolHandlerNorm(device, commandPool, flags);",
1199 "createFramebuffer" : "\t\treturn createFramebufferHandlerNorm(device, pCreateInfo, pAllocator, pFramebuffer);",
1202 "destroyDevice" : "\t\tdestroyDeviceHandler(device, pAllocator);",
1203 "createDescriptorSetLayout" : "\t\tcreateDescriptorSetLayoutHandlerStat(device, pCreateInfo, pAllocator, pSetLayout);",
1204 "destroyDescriptorSetLayout" : "\t\tdestroyDescriptorSetLayoutHandler(device, descriptorSetLayout, pAllocator);",
1205 "createImageView" : "\t\tcreateImageViewHandler(device, pCreateInfo, pAllocator, pView);",
1206 "destroyImageView" : "\t\tdestroyImageViewHandler(device, imageView, pAllocator);",
1207 "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}",
1208 "destroySemaphore" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(semaphore,semaphoreRequestCount,1);\n\t}",
1209 "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}",
1210 "destroyFence" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(fence,fenceRequestCount,1);\n\t}",
1211 "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}",
1212 "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}",
1213 "destroyBuffer" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(buffer,bufferRequestCount,1);\n\t}",
1214 "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}",
1215 "destroyImage" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(image,imageRequestCount,1);\n\t}",
1216 "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}",
1217 "destroyEvent" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(event,eventRequestCount,1);\n\t}",
1218 "createQueryPool" : "\t\tcreateQueryPoolHandler(device, pCreateInfo, pAllocator, pQueryPool);",
1219 "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}",
1220 "destroyBufferView" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(bufferView,bufferViewRequestCount,1);\n\t}",
1221 "createPipelineLayout" : "\t\tcreatePipelineLayoutHandlerStat(device, pCreateInfo, pAllocator, pPipelineLayout);",
1222 "destroyPipelineLayout" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(pipelineLayout,pipelineLayoutRequestCount,1);\n\t}",
1223 "createRenderPass" : "\t\tcreateRenderPassHandlerStat(device, pCreateInfo, pAllocator, pRenderPass);",
1224 "createRenderPass2" : "\t\tcreateRenderPass2HandlerStat(device, pCreateInfo, pAllocator, pRenderPass);",
1225 "destroyRenderPass" : "\t\tdestroyRenderPassHandler(device, renderPass, pAllocator);",
1226 "createGraphicsPipelines" : "\t\tcreateGraphicsPipelinesHandlerStat(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);",
1227 "createComputePipelines" : "\t\tcreateComputePipelinesHandlerStat(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);",
1228 "destroyPipeline" : "\t\tdestroyPipelineHandler(device, pipeline, pAllocator);",
1229 "createSampler" : "\t\tcreateSamplerHandlerStat(device, pCreateInfo, pAllocator, pSampler);",
1230 "destroySampler" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(sampler,samplerRequestCount,1);\n\t}",
1231 "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}",
1232 "resetDescriptorPool" : "\t\tresetDescriptorPoolHandlerStat(device, descriptorPool, flags);",
1233 "allocateDescriptorSets" : "\t\tallocateDescriptorSetsHandlerStat(device, pAllocateInfo, pDescriptorSets);",
1234 "freeDescriptorSets" : "\t\tfreeDescriptorSetsHandlerStat(device, descriptorPool, descriptorSetCount, pDescriptorSets);",
1235 "createFramebuffer" : "\t\tcreateFramebufferHandlerStat(device, pCreateInfo, pAllocator, pFramebuffer);",
1236 "destroyFramebuffer" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(framebuffer,framebufferRequestCount,1);\n\t}",
1237 "createCommandPool" : "\t\tcreateCommandPoolHandlerStat(device, pCreateInfo, pAllocator, pCommandPool);",
1238 "resetCommandPool" : "\t\tresetCommandPoolHandlerStat(device, commandPool, flags);",
1239 "allocateCommandBuffers" : "\t\tallocateCommandBuffersHandler(device, pAllocateInfo, pCommandBuffers);",
1240 "freeCommandBuffers" : "\t\tfreeCommandBuffersHandler(device, commandPool, commandBufferCount, pCommandBuffers);",
1241 "createSamplerYcbcrConversion" : "\t\tcreateSamplerYcbcrConversionHandlerStat(device, pCreateInfo, pAllocator, pYcbcrConversion);",
1242 "destroySamplerYcbcrConversion" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(ycbcrConversion,samplerYcbcrConversionRequestCount,1);\n\t}",
1243 "getDescriptorSetLayoutSupport" : "\t\tgetDescriptorSetLayoutSupportHandler(device, pCreateInfo, pSupport);",
1244 # "" : "surfaceRequestCount",
1245 # "" : "swapchainRequestCount",
1246 # "" : "displayModeRequestCount"
1247 "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}",
1248 "getBufferMemoryRequirements" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->size = 1048576U;\n\t\tpMemoryRequirements->alignment = 1U;\n\t\tpMemoryRequirements->memoryTypeBits = ~0U;\n\t}",
1249 "getImageMemoryRequirements" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->size = 1048576U;\n\t\tpMemoryRequirements->alignment = 1U;\n\t\tpMemoryRequirements->memoryTypeBits = ~0U;\n\t}",
1250 "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}",
1251 "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}",
1252 "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}",
1253 "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}",
1254 "destroyPipelineCache" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(pipelineCache,pipelineCacheRequestCount,1);\n\t}",
1255 "cmdUpdateBuffer" : "\t\tincreaseCommandBufferSize(commandBuffer, dataSize);",
1256 "getDeviceQueue" : "\t\tm_vk.getDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);",
1260 "VkResult" : "return VK_SUCCESS;",
1261 "VkDeviceAddress" : "return 0u;",
1262 "uint64_t" : "return 0u;",
1264 def makeFuncPtrInterfaceStatisticsImpl ():
1265 for function in api.functions:
1266 if function.getType() in functionTypes and not function.isAlias:
1268 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments))
1270 if ( getInterfaceName(function) in normFuncs ) or ( getInterfaceName(function) in statFuncs ):
1271 yield "\tstd::lock_guard<std::mutex> lock(functionMutex);"
1272 if getInterfaceName(function) != "getDeviceProcAddr" :
1273 yield "\tif (m_normalMode)"
1274 if getInterfaceName(function) in normFuncs :
1275 yield "%s" % ( normFuncs[getInterfaceName(function)] )
1277 yield "\t\t%sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
1278 if getInterfaceName(function) in statFuncs :
1280 yield "%s" % ( statFuncs[getInterfaceName(function)] )
1281 elif getInterfaceName(function)[:3] == "cmd" :
1283 yield "\t\tincreaseCommandBufferSize(commandBuffer, 0u);"
1284 if function.returnType in statReturns:
1285 yield "\t%s" % ( statReturns[function.returnType] )
1288 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceStatisticsImpl())
1290 def writeStrUtilProto (api, filename):
1291 def makeStrUtilProto ():
1292 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]):
1295 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]):
1298 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]):
1301 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']):
1304 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]):
1307 writeInlFile(filename, INL_HEADER, makeStrUtilProto())
1309 def writeStrUtilImpl (api, filename):
1310 def makeStrUtilImpl ():
1311 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]):
1315 yield "namespace %s" % PLATFORM_TYPE_NAMESPACE
1318 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):
1323 for enum in api.enums:
1327 yield "const char* get%sName (%s value)" % (enum.name[2:], enum.name)
1329 yield "\tswitch (value)"
1332 lastValue = 0x7FFFFFFF
1333 for n, v in enum.values:
1334 if (v[:2] != "VK") and (v != lastValue):
1335 enumValues.append(f"\t\tcase {n}:\treturn \"{n}\";")
1337 enumValues.append("\t\tdefault:\treturn DE_NULL;")
1338 for line in indentLines(enumValues):
1343 for bitfield in api.bitfields:
1344 if bitfield.isAlias:
1345 if bitfield.name != 'VkBuildAccelerationStructureFlagsNV':
1348 yield "tcu::Format::Bitfield<32> get%sStr (%s value)" % (bitfield.name[2:], bitfield.name)
1351 if len(bitfield.values) > 0:
1352 yield "\tstatic const tcu::Format::BitDesc s_desc[] ="
1354 for line in indentLines(["\t\ttcu::Format::BitDesc(%s,\t\"%s\")," % (n, n) for n, v in bitfield.values]):
1357 yield "\treturn tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));"
1359 yield "\treturn tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL);"
1362 bitfieldTypeNames = set([bitfield.name for bitfield in api.bitfields])
1364 for type in api.compositeTypes:
1365 if not type.isAlias:
1367 yield "std::ostream& operator<< (std::ostream& s, const %s& value)" % type.name
1369 yield "\ts << \"%s = {\\n\";" % type.name
1370 for member in type.members:
1371 memberName = member.name
1374 if member.getType() in bitfieldTypeNames:
1375 valFmt = "get%sStr(value.%s)" % (member.getType()[2:], member.name)
1376 elif member.getType() == "const char*" or member.getType() == "char*":
1377 valFmt = "getCharPtrStr(value.%s)" % member.name
1378 elif member.getType() == PLATFORM_TYPE_NAMESPACE + "::Win32LPCWSTR":
1379 valFmt = "getWStr(value.%s)" % member.name
1380 elif member.arraySize != '':
1381 singleDimensional = not '][' in member.arraySize
1382 if member.name in ["extensionName", "deviceName", "layerName", "description"]:
1383 valFmt = "(const char*)value.%s" % member.name
1384 elif singleDimensional and (member.getType() == 'char' or member.getType() == 'uint8_t'):
1385 newLine = "'\\n' << "
1386 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)
1388 if member.name == "memoryTypes" or member.name == "memoryHeaps":
1389 endIter = "DE_ARRAY_BEGIN(value.%s) + value.%sCount" % (member.name, member.name[:-1])
1391 endIter = "DE_ARRAY_END(value.%s)" % member.name
1392 newLine = "'\\n' << "
1393 valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), %s)" % (member.name, endIter)
1394 memberName = member.name
1396 valFmt = "value.%s" % member.name
1397 yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';"
1401 writeInlFile(filename, INL_HEADER, makeStrUtilImpl())
1404 def writeObjTypeImpl (api, filename):
1405 def makeObjTypeImpl ():
1407 yield "namespace vk"
1410 yield "template<typename T> VkObjectType getObjectType (void);"
1412 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]):
1417 writeInlFile(filename, INL_HEADER, makeObjTypeImpl())
1419 class ConstructorFunction:
1420 def __init__ (self, type, name, objectType, ifaceArgs, arguments):
1423 self.objectType = objectType
1424 self.ifaceArgs = ifaceArgs
1425 self.arguments = arguments
1427 def getConstructorFunctions (api):
1430 Function.TYPE_PLATFORM: [Variable("const PlatformInterface&", "vk", "")],
1431 Function.TYPE_INSTANCE: [Variable("const InstanceInterface&", "vk", "")],
1432 Function.TYPE_DEVICE: [Variable("const DeviceInterface&", "vk", "")]
1434 for function in api.functions:
1435 if function.isAlias:
1437 if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "createInfoCount" in [a.name for a in function.arguments]:
1438 if function.name == "vkCreateDisplayModeKHR":
1439 continue # No way to delete display modes (bug?)
1441 # \todo [pyry] Rather hacky
1442 ifaceArgs = ifacesDict[function.getType()]
1443 if function.name == "vkCreateDevice":
1444 ifaceArgs = [Variable("const PlatformInterface&", "vkp", ""), Variable("VkInstance", "instance", "")] + ifaceArgs
1446 assert (function.arguments[-2].type == ["const", "VkAllocationCallbacks", "*"])
1448 objectType = function.arguments[-1].type[0] #not getType() but type[0] on purpose
1449 arguments = function.arguments[:-1]
1450 funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function), objectType, ifaceArgs, arguments))
1453 def addVersionDefines(versionSpectrum):
1454 output = ["#define " + ver.getDefineName() + " " + ver.getInHex() for ver in versionSpectrum if not ver.isStandardVersion()]
1457 def removeVersionDefines(versionSpectrum):
1458 output = ["#undef " + ver.getDefineName() for ver in versionSpectrum if not ver.isStandardVersion()]
1461 def writeRefUtilProto (api, filename):
1462 functions = getConstructorFunctions(api)
1464 def makeRefUtilProto ():
1466 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]):
1469 writeInlFile(filename, INL_HEADER, makeRefUtilProto())
1471 def writeRefUtilImpl (api, filename):
1472 functions = getConstructorFunctions(api)
1474 def makeRefUtilImpl ():
1475 yield "namespace refdetails"
1479 for function in api.functions:
1480 if function.getType() == Function.TYPE_DEVICE \
1481 and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \
1482 and not function.name == "vkDestroyDevice" \
1483 and not function.isAlias:
1484 objectType = function.arguments[-2].getType()
1486 yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType)
1488 yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function))
1492 yield "} // refdetails"
1496 Function.TYPE_PLATFORM: "object",
1497 Function.TYPE_INSTANCE: "instance",
1498 Function.TYPE_DEVICE: "device"
1501 for function in functions:
1502 deleterArgsString = ''
1503 if function.name == "createDevice":
1504 # createDevice requires two additional parameters to setup VkDevice deleter
1505 deleterArgsString = "vkp, instance, object, " + function.arguments[-1].name
1507 deleterArgsString = "vk, %s, %s" % (dtorDict[function.type], function.arguments[-1].name)
1509 yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr(function.ifaceArgs + function.arguments))
1511 yield "\t%s object = 0;" % function.objectType
1512 yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"]))
1513 yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, deleterArgsString)
1517 writeInlFile(filename, INL_HEADER, makeRefUtilImpl())
1519 def writeStructTraitsImpl (api, filename):
1521 for type in api.compositeTypes:
1522 if type.getClassName() == "struct" and type.members[0].name == "sType" and not type.isAlias and type.name != "VkBaseOutStructure" and type.name != "VkBaseInStructure":
1523 yield "template<> VkStructureType getStructureType<%s> (void)" % type.name
1525 yield "\treturn %s;" % prefixName("VK_STRUCTURE_TYPE_", type.name)
1529 writeInlFile(filename, INL_HEADER, gen())
1531 def writeNullDriverImpl (api, filename):
1532 def genNullDriverImpl ():
1533 specialFuncNames = [
1534 "vkCreateGraphicsPipelines",
1535 "vkCreateComputePipelines",
1536 "vkCreateRayTracingPipelinesNV",
1537 "vkCreateRayTracingPipelinesKHR",
1538 "vkGetInstanceProcAddr",
1539 "vkGetDeviceProcAddr",
1540 "vkEnumeratePhysicalDevices",
1541 "vkEnumerateInstanceExtensionProperties",
1542 "vkEnumerateDeviceExtensionProperties",
1543 "vkGetPhysicalDeviceFeatures",
1544 "vkGetPhysicalDeviceFeatures2KHR",
1545 "vkGetPhysicalDeviceProperties",
1546 "vkGetPhysicalDeviceProperties2KHR",
1547 "vkGetPhysicalDeviceQueueFamilyProperties",
1548 "vkGetPhysicalDeviceMemoryProperties",
1549 "vkGetPhysicalDeviceFormatProperties",
1550 "vkGetPhysicalDeviceImageFormatProperties",
1552 "vkGetBufferMemoryRequirements",
1553 "vkGetBufferMemoryRequirements2KHR",
1554 "vkGetImageMemoryRequirements",
1555 "vkGetImageMemoryRequirements2KHR",
1559 "vkAllocateDescriptorSets",
1560 "vkFreeDescriptorSets",
1561 "vkResetDescriptorPool",
1562 "vkAllocateCommandBuffers",
1563 "vkFreeCommandBuffers",
1564 "vkCreateDisplayModeKHR",
1565 "vkCreateSharedSwapchainsKHR",
1566 "vkGetPhysicalDeviceExternalBufferPropertiesKHR",
1567 "vkGetPhysicalDeviceImageFormatProperties2KHR",
1568 "vkGetMemoryAndroidHardwareBufferANDROID",
1571 coreFunctions = [f for f in api.functions if not f.isAlias]
1572 specialFuncs = [f for f in coreFunctions if f.name in specialFuncNames]
1573 createFuncs = [f for f in coreFunctions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs]
1574 destroyFuncs = [f for f in coreFunctions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs]
1575 dummyFuncs = [f for f in coreFunctions if f not in specialFuncs + createFuncs + destroyFuncs]
1577 def getHandle (name):
1578 for handle in api.handles:
1579 if handle.name == name[0]:
1581 raise Exception("No such handle: %s" % name)
1583 for function in createFuncs:
1584 objectType = function.arguments[-1].type[:-1]
1585 argsStr = ", ".join([a.name for a in function.arguments[:-1]])
1587 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1589 yield "\tDE_UNREF(%s);" % function.arguments[-2].name
1591 if getHandle(objectType).type == Handle.TYPE_NONDISP:
1592 yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[0][2:], objectType[0], argsStr)
1594 yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[0][2:], objectType[0], argsStr)
1598 for function in destroyFuncs:
1599 objectArg = function.arguments[-2]
1601 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1603 for arg in function.arguments[:-2]:
1604 yield "\tDE_UNREF(%s);" % arg.name
1606 if getHandle(objectArg.type).type == Handle.TYPE_NONDISP:
1607 yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.getType()[2:], objectArg.getType(), objectArg.name, function.arguments[-1].name)
1609 yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.getType()[2:], objectArg.getType(), objectArg.name, function.arguments[-1].name)
1614 for function in dummyFuncs:
1615 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
1617 for arg in function.arguments:
1618 yield "\tDE_UNREF(%s);" % arg.name
1619 if function.returnType != "void":
1620 yield "\treturn VK_SUCCESS;"
1624 def genFuncEntryTable (type, name):
1625 funcs = [f for f in api.functions if f.getType() == type]
1627 for f in api.functions:
1629 refFuncs[f.alias] = f
1631 yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name
1633 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]):
1639 for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"):
1642 for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"):
1645 for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"):
1648 writeInlFile(filename, INL_HEADER, genNullDriverImpl())
1650 def writeTypeUtil (api, filename):
1651 # Structs filled by API queries are not often used in test code
1652 QUERY_RESULT_TYPES = set([
1653 "VkPhysicalDeviceFeatures",
1654 "VkPhysicalDeviceLimits",
1655 "VkFormatProperties",
1656 "VkImageFormatProperties",
1657 "VkPhysicalDeviceSparseProperties",
1658 "VkQueueFamilyProperties",
1661 "StdVideoH264SpsVuiFlags",
1662 "StdVideoH264SpsFlags",
1663 "StdVideoH264PpsFlags",
1664 "StdVideoDecodeH264PictureInfoFlags",
1665 "StdVideoDecodeH264ReferenceInfoFlags",
1666 "StdVideoDecodeH264MvcElementFlags",
1667 "StdVideoEncodeH264SliceHeaderFlags",
1668 "StdVideoEncodeH264PictureInfoFlags",
1669 "StdVideoEncodeH264RefMgmtFlags",
1670 "StdVideoEncodeH264ReferenceInfoFlags",
1671 "StdVideoH265HrdFlags",
1672 "StdVideoH265VpsFlags",
1673 "StdVideoH265SpsVuiFlags",
1674 "StdVideoH265SpsFlags",
1675 "StdVideoH265PpsFlags",
1676 "StdVideoDecodeH265PictureInfoFlags",
1677 "StdVideoDecodeH265ReferenceInfoFlags",
1678 "StdVideoEncodeH265PictureInfoFlags",
1679 "StdVideoEncodeH265SliceHeaderFlags",
1680 "StdVideoEncodeH265ReferenceModificationFlags",
1681 "StdVideoEncodeH265ReferenceInfoFlags",
1682 "StdVideoEncodeH265SliceSegmentHeaderFlags",
1684 COMPOSITE_TYPES = set([t.name for t in api.compositeTypes if not t.isAlias])
1686 def isSimpleStruct (type):
1687 def hasArrayMember (type):
1688 for member in type.members:
1689 if member.arraySize != '':
1693 def hasCompositeMember (type):
1694 for member in type.members:
1695 if member.getType() in COMPOSITE_TYPES:
1699 return type.typeClass == CompositeType.CLASS_STRUCT and \
1700 type.members[0].getType() != "VkStructureType" and \
1701 not type.name in QUERY_RESULT_TYPES and \
1702 not hasArrayMember(type) and \
1703 not hasCompositeMember(type)
1706 for type in api.compositeTypes:
1707 if not isSimpleStruct(type) or type.isAlias:
1710 name = type.name[2:] if type.name[:2].lower() == "vk" else type.name
1713 yield "inline %s make%s (%s)" % (type.name, name, argListToStr(type.members))
1715 yield "\t%s res;" % type.name
1716 for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]):
1718 yield "\treturn res;"
1721 writeInlFile(filename, INL_HEADER, gen())
1723 def writeDriverIds(apiName, filename):
1725 driverIdsString = []
1726 driverIdsString.append("static const struct\n"
1728 "\tstd::string driver;\n"
1730 "} driverIds [] =\n"
1733 vulkanHeaderFile = { "" : os.path.join(VULKAN_HEADERS_INCLUDE_DIR, "vulkan", "vulkan_core.h"),
1734 "SC" : os.path.join(SCRIPTS_SRC_DIR, "vulkan_sc_core.h") }
1735 vulkanCore = readFile(vulkanHeaderFile[apiName])
1737 items = re.search(r'(?:typedef\s+enum\s+VkDriverId\s*{)((.*\n)*)(?:}\s*VkDriverId\s*;)', vulkanCore).group(1).split(',')
1738 driverItems = dict()
1741 splitted = item.split('=')
1742 key = splitted[0].strip()
1743 value_str = splitted[1].strip()
1744 try: # is this previously defined value?
1745 value = driverItems[value_str]
1750 value_str = "\t// " + value_str
1751 driverItems[key] = value
1752 if not item == items[-1]:
1753 driverIdsString.append("\t{\"" + key + "\"" + ", " + value + "}," + value_str)
1755 driverIdsString.append("\t{\"" + key + "\"" + ", " + value + "}" + value_str)
1756 driverItems[key] = value
1758 driverIdsString.append("};")
1760 writeInlFile(filename, INL_HEADER, driverIdsString)
1763 def writeSupportedExtensions(apiName, api, filename):
1765 def writeExtensionsForVersions(map):
1768 result.append(" if (coreVersion >= " + str(version) + ")")
1770 for extension in map[version]:
1771 result.append(' dst.push_back("' + extension.name + '");')
1775 result.append(" DE_UNREF(coreVersion);")
1783 for ext in api.extensions:
1784 if ext.versionInCore != None:
1785 currVersion = Version(ext.versionInCore[1:])
1786 # VulkanSC is based on Vulkan 1.2. Any Vulkan version greater than 1.2 should be excluded
1787 if apiName=='SC' and currVersion.api==0 and currVersion.major==1 and currVersion.minor>2:
1789 if ext.versionInCore[0] == 'instance':
1790 list = instanceMap.get(Version(ext.versionInCore[1:]))
1791 instanceMap[Version(ext.versionInCore[1:])] = list + [ext] if list else [ext]
1793 list = deviceMap.get(Version(ext.versionInCore[1:]))
1794 deviceMap[Version(ext.versionInCore[1:])] = list + [ext] if list else [ext]
1795 versionSet.add(Version(ext.versionInCore[1:]))
1797 # add list of extensions missing in Vulkan SC specification
1799 for extensionName, data in api.additionalExtensionData:
1800 # make sure that this extension was registered
1801 if 'register_extension' not in data.keys():
1803 # save array containing 'device' or 'instance' string followed by the optional vulkan version in which this extension is core;
1804 # note that register_extension section is also required for partialy promoted extensions like VK_EXT_extended_dynamic_state2
1805 # but those extensions should not fill 'core' tag
1806 match = re.match("(\d).(\d).(\d).(\d)", data['register_extension']['core'])
1808 currVersion = Version([int(match.group(1)), int(match.group(2)), int(match.group(3)), int(match.group(4))])
1809 ext = Extension(extensionName, 0, 0, 0, 0, 0, 0, 0, 0, 0)
1810 if currVersion.api==0 and currVersion.major==1 and currVersion.minor>2:
1812 if data['register_extension']['type'] == 'instance':
1813 list = instanceMap.get(currVersion)
1814 instanceMap[currVersion] = list + [ext] if list else [ext]
1816 list = deviceMap.get(currVersion)
1817 deviceMap[currVersion] = list + [ext] if list else [ext]
1818 versionSet.add(currVersion)
1820 lines = addVersionDefines(versionSet) + [
1822 "void getCoreDeviceExtensionsImpl (uint32_t coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(deviceMap) != 0 or apiName == 'SC' else ""),
1823 "{"] + writeExtensionsForVersions(deviceMap) + [
1826 "void getCoreInstanceExtensionsImpl (uint32_t coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(instanceMap) != 0 or apiName == 'SC' else ""),
1827 "{"] + writeExtensionsForVersions(instanceMap) + [
1829 ""] + removeVersionDefines(versionSet)
1830 writeInlFile(filename, INL_HEADER, lines)
1833 def writeExtensionFunctions (api, filename):
1835 def isInstanceExtension (ext):
1836 if ext.name and ext.functions:
1837 if ext.functions[0].getType() == Function.TYPE_INSTANCE:
1842 def isDeviceExtension (ext):
1843 if ext.name and ext.functions:
1844 if ext.functions[0].getType() == Function.TYPE_DEVICE:
1849 def writeExtensionNameArrays ():
1850 instanceExtensionNames = []
1851 deviceExtensionNames = []
1852 for ext in api.extensions:
1853 if ext.name and isInstanceExtension(ext):
1854 instanceExtensionNames += [ext.name]
1855 elif ext.name and isDeviceExtension(ext):
1856 deviceExtensionNames += [ext.name]
1857 yield '::std::string instanceExtensionNames[] =\n{'
1858 for instanceExtName in instanceExtensionNames:
1859 if (instanceExtName == instanceExtensionNames[len(instanceExtensionNames) - 1]):
1860 yield '\t"%s"' % instanceExtName
1862 yield '\t"%s",' % instanceExtName
1864 yield '::std::string deviceExtensionNames[] =\n{'
1865 for deviceExtName in deviceExtensionNames:
1866 if (deviceExtName == deviceExtensionNames[len(deviceExtensionNames) - 1]):
1867 yield '\t"%s"' % deviceExtName
1869 yield '\t"%s",' % deviceExtName
1872 def writeExtensionFunctions (functionType):
1874 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
1875 if functionType == Function.TYPE_INSTANCE:
1876 yield 'void getInstanceExtensionFunctions (uint32_t apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{'
1877 dg_list = ["vkGetPhysicalDevicePresentRectanglesKHR"]
1878 elif functionType == Function.TYPE_DEVICE:
1879 yield 'void getDeviceExtensionFunctions (uint32_t apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{'
1880 dg_list = ["vkGetDeviceGroupPresentCapabilitiesKHR", "vkGetDeviceGroupSurfacePresentModesKHR", "vkAcquireNextImage2KHR"]
1881 for ext in api.extensions:
1884 for func in ext.functions:
1885 if func.getType() == functionType:
1886 # only add functions with same vendor as extension
1887 # this is a workaroudn for entrypoints requiring more
1888 # than one excetions and lack of the dependency in vulkan_core.h
1889 vendor = ext.name.split('_')[1]
1890 if func.name.endswith(vendor):
1891 funcNames.append(func.name)
1893 yield '\tif (extName == "%s")' % ext.name
1895 for funcName in funcNames:
1896 if funcName in dg_list:
1897 yield '\t\tif(apiVersion >= VK_API_VERSION_1_1) functions.push_back("%s");' % funcName
1899 yield '\t\tfunctions.push_back("%s");' % funcName
1900 if ext.name == "VK_KHR_device_group":
1901 for dg_func in dg_list:
1902 yield '\t\tif(apiVersion < VK_API_VERSION_1_1) functions.push_back("%s");' % dg_func
1905 isFirstWrite = False
1906 if not isFirstWrite:
1907 yield '\tDE_FATAL("Extension name not found");'
1911 for line in writeExtensionFunctions(Function.TYPE_INSTANCE):
1914 for line in writeExtensionFunctions(Function.TYPE_DEVICE):
1917 for line in writeExtensionNameArrays():
1920 writeInlFile(filename, INL_HEADER, lines)
1922 def writeCoreFunctionalities(api, filename):
1923 functionOriginValues = ["FUNCTIONORIGIN_PLATFORM", "FUNCTIONORIGIN_INSTANCE", "FUNCTIONORIGIN_DEVICE"]
1924 lines = addVersionDefines(api.versions) + [
1926 'enum FunctionOrigin', '{'] + [line for line in indentLines([
1927 '\t' + functionOriginValues[0] + '\t= 0,',
1928 '\t' + functionOriginValues[1] + ',',
1929 '\t' + functionOriginValues[2]])] + [
1932 "typedef ::std::pair<const char*, FunctionOrigin> FunctionInfo;",
1933 "typedef ::std::vector<FunctionInfo> FunctionInfosList;",
1934 "typedef ::std::map<uint32_t, FunctionInfosList> ApisMap;",
1936 "void initApisMap (ApisMap& apis)",
1938 " apis.clear();"] + [
1939 " apis.insert(::std::pair<uint32_t, FunctionInfosList>(" + str(v) + ", FunctionInfosList()));" for v in api.versions] + [
1943 for index, v in enumerate(api.versions):
1945 apiVersions.append("VK_VERSION_{0}_{1}".format(v.major, v.minor))
1946 # iterate over all functions that are core in latest vulkan version
1947 # note that first item in api.extension array are actually all definitions that are in vulkan.h.in before section with extensions
1948 for fun in api.extensions[0].functions:
1949 if fun.apiVersion in apiVersions:
1950 funcs.append(' apis[' + str(v) + '].push_back(FunctionInfo("' + fun.name + '",\t' + functionOriginValues[fun.getType()] + '));')
1951 lines = lines + [line for line in indentLines(funcs)] + [""]
1953 lines = lines + ["}", ""] + removeVersionDefines(api.versions)
1954 writeInlFile(filename, INL_HEADER, lines)
1956 def camelToSnake(name):
1957 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
1958 return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()
1960 def writeDeviceFeatures2(api, filename):
1961 def structInAPI(name):
1962 for c in api.compositeTypes:
1967 # list of structures that should be tested with getPhysicalDeviceFeatures2
1968 # this is not posible to determine from vulkan_core.h, if new feature structures
1969 # are added they should be manualy added to this list
1970 testedStructures = [
1971 'VkPhysicalDevice4444FormatsFeaturesEXT',
1972 'VkPhysicalDevice8BitStorageFeatures',
1973 'VkPhysicalDevice16BitStorageFeatures',
1974 'VkPhysicalDeviceAccelerationStructureFeaturesKHR',
1975 'VkPhysicalDeviceASTCDecodeFeaturesEXT',
1976 'VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT',
1977 'VkPhysicalDeviceBufferDeviceAddressFeaturesEXT',
1978 'VkPhysicalDeviceBufferDeviceAddressFeatures',
1979 'VkPhysicalDeviceConditionalRenderingFeaturesEXT',
1980 'VkPhysicalDeviceCustomBorderColorFeaturesEXT',
1981 'VkPhysicalDeviceColorWriteEnableFeaturesEXT',
1982 'VkPhysicalDeviceDescriptorIndexingFeatures',
1983 'VkPhysicalDeviceDepthClipEnableFeaturesEXT',
1984 'VkPhysicalDeviceDynamicRenderingFeatures',
1985 'VkPhysicalDeviceExtendedDynamicStateFeaturesEXT',
1986 'VkPhysicalDeviceExtendedDynamicState2FeaturesEXT',
1987 'VkPhysicalDeviceFragmentDensityMapFeaturesEXT',
1988 'VkPhysicalDeviceFragmentDensityMap2FeaturesEXT',
1989 'VkPhysicalDeviceFragmentShadingRateFeaturesKHR',
1990 'VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR',
1991 'VkPhysicalDeviceInlineUniformBlockFeatures',
1992 'VkPhysicalDeviceIndexTypeUint8FeaturesEXT',
1993 'VkPhysicalDeviceImagelessFramebufferFeatures',
1994 'VkPhysicalDeviceImageRobustnessFeatures',
1995 'VkPhysicalDeviceHostQueryResetFeatures',
1996 'VkPhysicalDeviceLineRasterizationFeaturesEXT',
1997 'VkPhysicalDeviceMaintenance4Features',
1998 'VkPhysicalDeviceMultiviewFeatures',
1999 'VkPhysicalDeviceMultiDrawFeaturesEXT',
2000 'VkPhysicalDeviceMemoryPriorityFeaturesEXT',
2001 'VkPhysicalDeviceDeviceMemoryReportFeaturesEXT',
2002 'VkPhysicalDevicePerformanceQueryFeaturesKHR',
2003 'VkPhysicalDevicePipelineCreationCacheControlFeatures',
2004 'VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR',
2005 'VkPhysicalDevicePresentIdFeaturesKHR',
2006 'VkPhysicalDevicePresentWaitFeaturesKHR',
2007 'VkPhysicalDeviceProtectedMemoryFeatures',
2008 'VkPhysicalDeviceProvokingVertexFeaturesEXT',
2009 'VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT',
2010 'VkPhysicalDevicePrivateDataFeatures',
2011 'VkPhysicalDeviceRayTracingPipelineFeaturesKHR',
2012 'VkPhysicalDeviceRayQueryFeaturesKHR',
2013 'VkPhysicalDeviceRobustness2FeaturesEXT',
2014 'VkPhysicalDeviceSamplerYcbcrConversionFeatures',
2015 'VkPhysicalDeviceScalarBlockLayoutFeatures',
2016 'VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures',
2017 'VkPhysicalDeviceShaderAtomicInt64Features',
2018 'VkPhysicalDeviceShaderAtomicFloatFeaturesEXT',
2019 'VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT',
2020 'VkPhysicalDeviceShaderFloat16Int8Features',
2021 'VkPhysicalDeviceShaderClockFeaturesKHR',
2022 'VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures',
2023 'VkPhysicalDeviceShaderDrawParametersFeatures',
2024 'VkPhysicalDeviceShaderIntegerDotProductFeatures',
2025 'VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures',
2026 'VkPhysicalDeviceShaderTerminateInvocationFeatures',
2027 'VkPhysicalDeviceSubgroupSizeControlFeatures',
2028 'VkPhysicalDeviceSynchronization2Features',
2029 'VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT',
2030 'VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT',
2031 'VkPhysicalDeviceTextureCompressionASTCHDRFeatures',
2032 'VkPhysicalDeviceTimelineSemaphoreFeatures',
2033 'VkPhysicalDeviceTransformFeedbackFeaturesEXT',
2034 'VkPhysicalDeviceUniformBufferStandardLayoutFeatures',
2035 'VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR',
2036 'VkPhysicalDeviceVariablePointersFeatures',
2037 'VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT',
2038 'VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT',
2039 'VkPhysicalDeviceVulkanMemoryModelFeaturesKHR',
2040 'VkPhysicalDeviceYcbcrImageArraysFeaturesEXT',
2041 'VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT',
2042 'VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures',
2045 # helper class used to encapsulate all data needed during generation
2046 class StructureDetail:
2047 def __init__ (self, name):
2048 nameResult = re.search('(.*)Features(.*)', name[len('VkPhysicalDevice'):])
2050 # generate structure type name from structure name
2051 # note that sometimes digits are separated with '_':
2052 # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT
2053 # but mostly they are not:
2054 # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES
2056 'FragmentDensityMap2' : ['FRAGMENT', 'DENSITY', 'MAP', '2'],
2057 'Ycbcr2Plane444Formats' : ['YCBCR', '2', 'PLANE', '444', 'FORMATS'],
2058 'ASTCDecode' : ['ASTC', 'DECODE'],
2059 '4444Formats' : ['4444', 'FORMATS'],
2060 'TextureCompressionASTCHDR' : ['TEXTURE', 'COMPRESSION', 'ASTC', 'HDR'],
2061 'Synchronization2' : ['SYNCHRONIZATION', '2'],
2062 'ShaderAtomicFloat2' : ['SHADER', 'ATOMIC', 'FLOAT', '2'],
2063 'Robustness2' : ['ROBUSTNESS', '2'],
2064 'Maintenance4' : ['MAINTENANCE', '4'],
2065 'ExtendedDynamicState2' : ['EXTENDED', 'DYNAMIC', 'STATE', '2'],
2067 nameSplitUp = specialCaseDict.get(nameResult.group(1))
2068 if nameSplitUp == None:
2069 nameSplit = re.findall(r'[1-9A-Z]+(?:[a-z1-9]+|[A-Z]*(?=[A-Z]|$))', nameResult.group(1))
2070 nameSplitUp = map(str.upper, nameSplit)
2071 nameSplitUp = list(nameSplitUp) + ['FEATURES']
2072 # check if there is extension suffix
2073 if (len(nameResult.group(2)) != 0):
2074 nameSplitUp.append(nameResult.group(2))
2076 self.sType = 'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_' + '_'.join(nameSplitUp)
2077 self.instanceName = 'd' + name[11:]
2078 self.flagName = 'is' + name[16:]
2079 self.extension = None
2084 # helper extension class used in algorith below
2085 class StructureFoundContinueToNextOne(Exception):
2087 existingStructures = list(filter(structInAPI, testedStructures)) # remove features not found in API ( important for Vulkan SC )
2088 testedStructureDetail = [StructureDetail(struct) for struct in existingStructures]
2089 # iterate over all searched structures and find extensions that enable them
2090 for structureDetail in testedStructureDetail:
2092 # iterate over all extensions
2093 for extension in api.extensions[1:]:
2094 # check composite types and typedefs in case extension is part of core
2095 for structureList in [extension.compositeTypes, extension.typedefs]:
2096 # iterate over all structures added by extension
2097 for extensionStructure in structureList:
2098 # compare checked structure name to name of structure from extension
2099 if structureDetail.name == extensionStructure.name:
2100 structureDetail.extension = extension.name
2101 if extension.versionInCore is not None:
2102 structureDetail.api = extension.versionInCore[1]
2103 structureDetail.major = extension.versionInCore[2]
2104 structureDetail.minor = extension.versionInCore[3]
2105 raise StructureFoundContinueToNextOne
2106 except StructureFoundContinueToNextOne:
2108 for structureDetail in testedStructureDetail:
2109 for compositeType in api.compositeTypes:
2110 if structureDetail.name != compositeType.name:
2112 structureMembers = compositeType.members[2:]
2113 structureDetail.members = [m.name for m in structureMembers]
2114 if structureDetail.major is not None:
2116 # if structure was not added with extension then check if
2117 # it was added directly with one of vulkan versions
2118 apiVersion = compositeType.apiVersion
2119 if apiVersion is None:
2121 structureDetail.api = apiVersion.api
2122 structureDetail.major = apiVersion.major
2123 structureDetail.minor = apiVersion.minor
2125 # generate file content
2126 structureDefinitions = []
2127 featureEnabledFlags = []
2128 clearStructures = []
2131 verifyStructures = []
2132 for index, structureDetail in enumerate(testedStructureDetail):
2133 # create two instances of each structure
2135 structureDefinitions.append(structureDetail.name + nameSpacing + structureDetail.instanceName + '[count];')
2136 # create flags that check if proper extension or vulkan version is available
2138 extension = structureDetail.extension
2139 major = structureDetail.major
2140 if extension is not None:
2141 condition = ' checkExtension(properties, "' + extension + '")'
2142 if major is not None:
2147 condition += 'context.contextSupports(vk::ApiVersion(' + str(structureDetail.api) + ', ' + str(major) + ', ' + str(structureDetail.minor) + ', 0))'
2151 nameSpacing = '\t' * int((len(structureDetail.name) - 4) / 4)
2152 featureEnabledFlags.append('const bool' + nameSpacing + structureDetail.flagName + ' =' + condition)
2153 # clear memory of each structure
2154 clearStructures.append('\tdeMemset(&' + structureDetail.instanceName + '[ndx], 0xFF * ndx, sizeof(' + structureDetail.name + '));')
2155 # construct structure chain
2156 nextInstanceName = 'DE_NULL';
2157 if index < len(testedStructureDetail)-1:
2158 nextInstanceName = '&' + testedStructureDetail[index+1].instanceName + '[ndx]'
2159 structureChain.append([
2160 '\t\t' + structureDetail.instanceName + '[ndx].sType = ' + structureDetail.flagName + ' ? ' + structureDetail.sType + ' : VK_STRUCTURE_TYPE_MAX_ENUM;',
2161 '\t\t' + structureDetail.instanceName + '[ndx].pNext = DE_NULL;'])
2162 # construct log section
2163 logStructures.append([
2164 '\tif (' + structureDetail.flagName + ')',
2165 '\t\tlog << TestLog::Message << ' + structureDetail.instanceName + '[0] << TestLog::EndMessage;'
2167 #construct verification section
2168 verifyStructure = []
2169 verifyStructure.append('\tif (' + structureDetail.flagName + ' &&')
2170 for index, m in enumerate(structureDetail.members):
2171 prefix = '\t\t(' if index == 0 else '\t\t '
2172 postfix = '))' if index == len(structureDetail.members)-1 else ' ||'
2173 verifyStructure.append(prefix + structureDetail.instanceName + '[0].' + m + ' != ' + structureDetail.instanceName + '[1].' + m + postfix)
2174 if len(structureDetail.members) == 0:
2175 verifyStructure.append('\t\tfalse)')
2176 verifyStructure.append('\t{\n\t\tTCU_FAIL("Mismatch between ' + structureDetail.name + '");\n\t}')
2177 verifyStructures.append(verifyStructure)
2179 # construct file content
2182 # individual test functions
2183 for n, x in enumerate(testedStructureDetail):
2184 stream.append("tcu::TestStatus testPhysicalDeviceFeature" + x.instanceName[len('device'):]+" (Context& context)")
2186 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
2187 const CustomInstance instance (createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
2188 const InstanceDriver& vki (instance.getDriver());
2189 const int count = 2u;
2190 TestLog& log = context.getTestContext().getLog();
2191 VkPhysicalDeviceFeatures2 extFeatures;
2192 vector<VkExtensionProperties> properties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
2194 stream.append("\t"+structureDefinitions[n])
2195 stream.append("\t"+featureEnabledFlags[n])
2197 stream.append('\tfor (int ndx = 0; ndx < count; ++ndx)\n\t{')
2198 stream.append("\t" + clearStructures[n])
2199 stream.extend(structureChain[n])
2202 '\t\tdeMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));\n'
2203 '\t\textFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;\n'
2204 '\t\textFeatures.pNext = &' + testedStructureDetail[n].instanceName + '[ndx];\n\n'
2205 '\t\tvki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);')
2206 stream.append('\t}\n')
2207 stream.extend(logStructures[n])
2209 stream.extend(verifyStructures[n])
2210 stream.append('\treturn tcu::TestStatus::pass("Querying succeeded");')
2211 stream.append("}\n")
2213 # function to create tests
2215 void addSeparateFeatureTests (tcu::TestCaseGroup* testGroup)
2218 for x in testedStructureDetail:
2219 stream.append('\taddFunctionCase(testGroup, "' + camelToSnake(x.instanceName[len('device'):]) + '", "' + x.name + '", testPhysicalDeviceFeature' + x.instanceName[len('device'):] + ');')
2220 stream.append('}\n')
2223 writeInlFile(filename, INL_HEADER, stream)
2225 def generateDeviceFeaturesDefs(apiName, src):
2226 # look for definitions
2227 ptrnSType = r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_FEATURES(\w*)\s*='
2228 matches = re.findall(ptrnSType, src, re.M)
2229 matches = sorted(matches, key=lambda m: m[0])
2230 # hardcoded list of core extensions having features and missing from Vulkan SC
2231 missingVulkanSCExt = \
2232 '#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME \"VK_KHR_16bit_storage\"\n' \
2233 '#define VK_KHR_8BIT_STORAGE_EXTENSION_NAME \"VK_KHR_8bit_storage\"\n' \
2234 '#define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME \"VK_KHR_buffer_device_address\"\n' \
2235 '#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME \"VK_EXT_descriptor_indexing\"\n' \
2236 '#define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME \"VK_EXT_host_query_reset\"\n' \
2237 '#define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME \"VK_KHR_imageless_framebuffer\"\n' \
2238 '#define VK_KHR_MULTIVIEW_EXTENSION_NAME \"VK_KHR_multiview\"\n' \
2239 '#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME \"VK_KHR_sampler_ycbcr_conversion\"\n' \
2240 '#define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME \"VK_EXT_scalar_block_layout\"\n' \
2241 '#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME \"VK_KHR_separate_depth_stencil_layouts\"\n' \
2242 '#define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME \"VK_KHR_shader_atomic_int64\"\n' \
2243 '#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME \"VK_KHR_shader_draw_parameters\"\n' \
2244 '#define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME \"VK_KHR_shader_float16_int8\"\n' \
2245 '#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME \"VK_KHR_shader_subgroup_extended_types\"\n' \
2246 '#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME \"VK_KHR_timeline_semaphore\"\n' \
2247 '#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME \"VK_KHR_uniform_buffer_standard_layout\"\n' \
2248 '#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME \"VK_KHR_variable_pointers\"\n' \
2249 '#define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME \"VK_KHR_vulkan_memory_model\"\n'
2250 # construct final list
2252 for sType, sSuffix in matches:
2253 structName = re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '')
2254 ptrnStructName = r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Features' + sSuffix.replace('_', '') + ')'
2255 matchStructName = re.search(ptrnStructName, src, re.IGNORECASE)
2257 # handle special cases
2258 if sType == "EXCLUSIVE_SCISSOR":
2259 sType = "SCISSOR_EXCLUSIVE"
2260 elif sType == "ASTC_DECODE":
2261 sType = "ASTC_DECODE_MODE"
2262 elif sType == "MAINTENANCE_4":
2263 sType = "MAINTENANCE4"
2264 elif sType == "YCBCR_2_PLANE_444_FORMATS":
2265 sType = "YCBCR_2PLANE_444_FORMATS"
2266 elif sType in {'VULKAN_1_1', 'VULKAN_1_2', 'VULKAN_1_3'}:
2268 elif sType == 'RASTERIZATION_ORDER_ATTACHMENT_ACCESS':
2269 # skip case that has const pNext pointer
2271 # skip cases that have const pNext pointer
2272 if sType == 'RASTERIZATION_ORDER_ATTACHMENT_ACCESS':
2274 # skip cases that have const pNext pointer
2275 if sType == 'RASTERIZATION_ORDER_ATTACHMENT_ACCESS':
2277 # end handling special cases
2278 ptrnExtensionName = r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_EXTENSION_NAME).+$'
2279 matchExtensionName = re.search(ptrnExtensionName, src, re.M)
2280 if matchExtensionName is None and apiName=='SC':
2281 matchExtensionName = re.search(ptrnExtensionName, missingVulkanSCExt, re.M)
2282 ptrnSpecVersion = r'^\s*#define\s+(\w+' + sSuffix + '_' + sType + '_SPEC_VERSION).+$'
2283 matchSpecVersion = re.search(ptrnSpecVersion, src, re.M)
2284 defs.append( (sType, '', sSuffix, matchStructName.group(1), \
2285 matchExtensionName.group(0) if matchExtensionName else None,
2286 matchExtensionName.group(1) if matchExtensionName else None,
2287 matchSpecVersion.group(1) if matchSpecVersion else '0') )
2290 def generateDevicePropertiesDefs(apiName, src):
2291 # look for definitions
2292 ptrnSType = r'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_PROPERTIES(\w*)\s*='
2293 matches = re.findall(ptrnSType, src, re.M)
2294 matches = sorted(matches, key=lambda m: m[0])
2295 # hardcoded list of core extensions having properties and missing from Vulkan SC
2296 missingVulkanSCExt = \
2297 '#define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME \"VK_KHR_depth_stencil_resolve\"\n' \
2298 '#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME \"VK_EXT_descriptor_indexing\"\n' \
2299 '#define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME \"VK_KHR_driver_properties\"\n' \
2300 '#define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME \"VK_KHR_shader_float_controls\"\n' \
2301 '#define VK_KHR_MAINTENANCE3_EXTENSION_NAME \"VK_KHR_maintenance3\"\n' \
2302 '#define VK_KHR_MULTIVIEW_EXTENSION_NAME \"VK_KHR_multiview\"\n' \
2303 '#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME \"VK_EXT_sampler_filter_minmax\"\n' \
2304 '#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME \"VK_KHR_timeline_semaphore\"\n'
2305 # construct final list
2307 for sType, sSuffix in matches:
2308 # handle special cases
2309 if sType in {'VULKAN_1_1', 'VULKAN_1_2', 'VULKAN_1_3', 'VULKAN_SC_1_0', 'GROUP', 'MEMORY_BUDGET', 'MEMORY', 'TOOL'}:
2311 # there are cases like VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD
2312 # where 2 is after PROPERTIES - to handle this we need to split suffix to two parts
2314 sExtSuffix = sSuffix
2315 suffixStart = sSuffix.rfind('_')
2317 sVerSuffix = sSuffix[:suffixStart]
2318 sExtSuffix = sSuffix[suffixStart:]
2319 # handle special case
2323 structName = re.sub("[_0-9][a-z]", lambda match: match.group(0).upper(), sType.capitalize()).replace('_', '')
2324 ptrnStructName = r'\s*typedef\s+struct\s+(VkPhysicalDevice' + structName + 'Properties' + sSuffix.replace('_', '') + ')'
2325 matchStructName = re.search(ptrnStructName, src, re.M)
2328 if extType == "DISCARD_RECTANGLE":
2329 extType = "DISCARD_RECTANGLES"
2330 elif extType == "DRIVER":
2331 extType = "DRIVER_PROPERTIES"
2332 elif extType == "POINT_CLIPPING":
2333 extType = "MAINTENANCE_2"
2334 elif extType == "SHADER_CORE":
2335 extType = "SHADER_CORE_PROPERTIES"
2336 elif extType == "DRM":
2337 extType = "PHYSICAL_DEVICE_DRM"
2339 if extType == "MAINTENANCE_3":
2340 extType = "MAINTENANCE3"
2341 elif extType == "MAINTENANCE_4":
2342 extType = "MAINTENANCE4"
2343 elif extType == "POINT_CLIPPING":
2344 extType = "MAINTENANCE2"
2345 # end handling special cases
2346 ptrnExtensionName = r'^\s*#define\s+(\w+' + sExtSuffix + '_' + extType + sVerSuffix +'[_0-9]*_EXTENSION_NAME).+$'
2347 matchExtensionName = re.search(ptrnExtensionName, src, re.M)
2348 if matchExtensionName is None and apiName=='SC':
2349 matchExtensionName = re.search(ptrnExtensionName, missingVulkanSCExt, re.M)
2350 ptrnSpecVersion = r'^\s*#define\s+(\w+' + sExtSuffix + '_' + extType + sVerSuffix + '[_0-9]*_SPEC_VERSION).+$'
2351 matchSpecVersion = re.search(ptrnSpecVersion, src, re.M)
2352 defs.append( (sType, sVerSuffix, sExtSuffix, matchStructName.group(1), \
2353 matchExtensionName.group(0) if matchExtensionName else None,
2354 matchExtensionName.group(1) if matchExtensionName else None,
2355 matchSpecVersion.group (1) if matchSpecVersion else '0') )
2358 def writeDeviceFeatures(api, dfDefs, filename):
2359 # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs
2360 # and construct dictionary with all of their attributes
2363 blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$")
2364 for structureType in api.compositeTypes:
2365 match = blobPattern.match(structureType.name)
2367 allMembers = [member.name for member in structureType.members]
2368 vkVersion = match.group(1)
2369 blobMembers[vkVersion] = allMembers[2:]
2370 blobStructs[vkVersion] = set()
2371 initFromBlobDefinitions = []
2372 emptyInitDefinitions = []
2373 # iterate over all feature structures
2374 allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*")
2375 nonExtFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*$")
2376 for structureType in api.compositeTypes:
2377 # skip structures that are not feature structures
2378 if not allFeaturesPattern.match(structureType.name):
2380 # skip structures that were previously identified as blobs
2381 if blobPattern.match(structureType.name):
2383 if structureType.isAlias:
2385 # skip sType and pNext and just grab third and next attributes
2386 structureMembers = structureType.members[2:]
2387 notPartOfBlob = True
2388 if nonExtFeaturesPattern.match(structureType.name):
2389 # check if this member is part of any of the blobs
2390 for blobName, blobMemberList in blobMembers.items():
2391 # if just one member is not part of this blob go to the next blob
2392 # (we asume that all members are part of blob - no need to check all)
2393 if structureMembers[0].name not in blobMemberList:
2395 # add another feature structure name to this blob
2396 blobStructs[blobName].add(structureType)
2397 # add specialization for this feature structure
2399 for member in structureMembers:
2400 memberCopying += "\tfeatureType.{0} = allFeaturesBlobs.vk{1}.{0};\n".format(member.name, blobName)
2402 "template<> void initFeatureFromBlob<{0}>({0}& featureType, const AllFeaturesBlobs& allFeaturesBlobs)\n" \
2405 "}}".format(structureType.name, memberCopying)
2406 initFromBlobDefinitions.append(wholeFunction)
2407 notPartOfBlob = False
2408 # assuming that all members are part of blob, goto next
2410 # add empty template definition as on Fedora there are issue with
2411 # linking using just generic template - all specializations are needed
2413 emptyFunction = "template<> void initFeatureFromBlob<{0}>({0}&, const AllFeaturesBlobs&) {{}}"
2414 emptyInitDefinitions.append(emptyFunction.format(structureType.name))
2415 extensionDefines = []
2416 makeFeatureDescDefinitions = []
2417 featureStructWrappers = []
2418 for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extLine, extName, specVer) in enumerate(dfDefs):
2419 extensionNameDefinition = extName
2420 if not extensionNameDefinition:
2421 extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType)
2422 # construct defines with names
2424 extensionDefines.append(extLine)
2426 extensionDefines.append('#define {0} "not_existent_feature"'.format(extensionNameDefinition))
2427 # handle special cases
2428 if sType == "SCISSOR_EXCLUSIVE":
2429 sType = "EXCLUSIVE_SCISSOR"
2430 elif sType == "ASTC_DECODE_MODE":
2431 sType = "ASTC_DECODE"
2432 elif sType == "MAINTENANCE4":
2433 sType = "MAINTENANCE_4"
2434 elif sType == "YCBCR_2PLANE_444_FORMATS":
2435 sType = "YCBCR_2_PLANE_444_FORMATS"
2436 # end handling special cases
2437 # construct makeFeatureDesc template function definitions
2438 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sVerSuffix + sExtSuffix)
2439 makeFeatureDescDefinitions.append("template<> FeatureDesc makeFeatureDesc<{0}>(void) " \
2440 "{{ return FeatureDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dfDefs)-idx))
2441 # construct CreateFeatureStruct wrapper block
2442 featureStructWrappers.append("\t{{ createFeatureStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer))
2443 # construct function that will check for which vk version structure sType is part of blob
2444 blobChecker = "deUint32 getBlobFeaturesVersion (VkStructureType sType)\n{\n" \
2445 "\tconst std::map<VkStructureType, deUint32> sTypeBlobMap\n" \
2447 # iterate over blobs with list of structures
2448 for blobName in sorted(blobStructs.keys()):
2449 blobChecker += "\t\t// Vulkan{0}\n".format(blobName)
2450 # iterate over all feature structures in current blob
2451 structuresList = list(blobStructs[blobName])
2452 structuresList = sorted(structuresList, key=lambda s: s.name)
2453 for structType in structuresList:
2454 # find definition of this structure in dfDefs
2455 structName = structType.name
2456 # handle special cases
2457 if structName == 'VkPhysicalDeviceShaderDrawParameterFeatures':
2458 structName = 'VkPhysicalDeviceShaderDrawParametersFeatures'
2459 # end handling special cases
2460 structDef = [s for s in dfDefs if s[3] == structName][0]
2461 sType = structDef[0]
2462 sSuffix = structDef[1] + structDef[2]
2463 # handle special cases
2464 if sType == "SCISSOR_EXCLUSIVE":
2465 sType = "EXCLUSIVE_SCISSOR"
2466 elif sType == "MAINTENANCE4":
2467 sType = "MAINTENANCE_4"
2468 # end handling special cases
2469 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sSuffix)
2470 tabs = "\t" * int((88 - len(sTypeName)) / 4)
2471 blobChecker += "\t\t{{ {0},{1}VK_API_VERSION_{2}_{3} }},\n".format(sTypeName, tabs, blobName[0], blobName[1])
2472 blobChecker += "\t};\n\n" \
2473 "\tauto it = sTypeBlobMap.find(sType);\n" \
2474 "\tif(it == sTypeBlobMap.end())\n" \
2476 "\treturn it->second;\n" \
2478 # combine all definition lists
2480 '#include "vkDeviceFeatures.hpp"\n',
2482 stream.extend(extensionDefines)
2484 stream.extend(initFromBlobDefinitions)
2485 stream.append('\n// generic template is not enough for some compilers')
2486 stream.extend(emptyInitDefinitions)
2488 stream.extend(makeFeatureDescDefinitions)
2490 stream.append('static const FeatureStructCreationData featureStructCreationArray[]\n{')
2491 stream.extend(featureStructWrappers)
2492 stream.append('};\n')
2493 stream.append(blobChecker)
2494 stream.append('} // vk\n')
2495 writeInlFile(filename, INL_HEADER, stream)
2497 def writeDeviceFeatureTest(apiName, api, filename):
2499 coreFeaturesPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$")
2502 # iterate over all feature structures
2503 allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*")
2504 for structureType in api.compositeTypes:
2505 # skip structures that are not feature structures
2506 if not allFeaturesPattern.match(structureType.name):
2508 # skip alias structures
2509 if structureType.isAlias:
2511 # skip sType and pNext and just grab third and next attributes
2512 structureMembers = structureType.members[2:]
2515 for member in structureMembers:
2516 items.append(" FEATURE_ITEM ({0}, {1}),".format(structureType.name, member.name))
2519 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest{4} (Context& context)
2521 const PlatformInterface& vkp = context.getPlatformInterface();
2522 tcu::TestLog& log = context.getTestContext().getLog();
2523 tcu::ResultCollector resultCollector (log);
2524 const CustomInstance instance (createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
2525 const InstanceDriver& instanceDriver (instance.getDriver());
2526 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
2527 const deUint32 queueFamilyIndex = 0;
2528 const deUint32 queueCount = 1;
2529 const float queuePriority = 1.0f;
2530 const DeviceFeatures deviceFeaturesAll (context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
2531 const VkPhysicalDeviceFeatures2 deviceFeatures2 = deviceFeaturesAll.getCoreFeatures2();
2533 bool isSubProcess = context.getTestContext().getCommandLine().isSubProcess();
2536 VkPhysicalDeviceFeatures emptyDeviceFeatures;
2537 deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));
2539 // Only non-core extensions will be used when creating the device.
2540 vector<const char*> coreExtensions;
2541 getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
2542 vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
2544 vector<const char*> extensionNames;
2545 extensionNames.reserve(nonCoreExtensions.size());
2546 for (const string& extension : nonCoreExtensions)
2547 extensionNames.push_back(extension.c_str());
2549 if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<{0}>()))
2551 static const Feature features[] =
2555 auto* supportedFeatures = reinterpret_cast<const {0}*>(featuresStruct);
2556 checkFeatures(vkp, instance, instanceDriver, physicalDevice, {2}, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, {3}, emptyDeviceFeatures, {5});
2560 return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
2562 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
2565 additionalParams = ( 'memReservationStatMax, isSubProcess' if apiName == 'SC' else 'isSubProcess' )
2566 additionalDefs = ( ' VkDeviceObjectReservationCreateInfo memReservationStatMax = context.getResourceInterface()->getStatMax();' if apiName == 'SC' else '')
2567 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))
2569 testFunctions.append("createDeviceWithUnsupportedFeaturesTest" + structureType.name[len('VkPhysicalDevice'):])
2572 stream.extend(featureItems)
2574 void addSeparateUnsupportedFeatureTests (tcu::TestCaseGroup* testGroup)
2577 for x in testFunctions:
2578 stream.append('\taddFunctionCase(testGroup, "' + camelToSnake(x[len('createDeviceWithUnsupportedFeaturesTest'):]) + '", "' + x + '", ' + x + ');')
2579 stream.append('}\n')
2581 writeInlFile(filename, INL_HEADER, stream)
2583 def writeDeviceProperties(api, dpDefs, filename):
2584 # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs
2585 # and construct dictionary with all of their attributes
2588 blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Properties[0-9]*$")
2589 for structureType in api.compositeTypes:
2590 match = blobPattern.match(structureType.name)
2592 allMembers = [member.name for member in structureType.members]
2593 vkVersion = match.group(1)
2594 blobMembers[vkVersion] = allMembers[2:]
2595 blobStructs[vkVersion] = set()
2596 initFromBlobDefinitions = []
2597 emptyInitDefinitions = []
2598 # iterate over all property structures
2599 allPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*")
2600 nonExtPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*$")
2601 for structureType in api.compositeTypes:
2602 # skip structures that are not property structures
2603 if not allPropertiesPattern.match(structureType.name):
2605 # skip structures that were previously identified as blobs
2606 if blobPattern.match(structureType.name):
2608 if structureType.isAlias:
2610 # skip sType and pNext and just grab third and next attributes
2611 structureMembers = structureType.members[2:]
2612 notPartOfBlob = True
2613 if nonExtPropertiesPattern.match(structureType.name):
2614 # check if this member is part of any of the blobs
2615 for blobName, blobMemberList in blobMembers.items():
2616 # if just one member is not part of this blob go to the next blob
2617 # (we asume that all members are part of blob - no need to check all)
2618 if structureMembers[0].name not in blobMemberList:
2620 # add another property structure name to this blob
2621 blobStructs[blobName].add(structureType)
2622 # add specialization for this property structure
2624 for member in structureMembers:
2625 if not member.arraySize:
2626 # handle special case
2627 if structureType.name == "VkPhysicalDeviceSubgroupProperties" and "subgroup" not in member.name :
2628 blobMemberName = "subgroup" + member.name[0].capitalize() + member.name[1:]
2629 memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{2};\n".format(member.name, blobName, blobMemberName)
2630 # end handling special case
2632 memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{0};\n".format(member.name, blobName)
2634 memberCopying += "\tmemcpy(propertyType.{0}, allPropertiesBlobs.vk{1}.{0}, sizeof({2}) * {3});\n".format(member.name, blobName, member.type[0], member.arraySize[1:-1])
2636 "template<> void initPropertyFromBlob<{0}>({0}& propertyType, const AllPropertiesBlobs& allPropertiesBlobs)\n" \
2639 "}}".format(structureType.name, memberCopying)
2640 initFromBlobDefinitions.append(wholeFunction)
2641 notPartOfBlob = False
2642 # assuming that all members are part of blob, goto next
2644 # add empty template definition as on Fedora there are issue with
2645 # linking using just generic template - all specializations are needed
2647 emptyFunction = "template<> void initPropertyFromBlob<{0}>({0}&, const AllPropertiesBlobs&) {{}}"
2648 emptyInitDefinitions.append(emptyFunction.format(structureType.name))
2649 extensionDefines = []
2650 makePropertyDescDefinitions = []
2651 propertyStructWrappers = []
2652 for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extLine, extName, specVer) in enumerate(dpDefs):
2653 extensionNameDefinition = extName
2654 if not extensionNameDefinition:
2655 extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType)
2656 # construct defines with names
2658 extensionDefines.append(extLine)
2660 extensionDefines.append('#define {0} "core_property"'.format(extensionNameDefinition))
2661 # construct makePropertyDesc template function definitions
2662 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sVerSuffix + sExtSuffix)
2663 makePropertyDescDefinitions.append("template<> PropertyDesc makePropertyDesc<{0}>(void) " \
2664 "{{ return PropertyDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVer, len(dpDefs)-idx))
2665 # construct CreateProperty struct wrapper block
2666 propertyStructWrappers.append("\t{{ createPropertyStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVer))
2667 # construct method that will check if structure sType is part of blob
2668 blobChecker = "deUint32 getBlobPropertiesVersion (VkStructureType sType)\n{\n" \
2669 "\tconst std::map<VkStructureType, deUint32> sTypeBlobMap\n" \
2671 # iterate over blobs with list of structures
2672 for blobName in sorted(blobStructs.keys()):
2673 blobChecker += "\t\t// Vulkan{0}\n".format(blobName)
2674 # iterate over all feature structures in current blob
2675 structuresList = list(blobStructs[blobName])
2676 structuresList = sorted(structuresList, key=lambda s: s.name)
2677 for structType in structuresList:
2678 # find definition of this structure in dpDefs
2679 structName = structType.name
2680 structDef = [s for s in dpDefs if s[3] == structName][0]
2681 sType = structDef[0]
2682 sSuffix = structDef[1] + structDef[2]
2683 sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sSuffix)
2684 tabs = "\t" * int((76 - len(sTypeName)) / 4)
2685 blobChecker += "\t\t{{ {0},{1}VK_API_VERSION_{2}_{3} }},\n".format(sTypeName, tabs, blobName[0], blobName[1])
2686 blobChecker += "\t};\n\n" \
2687 "\tauto it = sTypeBlobMap.find(sType);\n" \
2688 "\tif(it == sTypeBlobMap.end())\n" \
2690 "\treturn it->second;\n" \
2692 # combine all definition lists
2694 '#include "vkDeviceProperties.hpp"\n',
2696 stream.extend(extensionDefines)
2698 stream.extend(initFromBlobDefinitions)
2699 stream.append('\n// generic template is not enough for some compilers')
2700 stream.extend(emptyInitDefinitions)
2702 stream.extend(makePropertyDescDefinitions)
2704 stream.append('static const PropertyStructCreationData propertyStructCreationArray[] =\n{')
2705 stream.extend(propertyStructWrappers)
2706 stream.append('};\n')
2707 stream.append(blobChecker)
2708 stream.append('} // vk\n')
2709 writeInlFile(filename, INL_HEADER, stream)
2711 def genericDeviceFeaturesWriter(dfDefs, pattern, filename):
2713 for _, _, _, extStruct, _, _, _ in dfDefs:
2714 nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
2715 stream.append(pattern.format(extStruct, nameSubStr))
2716 writeInlFile(filename, INL_HEADER, indentLines(stream))
2718 def writeDeviceFeaturesDefaultDeviceDefs(dfDefs, filename):
2719 pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceFeatures.getFeatureType<{0}>();\t}}"
2720 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2722 def writeDeviceFeaturesContextDecl(dfDefs, filename):
2723 pattern = "const vk::{0}&\tget{1}\t(void) const;"
2724 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2726 def writeDeviceFeaturesContextDefs(dfDefs, filename):
2727 pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}"
2728 genericDeviceFeaturesWriter(dfDefs, pattern, filename)
2730 def genericDevicePropertiesWriter(dfDefs, pattern, filename):
2732 for _, _, _, extStruct, _, _, _ in dfDefs:
2733 nameSubStr = extStruct.replace("VkPhysicalDevice", "").replace("KHR", "").replace("NV", "")
2734 if extStruct == "VkPhysicalDeviceRayTracingPropertiesNV":
2736 stream.append(pattern.format(extStruct, nameSubStr))
2737 writeInlFile(filename, INL_HEADER, indentLines(stream))
2739 def writeDevicePropertiesDefaultDeviceDefs(dfDefs, filename):
2740 pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceProperties.getPropertyType<{0}>();\t}}"
2741 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2743 def writeDevicePropertiesContextDecl(dfDefs, filename):
2744 pattern = "const vk::{0}&\tget{1}\t(void) const;"
2745 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2747 def writeDevicePropertiesContextDefs(dfDefs, filename):
2748 pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}"
2749 genericDevicePropertiesWriter(dfDefs, pattern, filename)
2751 def writeMandatoryFeatures(api, filename):
2753 def structInAPI(name):
2754 for c in api.compositeTypes:
2762 for _, data in api.additionalExtensionData:
2763 if 'mandatory_features' not in data.keys():
2765 # sort to have same results for py2 and py3
2766 listStructFeatures = sorted(data['mandatory_features'].items(), key=lambda tup: tup[0])
2767 for structure, featuresList in listStructFeatures:
2768 for featureData in featuresList:
2769 # allow for featureless VKSC only extensions
2770 if not 'features' in featureData.keys() or 'requirements' not in featureData.keys():
2772 requirements = featureData['requirements']
2774 mandatory_variant = ''
2776 mandatory_variant = featureData['mandatory_variant']
2778 mandatory_variant = ''
2780 dictData.append( [ structure, featureData['features'], requirements, mandatory_variant] )
2782 if structure == 'VkPhysicalDeviceFeatures':
2784 # if structure is not in dict construct name of variable and add is as a first item
2785 if (structure not in dictStructs):
2786 dictStructs[structure] = ([structure[2:3].lower() + structure[3:]], mandatory_variant)
2787 # add first requirement if it is unique
2788 if requirements and (requirements[0] not in dictStructs[structure][0]):
2789 dictStructs[structure][0].append(requirements[0])
2792 stream.extend(['bool checkMandatoryFeatures(const vkt::Context& context)\n{',
2793 '\tif (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))',
2794 '\t\tTCU_THROW(NotSupportedError, "Extension VK_KHR_get_physical_device_properties2 is not present");',
2796 '\tVkPhysicalDevice\t\t\t\t\tphysicalDevice\t\t= context.getPhysicalDevice();',
2797 '\tconst InstanceInterface&\t\t\tvki\t\t\t\t\t= context.getInstanceInterface();',
2798 '\tconst vector<VkExtensionProperties>\tdeviceExtensions\t= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);',
2800 '\ttcu::TestLog& log = context.getTestContext().getLog();',
2801 '\tvk::VkPhysicalDeviceFeatures2 coreFeatures;',
2802 '\tdeMemset(&coreFeatures, 0, sizeof(coreFeatures));',
2803 '\tcoreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;',
2804 '\tvoid** nextPtr = &coreFeatures.pNext;',
2807 listStruct = sorted(dictStructs.items(), key=lambda tup: tup[0]) # sort to have same results for py2 and py3
2808 apiStruct = list( filter(lambda x : structInAPI(x[0]), listStruct)) # remove items not defined in current A
2810 for k, v in apiStruct:
2813 metaCondition = metaCondition + ' || defined(CTS_USES_' + v[1][0].upper() + ')'
2814 stream.extend(['#if ' + metaCondition[4:]])
2815 if (v[0][1].startswith("ApiVersion")):
2816 cond = '\tif (context.contextSupports(vk::' + v[0][1] + '))'
2818 cond = '\tif (vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "' + v[0][1] + '"))'
2819 stream.extend(['\tvk::' + k + ' ' + v[0][0]+ ';',
2820 '\tdeMemset(&' + v[0][0] + ', 0, sizeof(' + v[0][0] + '));',
2825 for i, req in enumerate(reqs) :
2826 if (req.startswith("ApiVersion")):
2827 cond = cond + 'context.contextSupports(vk::' + req + ')'
2829 cond = cond + 'isExtensionSupported(deviceExtensions, RequiredExtension("' + req + '"))'
2830 if i+1 < len(reqs) :
2831 cond = cond + ' || '
2833 stream.append('\t' + cond)
2834 stream.extend(['\t{',
2835 '\t\t' + v[0][0] + '.sType = getStructureType<' + k + '>();',
2836 '\t\t*nextPtr = &' + v[0][0] + ';',
2837 '\t\tnextPtr = &' + v[0][0] + '.pNext;',
2839 if metaCondition != '':
2840 stream.extend(['#endif // ' + metaCondition[4:],
2844 stream.extend(['\tcontext.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &coreFeatures);',
2845 '\tbool result = true;',
2850 if not structInAPI(v[0]): # remove items not defined in current API ( important for Vulkan SC )
2853 structName = 'coreFeatures.features';
2855 if len(v) == 4 and v[3] != '':
2856 # for x in v[3].split('_'):
2857 metaCondition = metaCondition + ' || defined(CTS_USES_' + v[3][0].upper() + ')'
2858 stream.extend(['#if ' + metaCondition[4:]])
2859 if v[0] != 'VkPhysicalDeviceFeatures' :
2860 structName = dictStructs[v[0]][0][0]
2863 for i, req in enumerate(v[2]) :
2864 if (req.startswith("ApiVersion")):
2865 condition = condition + 'context.contextSupports(vk::' + req + ')'
2867 condition = condition + req
2869 condition = condition + 'isExtensionSupported(deviceExtensions, RequiredExtension("' + req + '"))'
2870 if i+1 < len(v[2]) :
2871 condition = condition + ' && '
2872 condition = condition + ' )'
2873 stream.append('\t' + condition)
2874 stream.append('\t{')
2875 # Don't need to support an AND case since that would just be another line in the .txt
2877 stream.append('\t\tif ( ' + structName + '.' + v[1][0] + ' == VK_FALSE )')
2880 for i, feature in enumerate(v[1]):
2882 condition = condition + ' && '
2883 condition = condition + '( ' + structName + '.' + feature + ' == VK_FALSE )'
2884 condition = condition + ' )'
2885 stream.append('\t\t' + condition)
2886 featureSet = " or ".join(v[1])
2887 stream.extend(['\t\t{',
2888 '\t\t\tlog << tcu::TestLog::Message << "Mandatory feature ' + featureSet + ' not supported" << tcu::TestLog::EndMessage;',
2889 '\t\t\tresult = false;',
2892 if metaCondition != '':
2893 stream.extend(['#endif // ' + metaCondition[4:],
2898 stream.append('\treturn result;')
2899 stream.append('}\n')
2900 writeInlFile(filename, INL_HEADER, stream)
2902 def writeExtensionList(apiName, api, filename, extensionType):
2904 for extensionName, data in api.additionalExtensionData:
2905 # make sure extension name starts with VK_KHR
2906 if not extensionName.startswith('VK_KHR'):
2908 # make sure that this extension was registered
2909 if 'register_extension' not in data.keys():
2911 # make sure extension is intended for the vulkan variant
2915 if 'mandatory_features' in data.keys():
2916 for structure, listStruct in data['mandatory_features'].items():
2917 for featureData in listStruct:
2918 mandatory_variant = ''
2920 mandatory_variant = featureData['mandatory_variant']
2922 mandatory_variant = ''
2924 if 'vulkansc' in mandatory_variant:
2929 # make sure extension has proper type
2930 if extensionType == data['register_extension']['type']:
2931 extensionList.append(extensionName)
2932 extensionList.sort()
2933 # write list of all found extensions
2935 stream.append('static const char* s_allowed{0}KhrExtensions[] =\n{{'.format(extensionType.title()))
2936 for n in extensionList:
2937 stream.append('\t"' + n + '",')
2938 stream.append('};\n')
2939 writeInlFile(filename, INL_HEADER, stream)
2941 def parseCmdLineArgs():
2942 parser = argparse.ArgumentParser(description = "Generate Vulkan INL files",
2943 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
2944 parser.add_argument("-a",
2948 help="Choose between Vulkan and Vulkan SC")
2949 parser.add_argument("-o",
2953 help="Choose output directory")
2954 return parser.parse_args()
2956 def preprocessTopInclude(src, dir):
2957 pattern = r'#include\s+"([^\n]+)"'
2959 inc = re.search(pattern, src)
2962 incFileName = inc.string[inc.start(1):inc.end(1)]
2963 patternIncNamed = r'#include\s+"' + incFileName + '"'
2964 incBody = readFile(os.path.join(dir, incFileName)) if incFileName != 'vk_platform.h' else ''
2965 incBodySanitized = re.sub(pattern, '', incBody)
2966 bodyEndSanitized = re.sub(patternIncNamed, '', src[inc.end(0):])
2967 src = src[0:inc.start(0)] + incBodySanitized + bodyEndSanitized
2970 if __name__ == "__main__":
2971 args = parseCmdLineArgs()
2973 outputPath = DEFAULT_OUTPUT_DIR[args.api]
2974 # if argument was specified it is interpreted as a path to which .inl files will be written
2975 if args.outdir != '':
2976 outputPath = args.outdir
2982 # Generate vulkan headers from vk.xml
2983 currentDir = os.getcwd()
2984 pythonExecutable = sys.executable or "python"
2985 os.chdir(os.path.join(VULKAN_HEADERS_INCLUDE_DIR, "..", "xml"))
3000 "vulkan_xlib_xrandr.h",
3002 for target in vkTargets:
3003 execute([pythonExecutable, "../scripts/genvk.py", "-o", "../include/vulkan", target])
3005 videoDir = "../include/vk_video"
3006 if (not os.path.isdir(videoDir)):
3010 'vulkan_video_codecs_common.h',
3011 'vulkan_video_codec_h264std.h',
3012 'vulkan_video_codec_h264std_decode.h',
3013 'vulkan_video_codec_h264std_encode.h',
3014 'vulkan_video_codec_h265std.h',
3015 'vulkan_video_codec_h265std_decode.h',
3016 'vulkan_video_codec_h265std_encode.h',
3018 for target in videoTargets:
3019 execute([pythonExecutable, "../scripts/genvk.py", "-registry", "video.xml", "-o", videoDir, target])
3021 os.chdir(currentDir)
3023 # Read all .h files and make sure vulkan_core.h is first out of vulkan files
3024 vkTargets.remove("vulkan_core.h")
3026 vkTargets.insert(0, "vulkan_core.h")
3027 vkFilesWithCatalog = [os.path.join("vulkan", f) for f in vkTargets]
3029 for file in vkFilesWithCatalog:
3030 src += preprocessTopInclude(readFile(os.path.join(VULKAN_HEADERS_INCLUDE_DIR,file)), VULKAN_HEADERS_INCLUDE_DIR)
3031 elif args.api=='SC':
3032 # At the moment vulkan-docs does not have vulkan_sc_core.h. We will use a file from external/vulkancts/scripts/src
3033 src = preprocessTopInclude(readFile(os.path.join(os.path.dirname(__file__), "src", "vulkan_sc_core.h" )), VULKAN_HEADERS_INCLUDE_DIR)
3035 src = re.sub('\s*//[^\n]*', '', src)
3036 src = re.sub('\n\n', '\n', src)
3040 platformFuncs = [Function.TYPE_PLATFORM]
3041 instanceFuncs = [Function.TYPE_INSTANCE]
3042 deviceFuncs = [Function.TYPE_DEVICE]
3044 dfd = generateDeviceFeaturesDefs(args.api, src)
3045 writeDeviceFeatures (api, dfd, os.path.join(outputPath, "vkDeviceFeatures.inl"))
3046 writeDeviceFeaturesDefaultDeviceDefs (dfd, os.path.join(outputPath, "vkDeviceFeaturesForDefaultDeviceDefs.inl"))
3047 writeDeviceFeaturesContextDecl (dfd, os.path.join(outputPath, "vkDeviceFeaturesForContextDecl.inl"))
3048 writeDeviceFeaturesContextDefs (dfd, os.path.join(outputPath, "vkDeviceFeaturesForContextDefs.inl"))
3049 writeDeviceFeatureTest (args.api, api, os.path.join(outputPath, "vkDeviceFeatureTest.inl"))
3051 dpd = generateDevicePropertiesDefs(args.api, src)
3052 writeDeviceProperties (api, dpd, os.path.join(outputPath, "vkDeviceProperties.inl"))
3054 writeDevicePropertiesDefaultDeviceDefs (dpd, os.path.join(outputPath, "vkDevicePropertiesForDefaultDeviceDefs.inl"))
3055 writeDevicePropertiesContextDecl (dpd, os.path.join(outputPath, "vkDevicePropertiesForContextDecl.inl"))
3056 writeDevicePropertiesContextDefs (dpd, os.path.join(outputPath, "vkDevicePropertiesForContextDefs.inl"))
3058 writeHandleType (api, os.path.join(outputPath, "vkHandleType.inl"))
3059 writeBasicTypes (args.api, api, os.path.join(outputPath, "vkBasicTypes.inl"))
3060 writeCompositeTypes (api, os.path.join(outputPath, "vkStructTypes.inl"))
3061 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualPlatformInterface.inl"), platformFuncs, False)
3062 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualInstanceInterface.inl"), instanceFuncs, False)
3063 writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualDeviceInterface.inl"), deviceFuncs, False)
3064 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcretePlatformInterface.inl"), platformFuncs, True)
3065 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcreteInstanceInterface.inl"), instanceFuncs, True)
3066 writeInterfaceDecl (api, os.path.join(outputPath, "vkConcreteDeviceInterface.inl"), deviceFuncs, True)
3067 writeFunctionPtrTypes (api, os.path.join(outputPath, "vkFunctionPointerTypes.inl"))
3068 writeFunctionPointers (api, os.path.join(outputPath, "vkPlatformFunctionPointers.inl"), platformFuncs)
3069 writeFunctionPointers (api, os.path.join(outputPath, "vkInstanceFunctionPointers.inl"), instanceFuncs)
3070 writeFunctionPointers (api, os.path.join(outputPath, "vkDeviceFunctionPointers.inl"), deviceFuncs)
3071 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitPlatformFunctionPointers.inl"), platformFuncs, lambda f: f.name != "vkGetInstanceProcAddr")
3072 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitInstanceFunctionPointers.inl"), instanceFuncs)
3073 writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitDeviceFunctionPointers.inl"), deviceFuncs)
3074 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkPlatformDriverImpl.inl"), platformFuncs, "PlatformDriver")
3075 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkInstanceDriverImpl.inl"), instanceFuncs, "InstanceDriver")
3076 writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkDeviceDriverImpl.inl"), deviceFuncs, "DeviceDriver")
3078 writeFuncPtrInterfaceSCImpl (api, os.path.join(outputPath, "vkDeviceDriverSCImpl.inl"), deviceFuncs, "DeviceDriverSC")
3079 writeStrUtilProto (api, os.path.join(outputPath, "vkStrUtil.inl"))
3080 writeStrUtilImpl (api, os.path.join(outputPath, "vkStrUtilImpl.inl"))
3081 writeRefUtilProto (api, os.path.join(outputPath, "vkRefUtil.inl"))
3082 writeRefUtilImpl (api, os.path.join(outputPath, "vkRefUtilImpl.inl"))
3083 writeStructTraitsImpl (api, os.path.join(outputPath, "vkGetStructureTypeImpl.inl"))
3084 writeNullDriverImpl (api, os.path.join(outputPath, "vkNullDriverImpl.inl"))
3085 writeTypeUtil (api, os.path.join(outputPath, "vkTypeUtil.inl"))
3086 writeSupportedExtensions (args.api, api, os.path.join(outputPath, "vkSupportedExtensions.inl"))
3087 writeCoreFunctionalities (api, os.path.join(outputPath, "vkCoreFunctionalities.inl"))
3088 writeExtensionFunctions (api, os.path.join(outputPath, "vkExtensionFunctions.inl"))
3089 writeDeviceFeatures2 (api, os.path.join(outputPath, "vkDeviceFeatures2.inl"))
3090 writeMandatoryFeatures (api, os.path.join(outputPath, "vkMandatoryFeatures.inl"))
3091 writeExtensionList (args.api, api, os.path.join(outputPath, "vkInstanceExtensions.inl"), 'instance')
3092 writeExtensionList (args.api, api, os.path.join(outputPath, "vkDeviceExtensions.inl"), 'device')
3093 writeDriverIds (args.api, os.path.join(outputPath, "vkKnownDriverIds.inl"))
3094 writeObjTypeImpl (api, os.path.join(outputPath, "vkObjTypeImpl.inl"))
3095 # NOTE: when new files are generated then they should also be added to the
3096 # vk-gl-cts\external\vulkancts\framework\vulkan\CMakeLists.txt outputs list