1 # -*- coding: utf-8 -*-
3 #-------------------------------------------------------------------------
7 # Copyright (c) 2015 Google Inc.
9 # Permission is hereby granted, free of charge, to any person obtaining a
10 # copy of this software and/or associated documentation files (the
11 # "Materials"), to deal in the Materials without restriction, including
12 # without limitation the rights to use, copy, modify, merge, publish,
13 # distribute, sublicense, and/or sell copies of the Materials, and to
14 # permit persons to whom the Materials are furnished to do so, subject to
15 # the following conditions:
17 # The above copyright notice(s) and this permission notice shall be
18 # included in all copies or substantial portions of the Materials.
20 # The Materials are Confidential Information as defined by the
21 # Khronos Membership Agreement until designated non-confidential by
22 # Khronos, at which point this condition clause shall be removed.
24 # THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30 # MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
32 #-------------------------------------------------------------------------
38 sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts"))
40 from build.common import DEQP_DIR
41 from khr_util.format import indentLines, writeInlFile
43 VULKAN_DIR = os.path.join(os.path.dirname(__file__), "framework", "vulkan")
46 /* WARNING: This is auto-generated file. Do not modify, since changes will
47 * be lost! Modify the generating script instead.
51 PLATFORM_FUNCTIONS = [
53 "vkGetInstanceProcAddr",
54 "vkEnumerateInstanceExtensionProperties",
55 "vkEnumerateInstanceLayerProperties",
57 INSTANCE_FUNCTIONS = [
59 "vkEnumeratePhysicalDevices",
60 "vkGetPhysicalDeviceFeatures",
61 "vkGetPhysicalDeviceFormatProperties",
62 "vkGetPhysicalDeviceImageFormatProperties",
63 "vkGetPhysicalDeviceLimits",
64 "vkGetPhysicalDeviceProperties",
65 "vkGetPhysicalDeviceQueueFamilyProperties",
66 "vkGetPhysicalDeviceMemoryProperties",
67 "vkEnumerateDeviceExtensionProperties",
68 "vkEnumerateDeviceLayerProperties",
70 "vkGetDeviceProcAddr",
75 "VK_MAX_PHYSICAL_DEVICE_NAME_SIZE",
76 "VK_MAX_EXTENSION_NAME_SIZE",
78 "VK_MAX_MEMORY_TYPES",
79 "VK_MAX_MEMORY_HEAPS",
80 "VK_MAX_DESCRIPTION_SIZE",
81 "VK_ATTACHMENT_UNUSED",
88 def __init__ (self, type, name):
92 def getHandleType (self):
93 name = re.sub(r'([a-z])([A-Z])', r'\1_\2', self.name)
94 return "HANDLE_TYPE_" + name[3:].upper()
97 def __init__ (self, name, values):
102 def __init__ (self, name, values):
107 def __init__ (self, type, name, arraySize = None):
110 self.arraySize = arraySize
116 def __init__ (self, typeClass, name, members):
117 self.typeClass = typeClass
119 self.members = members
121 def getClassName (self):
122 names = {CompositeType.CLASS_STRUCT: 'struct', CompositeType.CLASS_UNION: 'union'}
123 return names[self.typeClass]
126 TYPE_PLATFORM = 0 # Not bound to anything
127 TYPE_INSTANCE = 1 # Bound to VkInstance
128 TYPE_DEVICE = 2 # Bound to VkDevice
130 def __init__ (self, name, returnType, arguments):
132 self.returnType = returnType
133 self.arguments = arguments
136 if self.name in PLATFORM_FUNCTIONS:
137 return Function.TYPE_PLATFORM
138 elif self.name in INSTANCE_FUNCTIONS:
139 return Function.TYPE_INSTANCE
141 return Function.TYPE_DEVICE
144 def __init__ (self, definitions, handles, enums, bitfields, compositeTypes, functions):
145 self.definitions = definitions
146 self.handles = handles
148 self.bitfields = bitfields
149 self.compositeTypes = compositeTypes
150 self.functions = functions
152 def readFile (filename):
153 with open(filename, 'rb') as f:
156 IDENT_PTRN = r'[a-zA-Z_][a-zA-Z0-9_]*'
157 TYPE_PTRN = r'[a-zA-Z_][a-zA-Z0-9_ \t*]*'
159 def endswith (s, postfix):
160 return len(s) >= len(postfix) and s[len(s)-len(postfix):] == postfix
162 def fixupEnumValues (values):
164 for name, value in values:
165 if endswith(name, "_BEGIN_RANGE") or endswith(name, "_END_RANGE"):
167 fixed.append((name, value))
170 def fixupType (type):
172 ("uint8_t", "deUint8"),
173 ("uint16_t", "deUint16"),
174 ("uint32_t", "deUint32"),
175 ("uint64_t", "deUint64"),
176 ("int8_t", "deInt8"),
177 ("int16_t", "deInt16"),
178 ("int32_t", "deInt32"),
179 ("int64_t", "deInt64"),
180 ("bool32_t", "deUint32"),
181 ("size_t", "deUintptr"),
184 for src, dst in replacements:
185 type = type.replace(src, dst)
189 def fixupFunction (function):
190 fixedArgs = [Variable(fixupType(a.type), a.name, a.arraySize) for a in function.arguments]
191 fixedReturnType = fixupType(function.returnType)
193 return Function(function.name, fixedReturnType, fixedArgs)
195 def getInterfaceName (function):
196 assert function.name[:2] == "vk"
197 return function.name[2].lower() + function.name[3:]
199 def getFunctionTypeName (function):
200 assert function.name[:2] == "vk"
201 return function.name[2:] + "Func"
203 def getBitEnumNameForBitfield (bitfieldName):
204 if bitfieldName[-3:] == "KHR":
206 bitfieldName = bitfieldName[:-3]
210 assert bitfieldName[-1] == "s"
211 return bitfieldName[:-1] + "Bits" + postfix
213 def getBitfieldNameForBitEnum (bitEnumName):
214 if bitEnumName[-3:] == "KHR":
216 bitEnumName = bitEnumName[:-3]
220 assert bitEnumName[-4:] == "Bits"
221 return bitEnumName[:-4] + "s" + postfix
223 def parsePreprocDefinedValue (src, name):
224 definition = re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src)
225 if definition is None:
226 raise Exception("No such definition: %s" % name)
227 value = definition.group(1).strip()
229 if value == "UINT32_MAX":
234 def parseEnum (name, src):
235 keyValuePtrn = '(' + IDENT_PTRN + r')\s*=\s*([^\s,}]+)\s*[,}]'
236 matches = re.findall(keyValuePtrn, src)
238 return Enum(name, fixupEnumValues(matches))
240 # \note Parses raw enums, some are mapped to bitfields later
241 def parseEnums (src):
242 matches = re.findall(r'typedef enum(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
245 for enumname, contents, typename in matches:
246 enums.append(parseEnum(typename, contents))
250 def parseCompositeType (type, name, src):
251 # \todo [pyry] Array support is currently a hack (size coupled with name)
252 typeNamePtrn = r'(' + TYPE_PTRN + ')(\s' + IDENT_PTRN + r'(\[[^\]]+\])*)\s*;'
253 matches = re.findall(typeNamePtrn, src)
254 members = [Variable(fixupType(t.strip()), n.strip()) for t, n, a in matches]
256 return CompositeType(type, name, members)
258 def parseCompositeTypes (src):
259 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
260 matches = re.findall(r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
263 for type, structname, contents, typename in matches:
264 types.append(parseCompositeType(typeMap[type], typename, contents))
268 def parseHandles (src):
269 matches = re.findall(r'VK_DEFINE(_NON_DISPATCHABLE|)_HANDLE\((' + IDENT_PTRN + r')\)[ \t]*[\n\r]', src)
271 typeMap = {'': Handle.TYPE_DISP, '_NON_DISPATCHABLE': Handle.TYPE_NONDISP}
273 for type, name in matches:
274 handle = Handle(typeMap[type], name)
275 handles.append(handle)
279 def parseArgList (src):
280 typeNamePtrn = r'(' + TYPE_PTRN + ')(\s' + IDENT_PTRN + r')(\[[^\]]+\])?'
283 for rawArg in src.split(','):
284 m = re.search(typeNamePtrn, rawArg)
285 args.append(Variable(m.group(1).strip(), m.group(2).strip(), m.group(3)))
289 def parseFunctions (src):
290 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
291 matches = re.findall(ptrn, src)
294 for returnType, name, argList in matches:
295 if name[-3:] == "KHR":
296 continue # \todo [2015-11-16 pyry] Figure out how to handle platform-specific extension functions
298 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList)))
300 return [fixupFunction(f) for f in functions]
302 def parseBitfieldNames (src):
303 ptrn = r'typedef\s+VkFlags\s(' + IDENT_PTRN + r')\s*;'
304 matches = re.findall(ptrn, src)
309 definitions = [(name, parsePreprocDefinedValue(src, name)) for name in DEFINITIONS]
310 rawEnums = parseEnums(src)
311 bitfieldNames = parseBitfieldNames(src)
314 bitfieldEnums = set([getBitEnumNameForBitfield(n) for n in bitfieldNames])
316 for enum in rawEnums:
317 if enum.name in bitfieldEnums:
318 bitfields.append(Bitfield(getBitfieldNameForBitEnum(enum.name), enum.values))
322 for bitfieldName in bitfieldNames:
323 if not bitfieldName in [bitfield.name for bitfield in bitfields]:
325 bitfields.append(Bitfield(bitfieldName, []))
328 definitions = definitions,
329 handles = parseHandles(src),
331 bitfields = bitfields,
332 compositeTypes = parseCompositeTypes(src),
333 functions = parseFunctions(src))
335 def writeHandleType (api, filename):
337 yield "enum HandleType"
339 yield "\t%s = 0," % api.handles[0].getHandleType()
340 for handle in api.handles[1:]:
341 yield "\t%s," % handle.getHandleType()
342 yield "\tHANDLE_TYPE_LAST"
346 writeInlFile(filename, INL_HEADER, gen())
348 def getEnumValuePrefix (enum):
349 prefix = enum.name[0]
350 for i in range(1, len(enum.name)):
351 if enum.name[i].isupper():
353 prefix += enum.name[i].upper()
356 def parseInt (value):
357 if value[:2] == "0x":
358 return int(value, 16)
360 return int(value, 10)
362 def areEnumValuesLinear (enum):
364 for name, value in enum.values:
365 if parseInt(value) != curIndex:
370 def genEnumSrc (enum):
371 yield "enum %s" % enum.name
374 for line in indentLines(["\t%s\t= %s," % v for v in enum.values]):
377 if areEnumValuesLinear(enum):
379 yield "\t%s_LAST" % getEnumValuePrefix(enum)
383 def genBitfieldSrc (bitfield):
384 if len(bitfield.values) > 0:
385 yield "enum %s" % getBitEnumNameForBitfield(bitfield.name)
387 for line in indentLines(["\t%s\t= %s," % v for v in bitfield.values]):
391 yield "typedef deUint32 %s;" % bitfield.name
393 def genCompositeTypeSrc (type):
394 yield "%s %s" % (type.getClassName(), type.name)
396 for line in indentLines(["\t%s\t%s;" % (m.type, m.name) for m in type.members]):
400 def genHandlesSrc (handles):
401 def genLines (handles):
402 for handle in handles:
403 if handle.type == Handle.TYPE_DISP:
404 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
405 elif handle.type == Handle.TYPE_NONDISP:
406 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
408 for line in indentLines(genLines(handles)):
411 def writeBasicTypes (api, filename):
413 for line in indentLines(["enum { %s\t= %s\t};" % define for define in api.definitions]):
416 for line in genHandlesSrc(api.handles):
419 for enum in api.enums:
420 for line in genEnumSrc(enum):
423 for bitfield in api.bitfields:
424 for line in genBitfieldSrc(bitfield):
428 writeInlFile(filename, INL_HEADER, gen())
430 def writeCompositeTypes (api, filename):
432 for type in api.compositeTypes:
433 for line in genCompositeTypeSrc(type):
437 writeInlFile(filename, INL_HEADER, gen())
439 def argListToStr (args):
440 return ", ".join("%s %s%s" % (v.type, v.name, v.arraySize if v.arraySize != None else "") for v in args)
442 def writeInterfaceDecl (api, filename, functionTypes, concrete):
444 postfix = "" if concrete else " = 0"
445 for function in api.functions:
446 if function.getType() in functionTypes:
447 yield "virtual %s\t%s\t(%s) const%s;" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments), postfix)
449 writeInlFile(filename, INL_HEADER, indentLines(genProtos()))
451 def writeFunctionPtrTypes (api, filename):
453 for function in api.functions:
454 yield "typedef VKAPI_ATTR %s\t(VKAPI_CALL* %s)\t(%s);" % (function.returnType, getFunctionTypeName(function), argListToStr(function.arguments))
456 writeInlFile(filename, INL_HEADER, indentLines(genTypes()))
458 def writeFunctionPointers (api, filename, functionTypes):
459 writeInlFile(filename, INL_HEADER, indentLines(["%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function)) for function in api.functions if function.getType() in functionTypes]))
461 def writeInitFunctionPointers (api, filename, functionTypes):
462 def makeInitFunctionPointers ():
463 for function in api.functions:
464 if function.getType() in functionTypes:
465 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
467 writeInlFile(filename, INL_HEADER, indentLines(makeInitFunctionPointers()))
469 def writeFuncPtrInterfaceImpl (api, filename, functionTypes, className):
470 def makeFuncPtrInterfaceImpl ():
471 for function in api.functions:
472 if function.getType() in functionTypes:
474 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments))
476 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
479 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceImpl())
481 def writeStrUtilProto (api, filename):
482 def makeStrUtilProto ():
483 for line in indentLines(["const char*\tget%sName\t(%s value);" % (enum.name[2:], enum.name) for enum in api.enums]):
486 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]):
489 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]):
492 for line in indentLines(["tcu::Format::Bitfield<32>\tget%sStr\t(%s value);" % (bitfield.name[2:], bitfield.name) for bitfield in api.bitfields]):
495 for line in indentLines(["std::ostream&\toperator<<\t(std::ostream& s, const %s& value);" % (s.name) for s in api.compositeTypes]):
498 writeInlFile(filename, INL_HEADER, makeStrUtilProto())
500 def writeStrUtilImpl (api, filename):
501 def makeStrUtilImpl ():
502 for line in indentLines(["template<> const char*\tgetTypeName<%s>\t(void) { return \"%s\";\t}" % (handle.name, handle.name) for handle in api.handles]):
505 for enum in api.enums:
507 yield "const char* get%sName (%s value)" % (enum.name[2:], enum.name)
509 yield "\tswitch (value)"
511 for line in indentLines(["\t\tcase %s:\treturn \"%s\";" % (n, n) for n, v in enum.values] + ["\t\tdefault:\treturn DE_NULL;"]):
516 for bitfield in api.bitfields:
518 yield "tcu::Format::Bitfield<32> get%sStr (%s value)" % (bitfield.name[2:], bitfield.name)
521 if len(bitfield.values) > 0:
522 yield "\tstatic const tcu::Format::BitDesc s_desc[] ="
524 for line in indentLines(["\t\ttcu::Format::BitDesc(%s,\t\"%s\")," % (n, n) for n, v in bitfield.values]):
527 yield "\treturn tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));"
529 yield "\treturn tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL);"
533 bitfieldTypeNames = set([bitfield.name for bitfield in api.bitfields])
535 for type in api.compositeTypes:
537 yield "std::ostream& operator<< (std::ostream& s, const %s& value)" % type.name
539 yield "\ts << \"%s = {\\n\";" % type.name
540 for member in type.members:
541 memberName = member.name
544 if member.type in bitfieldTypeNames:
545 valFmt = "get%sStr(value.%s)" % (member.type[2:], member.name)
546 elif member.type == "const char*" or member.type == "char*":
547 valFmt = "getCharPtrStr(value.%s)" % member.name
548 elif '[' in member.name:
549 baseName = member.name[:member.name.find('[')]
550 if baseName in ["extensionName", "deviceName", "layerName", "description"]:
551 valFmt = "(const char*)value.%s" % baseName
552 elif member.type == 'char' or member.type == 'deUint8':
553 newLine = "'\\n' << "
554 valFmt = "tcu::formatArray(tcu::Format::HexIterator<%s>(DE_ARRAY_BEGIN(value.%s)), tcu::Format::HexIterator<%s>(DE_ARRAY_END(value.%s)))" % (member.type, baseName, member.type, baseName)
556 newLine = "'\\n' << "
557 valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), DE_ARRAY_END(value.%s))" % (baseName, baseName)
558 memberName = baseName
560 valFmt = "value.%s" % member.name
561 yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';"
567 writeInlFile(filename, INL_HEADER, makeStrUtilImpl())
569 class ConstructorFunction:
570 def __init__ (self, type, name, objectType, iface, arguments):
573 self.objectType = objectType
575 self.arguments = arguments
577 def getConstructorFunctions (api):
579 for function in api.functions:
580 if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "count" in [a.name for a in function.arguments]:
581 # \todo [pyry] Rather hacky
583 if function.getType() == Function.TYPE_PLATFORM:
584 iface = Variable("const PlatformInterface&", "vk")
585 elif function.getType() == Function.TYPE_INSTANCE:
586 iface = Variable("const InstanceInterface&", "vk")
588 iface = Variable("const DeviceInterface&", "vk")
590 assert function.arguments[-2].type == "const VkAllocationCallbacks*"
592 objectType = function.arguments[-1].type.replace("*", "").strip()
593 arguments = function.arguments[:-1]
594 funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function), objectType, iface, arguments))
597 def writeRefUtilProto (api, filename):
598 functions = getConstructorFunctions(api)
600 def makeRefUtilProto ():
602 for line in indentLines(["Move<%s>\t%s\t(%s = DE_NULL);" % (function.objectType, function.name, argListToStr([function.iface] + function.arguments)) for function in functions]):
605 writeInlFile(filename, INL_HEADER, makeRefUtilProto())
607 def writeRefUtilImpl (api, filename):
608 functions = getConstructorFunctions(api)
610 def makeRefUtilImpl ():
611 yield "namespace refdetails"
615 for function in api.functions:
616 if function.getType() == Function.TYPE_DEVICE \
617 and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \
618 and not function.name == "vkDestroyDevice":
619 objectType = function.arguments[-2].type
621 yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType)
623 yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function))
627 yield "} // refdetails"
630 for function in functions:
631 dtorObj = "device" if function.type == Function.TYPE_DEVICE else "object"
633 yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr([function.iface] + function.arguments))
635 yield "\t%s object = 0;" % function.objectType
636 yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"]))
637 yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, ", ".join(["vk", dtorObj, function.arguments[-1].name]))
641 writeInlFile(filename, INL_HEADER, makeRefUtilImpl())
643 def writeNullDriverImpl (api, filename):
644 def genNullDriverImpl ():
646 "vkCreateGraphicsPipelines",
647 "vkCreateComputePipelines",
648 "vkGetInstanceProcAddr",
649 "vkGetDeviceProcAddr",
650 "vkEnumeratePhysicalDevices",
651 "vkGetPhysicalDeviceProperties",
652 "vkGetPhysicalDeviceQueueFamilyProperties",
653 "vkGetPhysicalDeviceMemoryProperties",
654 "vkGetPhysicalDeviceFormatProperties",
655 "vkGetBufferMemoryRequirements",
656 "vkGetImageMemoryRequirements",
658 "vkAllocateDescriptorSets",
659 "vkFreeDescriptorSets",
660 "vkResetDescriptorPool",
661 "vkAllocateCommandBuffers",
662 "vkFreeCommandBuffers"
664 specialFuncs = [f for f in api.functions if f.name in specialFuncNames]
665 createFuncs = [f for f in api.functions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs]
666 destroyFuncs = [f for f in api.functions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs]
667 dummyFuncs = [f for f in api.functions if f not in specialFuncs + createFuncs + destroyFuncs]
669 def getHandle (name):
670 for handle in api.handles:
671 if handle.name == name:
673 raise Exception("No such handle: %s" % name)
675 for function in createFuncs:
676 objectType = function.arguments[-1].type.replace("*", "").strip()
677 argsStr = ", ".join([a.name for a in function.arguments[:-1]])
679 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
681 yield "\tDE_UNREF(%s);" % function.arguments[-2].name
683 if getHandle(objectType).type == Handle.TYPE_NONDISP:
684 yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr)
686 yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr)
691 for function in destroyFuncs:
692 objectArg = function.arguments[-2]
694 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
696 for arg in function.arguments[:-2]:
697 yield "\tDE_UNREF(%s);" % arg.name
699 if getHandle(objectArg.type).type == Handle.TYPE_NONDISP:
700 yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name)
702 yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name)
707 for function in dummyFuncs:
708 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
710 for arg in function.arguments:
711 yield "\tDE_UNREF(%s);" % arg.name
712 if function.returnType != "void":
713 yield "\treturn VK_SUCCESS;"
717 def genFuncEntryTable (type, name):
718 funcs = [f for f in api.functions if f.getType() == type]
720 yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name
722 for line in indentLines(["\tVK_NULL_FUNC_ENTRY(%s,\t%s)," % (function.name, getInterfaceName(function)) for function in funcs]):
728 for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"):
731 for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"):
734 for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"):
738 writeInlFile(filename, INL_HEADER, genNullDriverImpl())
740 def writeTypeUtil (api, filename):
741 # Structs filled by API queries are not often used in test code
742 QUERY_RESULT_TYPES = set([
743 "VkPhysicalDeviceFeatures",
744 "VkPhysicalDeviceLimits",
745 "VkFormatProperties",
746 "VkImageFormatProperties",
747 "VkPhysicalDeviceSparseProperties",
748 "VkQueueFamilyProperties",
752 COMPOSITE_TYPES = set([t.name for t in api.compositeTypes])
754 def isSimpleStruct (type):
755 def hasArrayMember (type):
756 for member in type.members:
757 if "[" in member.name:
761 def hasCompositeMember (type):
762 for member in type.members:
763 if member.type in COMPOSITE_TYPES:
767 return type.typeClass == CompositeType.CLASS_STRUCT and \
768 type.members[0].type != "VkStructureType" and \
769 not type.name in QUERY_RESULT_TYPES and \
770 not hasArrayMember(type) and \
771 not hasCompositeMember(type)
774 for type in api.compositeTypes:
775 if not isSimpleStruct(type):
779 yield "inline %s make%s (%s)" % (type.name, type.name[2:], argListToStr(type.members))
781 yield "\t%s res;" % type.name
782 for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]):
784 yield "\treturn res;"
787 writeInlFile(filename, INL_HEADER, gen())
789 if __name__ == "__main__":
790 src = readFile(sys.argv[1])
792 platformFuncs = set([Function.TYPE_PLATFORM])
793 instanceFuncs = set([Function.TYPE_INSTANCE])
794 deviceFuncs = set([Function.TYPE_DEVICE])
796 writeHandleType (api, os.path.join(VULKAN_DIR, "vkHandleType.inl"))
797 writeBasicTypes (api, os.path.join(VULKAN_DIR, "vkBasicTypes.inl"))
798 writeCompositeTypes (api, os.path.join(VULKAN_DIR, "vkStructTypes.inl"))
799 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualPlatformInterface.inl"), functionTypes = platformFuncs, concrete = False)
800 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualInstanceInterface.inl"), functionTypes = instanceFuncs, concrete = False)
801 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualDeviceInterface.inl"), functionTypes = deviceFuncs, concrete = False)
802 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcretePlatformInterface.inl"), functionTypes = platformFuncs, concrete = True)
803 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteInstanceInterface.inl"), functionTypes = instanceFuncs, concrete = True)
804 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteDeviceInterface.inl"), functionTypes = deviceFuncs, concrete = True)
805 writeFunctionPtrTypes (api, os.path.join(VULKAN_DIR, "vkFunctionPointerTypes.inl"))
806 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkPlatformFunctionPointers.inl"), functionTypes = platformFuncs)
807 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInstanceFunctionPointers.inl"), functionTypes = instanceFuncs)
808 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkDeviceFunctionPointers.inl"), functionTypes = deviceFuncs)
809 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitPlatformFunctionPointers.inl"), functionTypes = platformFuncs)
810 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitInstanceFunctionPointers.inl"), functionTypes = instanceFuncs)
811 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitDeviceFunctionPointers.inl"), functionTypes = deviceFuncs)
812 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkPlatformDriverImpl.inl"), functionTypes = platformFuncs, className = "PlatformDriver")
813 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkInstanceDriverImpl.inl"), functionTypes = instanceFuncs, className = "InstanceDriver")
814 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkDeviceDriverImpl.inl"), functionTypes = deviceFuncs, className = "DeviceDriver")
815 writeStrUtilProto (api, os.path.join(VULKAN_DIR, "vkStrUtil.inl"))
816 writeStrUtilImpl (api, os.path.join(VULKAN_DIR, "vkStrUtilImpl.inl"))
817 writeRefUtilProto (api, os.path.join(VULKAN_DIR, "vkRefUtil.inl"))
818 writeRefUtilImpl (api, os.path.join(VULKAN_DIR, "vkRefUtilImpl.inl"))
819 writeNullDriverImpl (api, os.path.join(VULKAN_DIR, "vkNullDriverImpl.inl"))
820 writeTypeUtil (api, os.path.join(VULKAN_DIR, "vkTypeUtil.inl"))