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 newLine = "'\\n' << "
554 valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), DE_ARRAY_END(value.%s))" % (baseName, baseName)
555 memberName = baseName
557 valFmt = "value.%s" % member.name
558 yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';"
564 writeInlFile(filename, INL_HEADER, makeStrUtilImpl())
566 class ConstructorFunction:
567 def __init__ (self, type, name, objectType, iface, arguments):
570 self.objectType = objectType
572 self.arguments = arguments
574 def getConstructorFunctions (api):
576 for function in api.functions:
577 if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "count" in [a.name for a in function.arguments]:
578 # \todo [pyry] Rather hacky
580 if function.getType() == Function.TYPE_PLATFORM:
581 iface = Variable("const PlatformInterface&", "vk")
582 elif function.getType() == Function.TYPE_INSTANCE:
583 iface = Variable("const InstanceInterface&", "vk")
585 iface = Variable("const DeviceInterface&", "vk")
587 assert function.arguments[-2].type == "const VkAllocationCallbacks*"
589 objectType = function.arguments[-1].type.replace("*", "").strip()
590 arguments = function.arguments[:-1]
591 funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function), objectType, iface, arguments))
594 def writeRefUtilProto (api, filename):
595 functions = getConstructorFunctions(api)
597 def makeRefUtilProto ():
599 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]):
602 writeInlFile(filename, INL_HEADER, makeRefUtilProto())
604 def writeRefUtilImpl (api, filename):
605 functions = getConstructorFunctions(api)
607 def makeRefUtilImpl ():
608 yield "namespace refdetails"
612 for function in api.functions:
613 if function.getType() == Function.TYPE_DEVICE \
614 and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \
615 and not function.name == "vkDestroyDevice":
616 objectType = function.arguments[-2].type
618 yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType)
620 yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function))
624 yield "} // refdetails"
627 for function in functions:
628 if function.type == Function.TYPE_DEVICE:
630 elif function.type == Function.TYPE_INSTANCE:
631 if function.name == "createDevice":
638 yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr([function.iface] + function.arguments))
640 yield "\t%s object = 0;" % function.objectType
641 yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"]))
642 yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, ", ".join(["vk", dtorObj, function.arguments[-1].name]))
646 writeInlFile(filename, INL_HEADER, makeRefUtilImpl())
648 def writeNullDriverImpl (api, filename):
649 def genNullDriverImpl ():
651 "vkCreateGraphicsPipelines",
652 "vkCreateComputePipelines",
653 "vkGetInstanceProcAddr",
654 "vkGetDeviceProcAddr",
655 "vkEnumeratePhysicalDevices",
656 "vkGetPhysicalDeviceProperties",
657 "vkGetPhysicalDeviceQueueFamilyProperties",
658 "vkGetPhysicalDeviceMemoryProperties",
659 "vkGetPhysicalDeviceFormatProperties",
660 "vkGetBufferMemoryRequirements",
661 "vkGetImageMemoryRequirements",
663 "vkAllocateDescriptorSets",
664 "vkFreeDescriptorSets",
665 "vkResetDescriptorPool",
666 "vkAllocateCommandBuffers",
667 "vkFreeCommandBuffers"
669 specialFuncs = [f for f in api.functions if f.name in specialFuncNames]
670 createFuncs = [f for f in api.functions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs]
671 destroyFuncs = [f for f in api.functions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs]
672 dummyFuncs = [f for f in api.functions if f not in specialFuncs + createFuncs + destroyFuncs]
674 def getHandle (name):
675 for handle in api.handles:
676 if handle.name == name:
678 raise Exception("No such handle: %s" % name)
680 for function in createFuncs:
681 objectType = function.arguments[-1].type.replace("*", "").strip()
682 argsStr = ", ".join([a.name for a in function.arguments[:-1]])
684 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
686 yield "\tDE_UNREF(%s);" % function.arguments[-2].name
688 if getHandle(objectType).type == Handle.TYPE_NONDISP:
689 yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr)
691 yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr)
696 for function in destroyFuncs:
697 objectArg = function.arguments[-2]
699 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
701 for arg in function.arguments[:-2]:
702 yield "\tDE_UNREF(%s);" % arg.name
704 if getHandle(objectArg.type).type == Handle.TYPE_NONDISP:
705 yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name)
707 yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name)
712 for function in dummyFuncs:
713 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
715 for arg in function.arguments:
716 yield "\tDE_UNREF(%s);" % arg.name
717 if function.returnType != "void":
718 yield "\treturn VK_SUCCESS;"
722 def genFuncEntryTable (type, name):
723 funcs = [f for f in api.functions if f.getType() == type]
725 yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name
727 for line in indentLines(["\tVK_NULL_FUNC_ENTRY(%s,\t%s)," % (function.name, getInterfaceName(function)) for function in funcs]):
733 for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"):
736 for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"):
739 for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"):
743 writeInlFile(filename, INL_HEADER, genNullDriverImpl())
745 def writeTypeUtil (api, filename):
746 # Structs filled by API queries are not often used in test code
747 QUERY_RESULT_TYPES = set([
748 "VkPhysicalDeviceFeatures",
749 "VkPhysicalDeviceLimits",
750 "VkFormatProperties",
751 "VkImageFormatProperties",
752 "VkPhysicalDeviceSparseProperties",
753 "VkQueueFamilyProperties",
757 COMPOSITE_TYPES = set([t.name for t in api.compositeTypes])
759 def isSimpleStruct (type):
760 def hasArrayMember (type):
761 for member in type.members:
762 if "[" in member.name:
766 def hasCompositeMember (type):
767 for member in type.members:
768 if member.type in COMPOSITE_TYPES:
772 return type.typeClass == CompositeType.CLASS_STRUCT and \
773 type.members[0].type != "VkStructureType" and \
774 not type.name in QUERY_RESULT_TYPES and \
775 not hasArrayMember(type) and \
776 not hasCompositeMember(type)
779 for type in api.compositeTypes:
780 if not isSimpleStruct(type):
784 yield "inline %s make%s (%s)" % (type.name, type.name[2:], argListToStr(type.members))
786 yield "\t%s res;" % type.name
787 for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]):
789 yield "\treturn res;"
792 writeInlFile(filename, INL_HEADER, gen())
794 if __name__ == "__main__":
795 src = readFile(sys.argv[1])
797 platformFuncs = set([Function.TYPE_PLATFORM])
798 instanceFuncs = set([Function.TYPE_INSTANCE])
799 deviceFuncs = set([Function.TYPE_DEVICE])
801 writeHandleType (api, os.path.join(VULKAN_DIR, "vkHandleType.inl"))
802 writeBasicTypes (api, os.path.join(VULKAN_DIR, "vkBasicTypes.inl"))
803 writeCompositeTypes (api, os.path.join(VULKAN_DIR, "vkStructTypes.inl"))
804 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualPlatformInterface.inl"), functionTypes = platformFuncs, concrete = False)
805 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualInstanceInterface.inl"), functionTypes = instanceFuncs, concrete = False)
806 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualDeviceInterface.inl"), functionTypes = deviceFuncs, concrete = False)
807 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcretePlatformInterface.inl"), functionTypes = platformFuncs, concrete = True)
808 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteInstanceInterface.inl"), functionTypes = instanceFuncs, concrete = True)
809 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteDeviceInterface.inl"), functionTypes = deviceFuncs, concrete = True)
810 writeFunctionPtrTypes (api, os.path.join(VULKAN_DIR, "vkFunctionPointerTypes.inl"))
811 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkPlatformFunctionPointers.inl"), functionTypes = platformFuncs)
812 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInstanceFunctionPointers.inl"), functionTypes = instanceFuncs)
813 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkDeviceFunctionPointers.inl"), functionTypes = deviceFuncs)
814 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitPlatformFunctionPointers.inl"), functionTypes = platformFuncs)
815 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitInstanceFunctionPointers.inl"), functionTypes = instanceFuncs)
816 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitDeviceFunctionPointers.inl"), functionTypes = deviceFuncs)
817 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkPlatformDriverImpl.inl"), functionTypes = platformFuncs, className = "PlatformDriver")
818 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkInstanceDriverImpl.inl"), functionTypes = instanceFuncs, className = "InstanceDriver")
819 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkDeviceDriverImpl.inl"), functionTypes = deviceFuncs, className = "DeviceDriver")
820 writeStrUtilProto (api, os.path.join(VULKAN_DIR, "vkStrUtil.inl"))
821 writeStrUtilImpl (api, os.path.join(VULKAN_DIR, "vkStrUtilImpl.inl"))
822 writeRefUtilProto (api, os.path.join(VULKAN_DIR, "vkRefUtil.inl"))
823 writeRefUtilImpl (api, os.path.join(VULKAN_DIR, "vkRefUtilImpl.inl"))
824 writeNullDriverImpl (api, os.path.join(VULKAN_DIR, "vkNullDriverImpl.inl"))
825 writeTypeUtil (api, os.path.join(VULKAN_DIR, "vkTypeUtil.inl"))