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 #-------------------------------------------------------------------------
27 sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts"))
29 from build.common import DEQP_DIR
30 from khr_util.format import indentLines, writeInlFile
32 VULKAN_DIR = os.path.join(os.path.dirname(__file__), "framework", "vulkan")
35 /* WARNING: This is auto-generated file. Do not modify, since changes will
36 * be lost! Modify the generating script instead.
40 PLATFORM_FUNCTIONS = [
42 "vkGetInstanceProcAddr",
43 "vkEnumerateInstanceExtensionProperties",
44 "vkEnumerateInstanceLayerProperties",
46 INSTANCE_FUNCTIONS = [
48 "vkEnumeratePhysicalDevices",
49 "vkGetPhysicalDeviceFeatures",
50 "vkGetPhysicalDeviceFormatProperties",
51 "vkGetPhysicalDeviceImageFormatProperties",
52 "vkGetPhysicalDeviceLimits",
53 "vkGetPhysicalDeviceProperties",
54 "vkGetPhysicalDeviceQueueFamilyProperties",
55 "vkGetPhysicalDeviceMemoryProperties",
56 "vkEnumerateDeviceExtensionProperties",
57 "vkEnumerateDeviceLayerProperties",
59 "vkGetDeviceProcAddr",
60 "vkCreateDebugReportCallbackEXT",
61 "vkDestroyDebugReportCallbackEXT",
62 "vkDebugReportMessageEXT",
67 "VK_MAX_PHYSICAL_DEVICE_NAME_SIZE",
68 "VK_MAX_EXTENSION_NAME_SIZE",
70 "VK_MAX_MEMORY_TYPES",
71 "VK_MAX_MEMORY_HEAPS",
72 "VK_MAX_DESCRIPTION_SIZE",
73 "VK_ATTACHMENT_UNUSED",
80 def __init__ (self, type, name):
84 def getHandleType (self):
85 name = re.sub(r'([a-z])([A-Z])', r'\1_\2', self.name)
86 return "HANDLE_TYPE_" + name[3:].upper()
89 def __init__ (self, name, values):
94 def __init__ (self, name, values):
99 def __init__ (self, type, name, arraySize = None):
102 self.arraySize = arraySize
108 def __init__ (self, typeClass, name, members):
109 self.typeClass = typeClass
111 self.members = members
113 def getClassName (self):
114 names = {CompositeType.CLASS_STRUCT: 'struct', CompositeType.CLASS_UNION: 'union'}
115 return names[self.typeClass]
118 TYPE_PLATFORM = 0 # Not bound to anything
119 TYPE_INSTANCE = 1 # Bound to VkInstance
120 TYPE_DEVICE = 2 # Bound to VkDevice
122 def __init__ (self, name, returnType, arguments):
124 self.returnType = returnType
125 self.arguments = arguments
128 if self.name in PLATFORM_FUNCTIONS:
129 return Function.TYPE_PLATFORM
130 elif self.name in INSTANCE_FUNCTIONS:
131 return Function.TYPE_INSTANCE
133 return Function.TYPE_DEVICE
136 def __init__ (self, definitions, handles, enums, bitfields, compositeTypes, functions):
137 self.definitions = definitions
138 self.handles = handles
140 self.bitfields = bitfields
141 self.compositeTypes = compositeTypes
142 self.functions = functions
144 def readFile (filename):
145 with open(filename, 'rb') as f:
148 IDENT_PTRN = r'[a-zA-Z_][a-zA-Z0-9_]*'
149 TYPE_PTRN = r'[a-zA-Z_][a-zA-Z0-9_ \t*]*'
151 def endswith (s, postfix):
152 return len(s) >= len(postfix) and s[len(s)-len(postfix):] == postfix
154 def fixupEnumValues (values):
156 for name, value in values:
157 if endswith(name, "_BEGIN_RANGE") or endswith(name, "_END_RANGE"):
159 fixed.append((name, value))
162 def fixupType (type):
164 ("uint8_t", "deUint8"),
165 ("uint16_t", "deUint16"),
166 ("uint32_t", "deUint32"),
167 ("uint64_t", "deUint64"),
168 ("int8_t", "deInt8"),
169 ("int16_t", "deInt16"),
170 ("int32_t", "deInt32"),
171 ("int64_t", "deInt64"),
172 ("bool32_t", "deUint32"),
173 ("size_t", "deUintptr"),
176 for src, dst in replacements:
177 type = type.replace(src, dst)
181 def fixupFunction (function):
182 fixedArgs = [Variable(fixupType(a.type), a.name, a.arraySize) for a in function.arguments]
183 fixedReturnType = fixupType(function.returnType)
185 return Function(function.name, fixedReturnType, fixedArgs)
187 def getInterfaceName (function):
188 assert function.name[:2] == "vk"
189 return function.name[2].lower() + function.name[3:]
191 def getFunctionTypeName (function):
192 assert function.name[:2] == "vk"
193 return function.name[2:] + "Func"
195 def endsWith (str, postfix):
196 return str[-len(postfix):] == postfix
198 def splitNameExtPostfix (name):
199 knownExtPostfixes = ["KHR", "EXT"]
200 for postfix in knownExtPostfixes:
201 if endsWith(name, postfix):
202 return (name[:-len(postfix)], postfix)
205 def getBitEnumNameForBitfield (bitfieldName):
206 bitfieldName, postfix = splitNameExtPostfix(bitfieldName)
208 assert bitfieldName[-1] == "s"
209 return bitfieldName[:-1] + "Bits" + postfix
211 def getBitfieldNameForBitEnum (bitEnumName):
212 bitEnumName, postfix = splitNameExtPostfix(bitEnumName)
214 assert bitEnumName[-4:] == "Bits"
215 return bitEnumName[:-4] + "s" + postfix
217 def parsePreprocDefinedValue (src, name):
218 definition = re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src)
219 if definition is None:
220 raise Exception("No such definition: %s" % name)
221 value = definition.group(1).strip()
223 if value == "UINT32_MAX":
228 def parseEnum (name, src):
229 keyValuePtrn = '(' + IDENT_PTRN + r')\s*=\s*([^\s,}]+)\s*[,}]'
230 matches = re.findall(keyValuePtrn, src)
232 return Enum(name, fixupEnumValues(matches))
234 # \note Parses raw enums, some are mapped to bitfields later
235 def parseEnums (src):
236 matches = re.findall(r'typedef enum(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
239 for enumname, contents, typename in matches:
240 enums.append(parseEnum(typename, contents))
244 def parseCompositeType (type, name, src):
245 # \todo [pyry] Array support is currently a hack (size coupled with name)
246 typeNamePtrn = r'(' + TYPE_PTRN + ')(\s' + IDENT_PTRN + r'(\[[^\]]+\])*)\s*;'
247 matches = re.findall(typeNamePtrn, src)
248 members = [Variable(fixupType(t.strip()), n.strip()) for t, n, a in matches]
250 return CompositeType(type, name, members)
252 def parseCompositeTypes (src):
253 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
254 matches = re.findall(r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
257 for type, structname, contents, typename in matches:
258 if typename[-3:] == "KHR":
259 continue # \todo [2016-01-05 pyry] Figure out how to handle platform-specific types
261 types.append(parseCompositeType(typeMap[type], typename, contents))
265 def parseHandles (src):
266 matches = re.findall(r'VK_DEFINE(_NON_DISPATCHABLE|)_HANDLE\((' + IDENT_PTRN + r')\)[ \t]*[\n\r]', src)
268 typeMap = {'': Handle.TYPE_DISP, '_NON_DISPATCHABLE': Handle.TYPE_NONDISP}
270 for type, name in matches:
271 handle = Handle(typeMap[type], name)
272 handles.append(handle)
276 def parseArgList (src):
277 typeNamePtrn = r'(' + TYPE_PTRN + ')(\s' + IDENT_PTRN + r')(\[[^\]]+\])?'
280 for rawArg in src.split(','):
281 m = re.search(typeNamePtrn, rawArg)
282 args.append(Variable(m.group(1).strip(), m.group(2).strip(), m.group(3)))
286 def parseFunctions (src):
287 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
288 matches = re.findall(ptrn, src)
291 for returnType, name, argList in matches:
292 if name[-3:] == "KHR":
293 continue # \todo [2015-11-16 pyry] Figure out how to handle platform-specific extension functions
295 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList)))
297 return [fixupFunction(f) for f in functions]
299 def parseBitfieldNames (src):
300 ptrn = r'typedef\s+VkFlags\s(' + IDENT_PTRN + r')\s*;'
301 matches = re.findall(ptrn, src)
306 definitions = [(name, parsePreprocDefinedValue(src, name)) for name in DEFINITIONS]
307 rawEnums = parseEnums(src)
308 bitfieldNames = parseBitfieldNames(src)
311 bitfieldEnums = set([getBitEnumNameForBitfield(n) for n in bitfieldNames])
313 for enum in rawEnums:
314 if enum.name in bitfieldEnums:
315 bitfields.append(Bitfield(getBitfieldNameForBitEnum(enum.name), enum.values))
319 for bitfieldName in bitfieldNames:
320 if not bitfieldName in [bitfield.name for bitfield in bitfields]:
322 bitfields.append(Bitfield(bitfieldName, []))
325 definitions = definitions,
326 handles = parseHandles(src),
328 bitfields = bitfields,
329 compositeTypes = parseCompositeTypes(src),
330 functions = parseFunctions(src))
332 def writeHandleType (api, filename):
334 yield "enum HandleType"
336 yield "\t%s = 0," % api.handles[0].getHandleType()
337 for handle in api.handles[1:]:
338 yield "\t%s," % handle.getHandleType()
339 yield "\tHANDLE_TYPE_LAST"
343 writeInlFile(filename, INL_HEADER, gen())
345 def getEnumValuePrefix (enum):
346 prefix = enum.name[0]
347 for i in range(1, len(enum.name)):
348 if enum.name[i].isupper():
350 prefix += enum.name[i].upper()
353 def parseInt (value):
354 if value[:2] == "0x":
355 return int(value, 16)
357 return int(value, 10)
359 def areEnumValuesLinear (enum):
361 for name, value in enum.values:
362 if parseInt(value) != curIndex:
367 def genEnumSrc (enum):
368 yield "enum %s" % enum.name
371 for line in indentLines(["\t%s\t= %s," % v for v in enum.values]):
374 if areEnumValuesLinear(enum):
376 yield "\t%s_LAST" % getEnumValuePrefix(enum)
380 def genBitfieldSrc (bitfield):
381 if len(bitfield.values) > 0:
382 yield "enum %s" % getBitEnumNameForBitfield(bitfield.name)
384 for line in indentLines(["\t%s\t= %s," % v for v in bitfield.values]):
388 yield "typedef deUint32 %s;" % bitfield.name
390 def genCompositeTypeSrc (type):
391 yield "%s %s" % (type.getClassName(), type.name)
393 for line in indentLines(["\t%s\t%s;" % (m.type, m.name) for m in type.members]):
397 def genHandlesSrc (handles):
398 def genLines (handles):
399 for handle in handles:
400 if handle.type == Handle.TYPE_DISP:
401 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
402 elif handle.type == Handle.TYPE_NONDISP:
403 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
405 for line in indentLines(genLines(handles)):
408 def writeBasicTypes (api, filename):
410 for line in indentLines(["enum { %s\t= %s\t};" % define for define in api.definitions]):
413 for line in genHandlesSrc(api.handles):
416 for enum in api.enums:
417 for line in genEnumSrc(enum):
420 for bitfield in api.bitfields:
421 for line in genBitfieldSrc(bitfield):
425 writeInlFile(filename, INL_HEADER, gen())
427 def writeCompositeTypes (api, filename):
429 for type in api.compositeTypes:
430 for line in genCompositeTypeSrc(type):
434 writeInlFile(filename, INL_HEADER, gen())
436 def argListToStr (args):
437 return ", ".join("%s %s%s" % (v.type, v.name, v.arraySize if v.arraySize != None else "") for v in args)
439 def writeInterfaceDecl (api, filename, functionTypes, concrete):
441 postfix = "" if concrete else " = 0"
442 for function in api.functions:
443 if function.getType() in functionTypes:
444 yield "virtual %s\t%s\t(%s) const%s;" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments), postfix)
446 writeInlFile(filename, INL_HEADER, indentLines(genProtos()))
448 def writeFunctionPtrTypes (api, filename):
450 for function in api.functions:
451 yield "typedef VKAPI_ATTR %s\t(VKAPI_CALL* %s)\t(%s);" % (function.returnType, getFunctionTypeName(function), argListToStr(function.arguments))
453 writeInlFile(filename, INL_HEADER, indentLines(genTypes()))
455 def writeFunctionPointers (api, filename, functionTypes):
456 writeInlFile(filename, INL_HEADER, indentLines(["%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function)) for function in api.functions if function.getType() in functionTypes]))
458 def writeInitFunctionPointers (api, filename, functionTypes):
459 def makeInitFunctionPointers ():
460 for function in api.functions:
461 if function.getType() in functionTypes:
462 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
464 writeInlFile(filename, INL_HEADER, indentLines(makeInitFunctionPointers()))
466 def writeFuncPtrInterfaceImpl (api, filename, functionTypes, className):
467 def makeFuncPtrInterfaceImpl ():
468 for function in api.functions:
469 if function.getType() in functionTypes:
471 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments))
473 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
476 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceImpl())
478 def writeStrUtilProto (api, filename):
479 def makeStrUtilProto ():
480 for line in indentLines(["const char*\tget%sName\t(%s value);" % (enum.name[2:], enum.name) for enum in api.enums]):
483 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]):
486 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]):
489 for line in indentLines(["tcu::Format::Bitfield<32>\tget%sStr\t(%s value);" % (bitfield.name[2:], bitfield.name) for bitfield in api.bitfields]):
492 for line in indentLines(["std::ostream&\toperator<<\t(std::ostream& s, const %s& value);" % (s.name) for s in api.compositeTypes]):
495 writeInlFile(filename, INL_HEADER, makeStrUtilProto())
497 def writeStrUtilImpl (api, filename):
498 def makeStrUtilImpl ():
499 for line in indentLines(["template<> const char*\tgetTypeName<%s>\t(void) { return \"%s\";\t}" % (handle.name, handle.name) for handle in api.handles]):
502 for enum in api.enums:
504 yield "const char* get%sName (%s value)" % (enum.name[2:], enum.name)
506 yield "\tswitch (value)"
508 for line in indentLines(["\t\tcase %s:\treturn \"%s\";" % (n, n) for n, v in enum.values] + ["\t\tdefault:\treturn DE_NULL;"]):
513 for bitfield in api.bitfields:
515 yield "tcu::Format::Bitfield<32> get%sStr (%s value)" % (bitfield.name[2:], bitfield.name)
518 if len(bitfield.values) > 0:
519 yield "\tstatic const tcu::Format::BitDesc s_desc[] ="
521 for line in indentLines(["\t\ttcu::Format::BitDesc(%s,\t\"%s\")," % (n, n) for n, v in bitfield.values]):
524 yield "\treturn tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));"
526 yield "\treturn tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL);"
530 bitfieldTypeNames = set([bitfield.name for bitfield in api.bitfields])
532 for type in api.compositeTypes:
534 yield "std::ostream& operator<< (std::ostream& s, const %s& value)" % type.name
536 yield "\ts << \"%s = {\\n\";" % type.name
537 for member in type.members:
538 memberName = member.name
541 if member.type in bitfieldTypeNames:
542 valFmt = "get%sStr(value.%s)" % (member.type[2:], member.name)
543 elif member.type == "const char*" or member.type == "char*":
544 valFmt = "getCharPtrStr(value.%s)" % member.name
545 elif '[' in member.name:
546 baseName = member.name[:member.name.find('[')]
547 if baseName in ["extensionName", "deviceName", "layerName", "description"]:
548 valFmt = "(const char*)value.%s" % baseName
549 elif member.type == 'char' or member.type == 'deUint8':
550 newLine = "'\\n' << "
551 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)
553 if baseName == "memoryTypes" or baseName == "memoryHeaps":
554 endIter = "DE_ARRAY_BEGIN(value.%s) + value.%sCount" % (baseName, baseName[:-1])
556 endIter = "DE_ARRAY_END(value.%s)" % baseName
557 newLine = "'\\n' << "
558 valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), %s)" % (baseName, endIter)
559 memberName = baseName
561 valFmt = "value.%s" % member.name
562 yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';"
568 writeInlFile(filename, INL_HEADER, makeStrUtilImpl())
570 class ConstructorFunction:
571 def __init__ (self, type, name, objectType, iface, arguments):
574 self.objectType = objectType
576 self.arguments = arguments
578 def getConstructorFunctions (api):
580 for function in api.functions:
581 if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "count" in [a.name for a in function.arguments]:
582 # \todo [pyry] Rather hacky
584 if function.getType() == Function.TYPE_PLATFORM:
585 iface = Variable("const PlatformInterface&", "vk")
586 elif function.getType() == Function.TYPE_INSTANCE:
587 iface = Variable("const InstanceInterface&", "vk")
589 iface = Variable("const DeviceInterface&", "vk")
591 assert function.arguments[-2].type == "const VkAllocationCallbacks*"
593 objectType = function.arguments[-1].type.replace("*", "").strip()
594 arguments = function.arguments[:-1]
595 funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function), objectType, iface, arguments))
598 def writeRefUtilProto (api, filename):
599 functions = getConstructorFunctions(api)
601 def makeRefUtilProto ():
603 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]):
606 writeInlFile(filename, INL_HEADER, makeRefUtilProto())
608 def writeRefUtilImpl (api, filename):
609 functions = getConstructorFunctions(api)
611 def makeRefUtilImpl ():
612 yield "namespace refdetails"
616 for function in api.functions:
617 if function.getType() == Function.TYPE_DEVICE \
618 and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \
619 and not function.name == "vkDestroyDevice":
620 objectType = function.arguments[-2].type
622 yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType)
624 yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function))
628 yield "} // refdetails"
631 for function in functions:
632 if function.type == Function.TYPE_DEVICE:
634 elif function.type == Function.TYPE_INSTANCE:
635 if function.name == "createDevice":
642 yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr([function.iface] + function.arguments))
644 yield "\t%s object = 0;" % function.objectType
645 yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"]))
646 yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, ", ".join(["vk", dtorObj, function.arguments[-1].name]))
650 writeInlFile(filename, INL_HEADER, makeRefUtilImpl())
652 def writeNullDriverImpl (api, filename):
653 def genNullDriverImpl ():
655 "vkCreateGraphicsPipelines",
656 "vkCreateComputePipelines",
657 "vkGetInstanceProcAddr",
658 "vkGetDeviceProcAddr",
659 "vkEnumeratePhysicalDevices",
660 "vkGetPhysicalDeviceProperties",
661 "vkGetPhysicalDeviceQueueFamilyProperties",
662 "vkGetPhysicalDeviceMemoryProperties",
663 "vkGetPhysicalDeviceFormatProperties",
664 "vkGetBufferMemoryRequirements",
665 "vkGetImageMemoryRequirements",
667 "vkAllocateDescriptorSets",
668 "vkFreeDescriptorSets",
669 "vkResetDescriptorPool",
670 "vkAllocateCommandBuffers",
671 "vkFreeCommandBuffers"
673 specialFuncs = [f for f in api.functions if f.name in specialFuncNames]
674 createFuncs = [f for f in api.functions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs]
675 destroyFuncs = [f for f in api.functions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs]
676 dummyFuncs = [f for f in api.functions if f not in specialFuncs + createFuncs + destroyFuncs]
678 def getHandle (name):
679 for handle in api.handles:
680 if handle.name == name:
682 raise Exception("No such handle: %s" % name)
684 for function in createFuncs:
685 objectType = function.arguments[-1].type.replace("*", "").strip()
686 argsStr = ", ".join([a.name for a in function.arguments[:-1]])
688 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
690 yield "\tDE_UNREF(%s);" % function.arguments[-2].name
692 if getHandle(objectType).type == Handle.TYPE_NONDISP:
693 yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr)
695 yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr)
700 for function in destroyFuncs:
701 objectArg = function.arguments[-2]
703 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
705 for arg in function.arguments[:-2]:
706 yield "\tDE_UNREF(%s);" % arg.name
708 if getHandle(objectArg.type).type == Handle.TYPE_NONDISP:
709 yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name)
711 yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name)
716 for function in dummyFuncs:
717 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
719 for arg in function.arguments:
720 yield "\tDE_UNREF(%s);" % arg.name
721 if function.returnType != "void":
722 yield "\treturn VK_SUCCESS;"
726 def genFuncEntryTable (type, name):
727 funcs = [f for f in api.functions if f.getType() == type]
729 yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name
731 for line in indentLines(["\tVK_NULL_FUNC_ENTRY(%s,\t%s)," % (function.name, getInterfaceName(function)) for function in funcs]):
737 for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"):
740 for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"):
743 for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"):
747 writeInlFile(filename, INL_HEADER, genNullDriverImpl())
749 def writeTypeUtil (api, filename):
750 # Structs filled by API queries are not often used in test code
751 QUERY_RESULT_TYPES = set([
752 "VkPhysicalDeviceFeatures",
753 "VkPhysicalDeviceLimits",
754 "VkFormatProperties",
755 "VkImageFormatProperties",
756 "VkPhysicalDeviceSparseProperties",
757 "VkQueueFamilyProperties",
761 COMPOSITE_TYPES = set([t.name for t in api.compositeTypes])
763 def isSimpleStruct (type):
764 def hasArrayMember (type):
765 for member in type.members:
766 if "[" in member.name:
770 def hasCompositeMember (type):
771 for member in type.members:
772 if member.type in COMPOSITE_TYPES:
776 return type.typeClass == CompositeType.CLASS_STRUCT and \
777 type.members[0].type != "VkStructureType" and \
778 not type.name in QUERY_RESULT_TYPES and \
779 not hasArrayMember(type) and \
780 not hasCompositeMember(type)
783 for type in api.compositeTypes:
784 if not isSimpleStruct(type):
788 yield "inline %s make%s (%s)" % (type.name, type.name[2:], argListToStr(type.members))
790 yield "\t%s res;" % type.name
791 for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]):
793 yield "\treturn res;"
796 writeInlFile(filename, INL_HEADER, gen())
798 if __name__ == "__main__":
799 src = readFile(sys.argv[1])
801 platformFuncs = set([Function.TYPE_PLATFORM])
802 instanceFuncs = set([Function.TYPE_INSTANCE])
803 deviceFuncs = set([Function.TYPE_DEVICE])
805 writeHandleType (api, os.path.join(VULKAN_DIR, "vkHandleType.inl"))
806 writeBasicTypes (api, os.path.join(VULKAN_DIR, "vkBasicTypes.inl"))
807 writeCompositeTypes (api, os.path.join(VULKAN_DIR, "vkStructTypes.inl"))
808 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualPlatformInterface.inl"), functionTypes = platformFuncs, concrete = False)
809 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualInstanceInterface.inl"), functionTypes = instanceFuncs, concrete = False)
810 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualDeviceInterface.inl"), functionTypes = deviceFuncs, concrete = False)
811 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcretePlatformInterface.inl"), functionTypes = platformFuncs, concrete = True)
812 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteInstanceInterface.inl"), functionTypes = instanceFuncs, concrete = True)
813 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteDeviceInterface.inl"), functionTypes = deviceFuncs, concrete = True)
814 writeFunctionPtrTypes (api, os.path.join(VULKAN_DIR, "vkFunctionPointerTypes.inl"))
815 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkPlatformFunctionPointers.inl"), functionTypes = platformFuncs)
816 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInstanceFunctionPointers.inl"), functionTypes = instanceFuncs)
817 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkDeviceFunctionPointers.inl"), functionTypes = deviceFuncs)
818 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitPlatformFunctionPointers.inl"), functionTypes = platformFuncs)
819 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitInstanceFunctionPointers.inl"), functionTypes = instanceFuncs)
820 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitDeviceFunctionPointers.inl"), functionTypes = deviceFuncs)
821 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkPlatformDriverImpl.inl"), functionTypes = platformFuncs, className = "PlatformDriver")
822 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkInstanceDriverImpl.inl"), functionTypes = instanceFuncs, className = "InstanceDriver")
823 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkDeviceDriverImpl.inl"), functionTypes = deviceFuncs, className = "DeviceDriver")
824 writeStrUtilProto (api, os.path.join(VULKAN_DIR, "vkStrUtil.inl"))
825 writeStrUtilImpl (api, os.path.join(VULKAN_DIR, "vkStrUtilImpl.inl"))
826 writeRefUtilProto (api, os.path.join(VULKAN_DIR, "vkRefUtil.inl"))
827 writeRefUtilImpl (api, os.path.join(VULKAN_DIR, "vkRefUtilImpl.inl"))
828 writeNullDriverImpl (api, os.path.join(VULKAN_DIR, "vkNullDriverImpl.inl"))
829 writeTypeUtil (api, os.path.join(VULKAN_DIR, "vkTypeUtil.inl"))