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_H = os.path.join(os.path.dirname(__file__), "src", "vulkan.h.in")
33 VULKAN_DIR = os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan")
36 /* WARNING: This is auto-generated file. Do not modify, since changes will
37 * be lost! Modify the generating script instead.
42 ("VK_API_VERSION", "deUint32"),
43 ("VK_MAX_PHYSICAL_DEVICE_NAME_SIZE", "size_t"),
44 ("VK_MAX_EXTENSION_NAME_SIZE", "size_t"),
45 ("VK_UUID_SIZE", "size_t"),
46 ("VK_LUID_SIZE_KHR", "size_t"),
47 ("VK_MAX_MEMORY_TYPES", "size_t"),
48 ("VK_MAX_MEMORY_HEAPS", "size_t"),
49 ("VK_MAX_DESCRIPTION_SIZE", "size_t"),
50 ("VK_ATTACHMENT_UNUSED", "deUint32"),
51 ("VK_SUBPASS_EXTERNAL", "deUint32"),
52 ("VK_QUEUE_FAMILY_IGNORED", "deUint32"),
53 ("VK_QUEUE_FAMILY_EXTERNAL_KHR", "deUint32"),
54 ("VK_REMAINING_MIP_LEVELS", "deUint32"),
55 ("VK_REMAINING_ARRAY_LAYERS", "deUint32"),
56 ("VK_WHOLE_SIZE", "vk::VkDeviceSize"),
57 ("VK_TRUE", "vk::VkBool32"),
58 ("VK_FALSE", "vk::VkBool32"),
63 ("Display*", "XlibDisplayPtr", "void*"),
64 ("Window", "XlibWindow", "deUintptr",),
65 ("VisualID", "XlibVisualID", "deUint32"),
68 ("xcb_connection_t*", "XcbConnectionPtr", "void*"),
69 ("xcb_window_t", "XcbWindow", "deUintptr"),
70 ("xcb_visualid_t", "XcbVisualid", "deUint32"),
72 # VK_KHR_wayland_surface
73 ("struct wl_display*", "WaylandDisplayPtr", "void*"),
74 ("struct wl_surface*", "WaylandSurfacePtr", "void*"),
77 ("MirConnection*", "MirConnectionPtr", "void*"),
78 ("MirSurface*", "MirSurfacePtr", "void*"),
80 # VK_KHR_android_surface
81 ("ANativeWindow*", "AndroidNativeWindowPtr", "void*"),
83 # VK_KHR_win32_surface
84 ("HINSTANCE", "Win32InstanceHandle", "void*"),
85 ("HWND", "Win32WindowHandle", "void*"),
86 ("HANDLE", "Win32Handle", "void*"),
87 ("const SECURITY_ATTRIBUTES*", "Win32SecurityAttributesPtr", "const void*"),
89 PLATFORM_TYPE_NAMESPACE = "pt"
90 TYPE_SUBSTITUTIONS = [
91 ("uint8_t", "deUint8"),
92 ("uint16_t", "deUint16"),
93 ("uint32_t", "deUint32"),
94 ("uint64_t", "deUint64"),
96 ("int16_t", "deInt16"),
97 ("int32_t", "deInt32"),
98 ("int64_t", "deInt64"),
99 ("bool32_t", "deUint32"),
100 ("size_t", "deUintptr"),
103 ("DWORD", "deUint32"),
104 ("HANDLE*", PLATFORM_TYPE_NAMESPACE + "::" + "Win32Handle*"),
105 ("LPCWSTR", "char*"),
108 EXTENSION_POSTFIXES = ["KHR", "EXT", "NV", "NVX", "KHX"]
114 def __init__ (self, type, name):
118 def getHandleType (self):
119 name = re.sub(r'([a-z])([A-Z])', r'\1_\2', self.name)
120 return "HANDLE_TYPE_" + name[3:].upper()
123 def __init__ (self, name, values):
128 def __init__ (self, name, values):
133 def __init__ (self, type, name, arraySize = None):
136 self.arraySize = arraySize
142 def __init__ (self, typeClass, name, members):
143 self.typeClass = typeClass
145 self.members = members
147 def getClassName (self):
148 names = {CompositeType.CLASS_STRUCT: 'struct', CompositeType.CLASS_UNION: 'union'}
149 return names[self.typeClass]
152 TYPE_PLATFORM = 0 # Not bound to anything
153 TYPE_INSTANCE = 1 # Bound to VkInstance
154 TYPE_DEVICE = 2 # Bound to VkDevice
156 def __init__ (self, name, returnType, arguments):
158 self.returnType = returnType
159 self.arguments = arguments
163 if self.name == "vkGetInstanceProcAddr":
164 return Function.TYPE_PLATFORM
165 elif self.name == "vkGetDeviceProcAddr":
166 return Function.TYPE_INSTANCE
168 assert len(self.arguments) > 0
169 firstArgType = self.arguments[0].type
171 if firstArgType in ["VkInstance", "VkPhysicalDevice"]:
172 return Function.TYPE_INSTANCE
173 elif firstArgType in ["VkDevice", "VkCommandBuffer", "VkQueue"]:
174 return Function.TYPE_DEVICE
176 return Function.TYPE_PLATFORM
179 def __init__ (self, definitions, handles, enums, bitfields, compositeTypes, functions):
180 self.definitions = definitions
181 self.handles = handles
183 self.bitfields = bitfields
184 self.compositeTypes = compositeTypes
185 self.functions = functions
187 def readFile (filename):
188 with open(filename, 'rb') as f:
191 IDENT_PTRN = r'[a-zA-Z_][a-zA-Z0-9_]*'
192 TYPE_PTRN = r'[a-zA-Z_][a-zA-Z0-9_ \t*]*'
194 def fixupEnumValues (values):
196 for name, value in values:
197 if "_BEGIN_RANGE" in name or "_END_RANGE" in name:
199 fixed.append((name, value))
202 def fixupType (type):
203 for platformType, substitute, compat in PLATFORM_TYPES:
204 if type == platformType:
205 return PLATFORM_TYPE_NAMESPACE + "::" + substitute
207 for src, dst in TYPE_SUBSTITUTIONS:
208 type = type.replace(src, dst)
212 def fixupFunction (function):
213 fixedArgs = [Variable(fixupType(a.type), a.name, a.arraySize) for a in function.arguments]
214 fixedReturnType = fixupType(function.returnType)
216 return Function(function.name, fixedReturnType, fixedArgs)
218 def getInterfaceName (function):
219 assert function.name[:2] == "vk"
220 return function.name[2].lower() + function.name[3:]
222 def getFunctionTypeName (function):
223 assert function.name[:2] == "vk"
224 return function.name[2:] + "Func"
226 def endsWith (str, postfix):
227 return str[-len(postfix):] == postfix
229 def splitNameExtPostfix (name):
230 knownExtPostfixes = EXTENSION_POSTFIXES
231 for postfix in knownExtPostfixes:
232 if endsWith(name, postfix):
233 return (name[:-len(postfix)], postfix)
236 def getBitEnumNameForBitfield (bitfieldName):
237 bitfieldName, postfix = splitNameExtPostfix(bitfieldName)
239 assert bitfieldName[-1] == "s"
240 return bitfieldName[:-1] + "Bits" + postfix
242 def getBitfieldNameForBitEnum (bitEnumName):
243 bitEnumName, postfix = splitNameExtPostfix(bitEnumName)
245 assert bitEnumName[-4:] == "Bits"
246 return bitEnumName[:-4] + "s" + postfix
248 def parsePreprocDefinedValue (src, name):
249 definition = re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src)
250 if definition is None:
251 raise Exception("No such definition: %s" % name)
252 value = definition.group(1).strip()
254 if value == "UINT32_MAX":
259 def parseEnum (name, src):
260 keyValuePtrn = '(' + IDENT_PTRN + r')\s*=\s*([^\s,}]+)\s*[,}]'
261 matches = re.findall(keyValuePtrn, src)
263 return Enum(name, fixupEnumValues(matches))
265 # \note Parses raw enums, some are mapped to bitfields later
266 def parseEnums (src):
267 matches = re.findall(r'typedef enum(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
270 for enumname, contents, typename in matches:
271 enums.append(parseEnum(typename, contents))
275 def parseCompositeType (type, name, src):
276 # \todo [pyry] Array support is currently a hack (size coupled with name)
277 typeNamePtrn = r'(' + TYPE_PTRN + ')(\s' + IDENT_PTRN + r'(\[[^\]]+\])*)\s*;'
278 matches = re.findall(typeNamePtrn, src)
279 members = [Variable(fixupType(t.strip()), n.strip()) for t, n, a in matches]
281 return CompositeType(type, name, members)
283 def parseCompositeTypes (src):
284 typeMap = { 'struct': CompositeType.CLASS_STRUCT, 'union': CompositeType.CLASS_UNION }
285 matches = re.findall(r'typedef (struct|union)(\s*' + IDENT_PTRN + r')?\s*{([^}]*)}\s*(' + IDENT_PTRN + r')\s*;', src)
288 for type, structname, contents, typename in matches:
289 types.append(parseCompositeType(typeMap[type], typename, contents))
293 def parseHandles (src):
294 matches = re.findall(r'VK_DEFINE(_NON_DISPATCHABLE|)_HANDLE\((' + IDENT_PTRN + r')\)[ \t]*[\n\r]', src)
296 typeMap = {'': Handle.TYPE_DISP, '_NON_DISPATCHABLE': Handle.TYPE_NONDISP}
298 for type, name in matches:
299 handle = Handle(typeMap[type], name)
300 handles.append(handle)
304 def parseArgList (src):
305 typeNamePtrn = r'(' + TYPE_PTRN + ')(\s' + IDENT_PTRN + r')(\[[^\]]+\])?'
308 for rawArg in src.split(','):
309 m = re.search(typeNamePtrn, rawArg)
310 args.append(Variable(m.group(1).strip(), m.group(2).strip(), m.group(3)))
314 def parseFunctions (src):
315 ptrn = r'VKAPI_ATTR\s+(' + TYPE_PTRN + ')VKAPI_CALL\s+(' + IDENT_PTRN + r')\s*\(([^)]*)\)\s*;'
316 matches = re.findall(ptrn, src)
319 for returnType, name, argList in matches:
320 functions.append(Function(name.strip(), returnType.strip(), parseArgList(argList)))
322 return [fixupFunction(f) for f in functions]
324 def parseBitfieldNames (src):
325 ptrn = r'typedef\s+VkFlags\s(' + IDENT_PTRN + r')\s*;'
326 matches = re.findall(ptrn, src)
331 definitions = [(name, type, parsePreprocDefinedValue(src, name)) for name, type in DEFINITIONS]
332 rawEnums = parseEnums(src)
333 bitfieldNames = parseBitfieldNames(src)
336 bitfieldEnums = set([getBitEnumNameForBitfield(n) for n in bitfieldNames])
338 for enum in rawEnums:
339 if enum.name in bitfieldEnums:
340 bitfields.append(Bitfield(getBitfieldNameForBitEnum(enum.name), enum.values))
344 for bitfieldName in bitfieldNames:
345 if not bitfieldName in [bitfield.name for bitfield in bitfields]:
347 bitfields.append(Bitfield(bitfieldName, []))
350 definitions = definitions,
351 handles = parseHandles(src),
353 bitfields = bitfields,
354 compositeTypes = parseCompositeTypes(src),
355 functions = parseFunctions(src))
357 def writeHandleType (api, filename):
359 yield "enum HandleType"
361 yield "\t%s = 0," % api.handles[0].getHandleType()
362 for handle in api.handles[1:]:
363 yield "\t%s," % handle.getHandleType()
364 yield "\tHANDLE_TYPE_LAST"
368 writeInlFile(filename, INL_HEADER, gen())
370 def getEnumValuePrefix (enum):
371 prefix = enum.name[0]
372 for i in range(1, len(enum.name)):
373 if enum.name[i].isupper() and not enum.name[i-1].isupper():
375 prefix += enum.name[i].upper()
378 def parseInt (value):
379 if value[:2] == "0x":
380 return int(value, 16)
382 return int(value, 10)
384 def areEnumValuesLinear (enum):
386 for name, value in enum.values:
387 if parseInt(value) != curIndex:
392 def genEnumSrc (enum):
393 yield "enum %s" % enum.name
396 for line in indentLines(["\t%s\t= %s," % v for v in enum.values]):
399 if areEnumValuesLinear(enum):
401 yield "\t%s_LAST" % getEnumValuePrefix(enum)
405 def genBitfieldSrc (bitfield):
406 if len(bitfield.values) > 0:
407 yield "enum %s" % getBitEnumNameForBitfield(bitfield.name)
409 for line in indentLines(["\t%s\t= %s," % v for v in bitfield.values]):
413 yield "typedef deUint32 %s;" % bitfield.name
415 def genCompositeTypeSrc (type):
416 yield "%s %s" % (type.getClassName(), type.name)
418 for line in indentLines(["\t%s\t%s;" % (m.type, m.name) for m in type.members]):
422 def genHandlesSrc (handles):
423 def genLines (handles):
424 for handle in handles:
425 if handle.type == Handle.TYPE_DISP:
426 yield "VK_DEFINE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
427 elif handle.type == Handle.TYPE_NONDISP:
428 yield "VK_DEFINE_NON_DISPATCHABLE_HANDLE\t(%s,\t%s);" % (handle.name, handle.getHandleType())
430 for line in indentLines(genLines(handles)):
433 def writeBasicTypes (api, filename):
435 for line in indentLines(["#define %s\t(static_cast<%s>\t(%s))" % (name, type, value) for name, type, value in api.definitions]):
438 for line in genHandlesSrc(api.handles):
441 for enum in api.enums:
442 for line in genEnumSrc(enum):
445 for bitfield in api.bitfields:
446 for line in genBitfieldSrc(bitfield):
449 for line in indentLines(["VK_DEFINE_PLATFORM_TYPE(%s,\t%s);" % (s, c) for n, s, c in PLATFORM_TYPES]):
452 writeInlFile(filename, INL_HEADER, gen())
454 def writeCompositeTypes (api, filename):
456 for type in api.compositeTypes:
457 for line in genCompositeTypeSrc(type):
461 writeInlFile(filename, INL_HEADER, gen())
463 def argListToStr (args):
464 return ", ".join("%s %s%s" % (v.type, v.name, v.arraySize if v.arraySize != None else "") for v in args)
466 def writeInterfaceDecl (api, filename, functionTypes, concrete):
468 postfix = "" if concrete else " = 0"
469 for function in api.functions:
470 if function.getType() in functionTypes:
471 yield "virtual %s\t%s\t(%s) const%s;" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments), postfix)
473 writeInlFile(filename, INL_HEADER, indentLines(genProtos()))
475 def writeFunctionPtrTypes (api, filename):
477 for function in api.functions:
478 yield "typedef VKAPI_ATTR %s\t(VKAPI_CALL* %s)\t(%s);" % (function.returnType, getFunctionTypeName(function), argListToStr(function.arguments))
480 writeInlFile(filename, INL_HEADER, indentLines(genTypes()))
482 def writeFunctionPointers (api, filename, functionTypes):
483 writeInlFile(filename, INL_HEADER, indentLines(["%s\t%s;" % (getFunctionTypeName(function), getInterfaceName(function)) for function in api.functions if function.getType() in functionTypes]))
485 def writeInitFunctionPointers (api, filename, functionTypes, cond = None):
486 def makeInitFunctionPointers ():
487 for function in api.functions:
488 if function.getType() in functionTypes and (cond == None or cond(function)):
489 yield "m_vk.%s\t= (%s)\tGET_PROC_ADDR(\"%s\");" % (getInterfaceName(function), getFunctionTypeName(function), function.name)
491 writeInlFile(filename, INL_HEADER, indentLines(makeInitFunctionPointers()))
493 def writeFuncPtrInterfaceImpl (api, filename, functionTypes, className):
494 def makeFuncPtrInterfaceImpl ():
495 for function in api.functions:
496 if function.getType() in functionTypes:
498 yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function), argListToStr(function.arguments))
500 yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function), ", ".join(a.name for a in function.arguments))
503 writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceImpl())
505 def writeStrUtilProto (api, filename):
506 def makeStrUtilProto ():
507 for line in indentLines(["const char*\tget%sName\t(%s value);" % (enum.name[2:], enum.name) for enum in api.enums]):
510 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]):
513 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]):
516 for line in indentLines(["tcu::Format::Bitfield<32>\tget%sStr\t(%s value);" % (bitfield.name[2:], bitfield.name) for bitfield in api.bitfields]):
519 for line in indentLines(["std::ostream&\toperator<<\t(std::ostream& s, const %s& value);" % (s.name) for s in api.compositeTypes]):
522 writeInlFile(filename, INL_HEADER, makeStrUtilProto())
524 def writeStrUtilImpl (api, filename):
525 def makeStrUtilImpl ():
526 for line in indentLines(["template<> const char*\tgetTypeName<%s>\t(void) { return \"%s\";\t}" % (handle.name, handle.name) for handle in api.handles]):
530 yield "namespace %s" % PLATFORM_TYPE_NAMESPACE
533 for line in indentLines("std::ostream& operator<< (std::ostream& s, %s\tv) { return s << tcu::toHex(v.internal); }" % s for n, s, c in PLATFORM_TYPES):
538 for enum in api.enums:
540 yield "const char* get%sName (%s value)" % (enum.name[2:], enum.name)
542 yield "\tswitch (value)"
544 for line in indentLines(["\t\tcase %s:\treturn \"%s\";" % (n, n) for n, v in enum.values] + ["\t\tdefault:\treturn DE_NULL;"]):
549 for bitfield in api.bitfields:
551 yield "tcu::Format::Bitfield<32> get%sStr (%s value)" % (bitfield.name[2:], bitfield.name)
554 if len(bitfield.values) > 0:
555 yield "\tstatic const tcu::Format::BitDesc s_desc[] ="
557 for line in indentLines(["\t\ttcu::Format::BitDesc(%s,\t\"%s\")," % (n, n) for n, v in bitfield.values]):
560 yield "\treturn tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));"
562 yield "\treturn tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL);"
566 bitfieldTypeNames = set([bitfield.name for bitfield in api.bitfields])
568 for type in api.compositeTypes:
570 yield "std::ostream& operator<< (std::ostream& s, const %s& value)" % type.name
572 yield "\ts << \"%s = {\\n\";" % type.name
573 for member in type.members:
574 memberName = member.name
577 if member.type in bitfieldTypeNames:
578 valFmt = "get%sStr(value.%s)" % (member.type[2:], member.name)
579 elif member.type == "const char*" or member.type == "char*":
580 valFmt = "getCharPtrStr(value.%s)" % member.name
581 elif '[' in member.name:
582 baseName = member.name[:member.name.find('[')]
583 if baseName in ["extensionName", "deviceName", "layerName", "description"]:
584 valFmt = "(const char*)value.%s" % baseName
585 elif member.type == 'char' or member.type == 'deUint8':
586 newLine = "'\\n' << "
587 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)
589 if baseName == "memoryTypes" or baseName == "memoryHeaps":
590 endIter = "DE_ARRAY_BEGIN(value.%s) + value.%sCount" % (baseName, baseName[:-1])
592 endIter = "DE_ARRAY_END(value.%s)" % baseName
593 newLine = "'\\n' << "
594 valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), %s)" % (baseName, endIter)
595 memberName = baseName
597 valFmt = "value.%s" % member.name
598 yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';"
604 writeInlFile(filename, INL_HEADER, makeStrUtilImpl())
606 class ConstructorFunction:
607 def __init__ (self, type, name, objectType, iface, arguments):
610 self.objectType = objectType
612 self.arguments = arguments
614 def getConstructorFunctions (api):
616 for function in api.functions:
617 if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "createInfoCount" in [a.name for a in function.arguments]:
618 if function.name == "vkCreateDisplayModeKHR":
619 continue # No way to delete display modes (bug?)
621 # \todo [pyry] Rather hacky
623 if function.getType() == Function.TYPE_PLATFORM:
624 iface = Variable("const PlatformInterface&", "vk")
625 elif function.getType() == Function.TYPE_INSTANCE:
626 iface = Variable("const InstanceInterface&", "vk")
628 iface = Variable("const DeviceInterface&", "vk")
630 assert function.arguments[-2].type == "const VkAllocationCallbacks*"
632 objectType = function.arguments[-1].type.replace("*", "").strip()
633 arguments = function.arguments[:-1]
634 funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function), objectType, iface, arguments))
637 def writeRefUtilProto (api, filename):
638 functions = getConstructorFunctions(api)
640 def makeRefUtilProto ():
642 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]):
645 writeInlFile(filename, INL_HEADER, makeRefUtilProto())
647 def writeRefUtilImpl (api, filename):
648 functions = getConstructorFunctions(api)
650 def makeRefUtilImpl ():
651 yield "namespace refdetails"
655 for function in api.functions:
656 if function.getType() == Function.TYPE_DEVICE \
657 and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \
658 and not function.name == "vkDestroyDevice":
659 objectType = function.arguments[-2].type
661 yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType)
663 yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function))
667 yield "} // refdetails"
670 for function in functions:
671 if function.type == Function.TYPE_DEVICE:
673 elif function.type == Function.TYPE_INSTANCE:
674 if function.name == "createDevice":
681 yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr([function.iface] + function.arguments))
683 yield "\t%s object = 0;" % function.objectType
684 yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"]))
685 yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, ", ".join(["vk", dtorObj, function.arguments[-1].name]))
689 writeInlFile(filename, INL_HEADER, makeRefUtilImpl())
691 def writeNullDriverImpl (api, filename):
692 def genNullDriverImpl ():
694 "vkCreateGraphicsPipelines",
695 "vkCreateComputePipelines",
696 "vkGetInstanceProcAddr",
697 "vkGetDeviceProcAddr",
698 "vkEnumeratePhysicalDevices",
699 "vkGetPhysicalDeviceFeatures",
700 "vkGetPhysicalDeviceProperties",
701 "vkGetPhysicalDeviceQueueFamilyProperties",
702 "vkGetPhysicalDeviceMemoryProperties",
703 "vkGetPhysicalDeviceFormatProperties",
704 "vkGetPhysicalDeviceImageFormatProperties",
706 "vkGetBufferMemoryRequirements",
707 "vkGetImageMemoryRequirements",
709 "vkAllocateDescriptorSets",
710 "vkFreeDescriptorSets",
711 "vkResetDescriptorPool",
712 "vkAllocateCommandBuffers",
713 "vkFreeCommandBuffers",
714 "vkCreateDisplayModeKHR",
715 "vkCreateSharedSwapchainsKHR",
717 specialFuncs = [f for f in api.functions if f.name in specialFuncNames]
718 createFuncs = [f for f in api.functions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs]
719 destroyFuncs = [f for f in api.functions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs]
720 dummyFuncs = [f for f in api.functions if f not in specialFuncs + createFuncs + destroyFuncs]
722 def getHandle (name):
723 for handle in api.handles:
724 if handle.name == name:
726 raise Exception("No such handle: %s" % name)
728 for function in createFuncs:
729 objectType = function.arguments[-1].type.replace("*", "").strip()
730 argsStr = ", ".join([a.name for a in function.arguments[:-1]])
732 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
734 yield "\tDE_UNREF(%s);" % function.arguments[-2].name
736 if getHandle(objectType).type == Handle.TYPE_NONDISP:
737 yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr)
739 yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr)
744 for function in destroyFuncs:
745 objectArg = function.arguments[-2]
747 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
749 for arg in function.arguments[:-2]:
750 yield "\tDE_UNREF(%s);" % arg.name
752 if getHandle(objectArg.type).type == Handle.TYPE_NONDISP:
753 yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name)
755 yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name)
760 for function in dummyFuncs:
761 yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function), argListToStr(function.arguments))
763 for arg in function.arguments:
764 yield "\tDE_UNREF(%s);" % arg.name
765 if function.returnType != "void":
766 yield "\treturn VK_SUCCESS;"
770 def genFuncEntryTable (type, name):
771 funcs = [f for f in api.functions if f.getType() == type]
773 yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name
775 for line in indentLines(["\tVK_NULL_FUNC_ENTRY(%s,\t%s)," % (function.name, getInterfaceName(function)) for function in funcs]):
781 for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"):
784 for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"):
787 for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"):
791 writeInlFile(filename, INL_HEADER, genNullDriverImpl())
793 def writeTypeUtil (api, filename):
794 # Structs filled by API queries are not often used in test code
795 QUERY_RESULT_TYPES = set([
796 "VkPhysicalDeviceFeatures",
797 "VkPhysicalDeviceLimits",
798 "VkFormatProperties",
799 "VkImageFormatProperties",
800 "VkPhysicalDeviceSparseProperties",
801 "VkQueueFamilyProperties",
805 COMPOSITE_TYPES = set([t.name for t in api.compositeTypes])
807 def isSimpleStruct (type):
808 def hasArrayMember (type):
809 for member in type.members:
810 if "[" in member.name:
814 def hasCompositeMember (type):
815 for member in type.members:
816 if member.type in COMPOSITE_TYPES:
820 return type.typeClass == CompositeType.CLASS_STRUCT and \
821 type.members[0].type != "VkStructureType" and \
822 not type.name in QUERY_RESULT_TYPES and \
823 not hasArrayMember(type) and \
824 not hasCompositeMember(type)
827 for type in api.compositeTypes:
828 if not isSimpleStruct(type):
832 yield "inline %s make%s (%s)" % (type.name, type.name[2:], argListToStr(type.members))
834 yield "\t%s res;" % type.name
835 for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]):
837 yield "\treturn res;"
840 writeInlFile(filename, INL_HEADER, gen())
842 if __name__ == "__main__":
843 src = readFile(VULKAN_H)
845 platformFuncs = set([Function.TYPE_PLATFORM])
846 instanceFuncs = set([Function.TYPE_INSTANCE])
847 deviceFuncs = set([Function.TYPE_DEVICE])
849 writeHandleType (api, os.path.join(VULKAN_DIR, "vkHandleType.inl"))
850 writeBasicTypes (api, os.path.join(VULKAN_DIR, "vkBasicTypes.inl"))
851 writeCompositeTypes (api, os.path.join(VULKAN_DIR, "vkStructTypes.inl"))
852 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualPlatformInterface.inl"), functionTypes = platformFuncs, concrete = False)
853 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualInstanceInterface.inl"), functionTypes = instanceFuncs, concrete = False)
854 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkVirtualDeviceInterface.inl"), functionTypes = deviceFuncs, concrete = False)
855 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcretePlatformInterface.inl"), functionTypes = platformFuncs, concrete = True)
856 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteInstanceInterface.inl"), functionTypes = instanceFuncs, concrete = True)
857 writeInterfaceDecl (api, os.path.join(VULKAN_DIR, "vkConcreteDeviceInterface.inl"), functionTypes = deviceFuncs, concrete = True)
858 writeFunctionPtrTypes (api, os.path.join(VULKAN_DIR, "vkFunctionPointerTypes.inl"))
859 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkPlatformFunctionPointers.inl"), functionTypes = platformFuncs)
860 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInstanceFunctionPointers.inl"), functionTypes = instanceFuncs)
861 writeFunctionPointers (api, os.path.join(VULKAN_DIR, "vkDeviceFunctionPointers.inl"), functionTypes = deviceFuncs)
862 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitPlatformFunctionPointers.inl"), functionTypes = platformFuncs, cond = lambda f: f.name != "vkGetInstanceProcAddr")
863 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitInstanceFunctionPointers.inl"), functionTypes = instanceFuncs)
864 writeInitFunctionPointers (api, os.path.join(VULKAN_DIR, "vkInitDeviceFunctionPointers.inl"), functionTypes = deviceFuncs)
865 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkPlatformDriverImpl.inl"), functionTypes = platformFuncs, className = "PlatformDriver")
866 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkInstanceDriverImpl.inl"), functionTypes = instanceFuncs, className = "InstanceDriver")
867 writeFuncPtrInterfaceImpl (api, os.path.join(VULKAN_DIR, "vkDeviceDriverImpl.inl"), functionTypes = deviceFuncs, className = "DeviceDriver")
868 writeStrUtilProto (api, os.path.join(VULKAN_DIR, "vkStrUtil.inl"))
869 writeStrUtilImpl (api, os.path.join(VULKAN_DIR, "vkStrUtilImpl.inl"))
870 writeRefUtilProto (api, os.path.join(VULKAN_DIR, "vkRefUtil.inl"))
871 writeRefUtilImpl (api, os.path.join(VULKAN_DIR, "vkRefUtilImpl.inl"))
872 writeNullDriverImpl (api, os.path.join(VULKAN_DIR, "vkNullDriverImpl.inl"))
873 writeTypeUtil (api, os.path.join(VULKAN_DIR, "vkTypeUtil.inl"))