1e5c31af7Sopenharmony_ci# -*- coding: utf-8 -*- 2e5c31af7Sopenharmony_ci 3e5c31af7Sopenharmony_ci#------------------------------------------------------------------------- 4e5c31af7Sopenharmony_ci# Vulkan CTS 5e5c31af7Sopenharmony_ci# ---------- 6e5c31af7Sopenharmony_ci# 7e5c31af7Sopenharmony_ci# Copyright (c) 2015 Google Inc. 8e5c31af7Sopenharmony_ci# 9e5c31af7Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 10e5c31af7Sopenharmony_ci# you may not use this file except in compliance with the License. 11e5c31af7Sopenharmony_ci# You may obtain a copy of the License at 12e5c31af7Sopenharmony_ci# 13e5c31af7Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 14e5c31af7Sopenharmony_ci# 15e5c31af7Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 16e5c31af7Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 17e5c31af7Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18e5c31af7Sopenharmony_ci# See the License for the specific language governing permissions and 19e5c31af7Sopenharmony_ci# limitations under the License. 20e5c31af7Sopenharmony_ci# 21e5c31af7Sopenharmony_ci#------------------------------------------------------------------------- 22e5c31af7Sopenharmony_ci 23e5c31af7Sopenharmony_ciimport os 24e5c31af7Sopenharmony_ciimport re 25e5c31af7Sopenharmony_ciimport sys 26e5c31af7Sopenharmony_ciimport glob 27e5c31af7Sopenharmony_ciimport json 28e5c31af7Sopenharmony_ciimport argparse 29e5c31af7Sopenharmony_ciimport datetime 30e5c31af7Sopenharmony_ciimport collections 31e5c31af7Sopenharmony_cifrom lxml import etree 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ciscriptPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "scripts") 34e5c31af7Sopenharmony_cisys.path.insert(0, scriptPath) 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_cifrom ctsbuild.common import DEQP_DIR, execute 37e5c31af7Sopenharmony_cifrom khr_util.format import indentLines, writeInlFile 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_cisys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "vulkan-docs", "src", "scripts")) 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_cifrom reg import stripNonmatchingAPIs 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_ciVULKAN_XML_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "vulkan-docs", "src", "xml") 44e5c31af7Sopenharmony_ciSCRIPTS_SRC_DIR = os.path.join(os.path.dirname(__file__), "src") 45e5c31af7Sopenharmony_ciDEFAULT_OUTPUT_DIR = { "" : os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan", "generated", "vulkan"), 46e5c31af7Sopenharmony_ci "SC" : os.path.join(os.path.dirname(__file__), "..", "framework", "vulkan", "generated", "vulkansc") } 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ciINL_HEADER = """\ 49e5c31af7Sopenharmony_ci/* WARNING: This is auto-generated file. Do not modify, since changes will 50e5c31af7Sopenharmony_ci * be lost! Modify the generating script instead. 51e5c31af7Sopenharmony_ci * This file was generated by /scripts/gen_framework.py 52e5c31af7Sopenharmony_ci */\ 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_ci""" 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ciDEFINITIONS = { 57e5c31af7Sopenharmony_ci "VK_MAX_PHYSICAL_DEVICE_NAME_SIZE": "size_t", 58e5c31af7Sopenharmony_ci "VK_MAX_EXTENSION_NAME_SIZE": "size_t", 59e5c31af7Sopenharmony_ci "VK_MAX_DRIVER_NAME_SIZE": "size_t", 60e5c31af7Sopenharmony_ci "VK_MAX_DRIVER_INFO_SIZE": "size_t", 61e5c31af7Sopenharmony_ci "VK_UUID_SIZE": "size_t", 62e5c31af7Sopenharmony_ci "VK_LUID_SIZE": "size_t", 63e5c31af7Sopenharmony_ci "VK_MAX_MEMORY_TYPES": "size_t", 64e5c31af7Sopenharmony_ci "VK_MAX_MEMORY_HEAPS": "size_t", 65e5c31af7Sopenharmony_ci "VK_MAX_DESCRIPTION_SIZE": "size_t", 66e5c31af7Sopenharmony_ci "VK_MAX_DEVICE_GROUP_SIZE": "size_t", 67e5c31af7Sopenharmony_ci "VK_ATTACHMENT_UNUSED": "uint32_t", 68e5c31af7Sopenharmony_ci "VK_SUBPASS_EXTERNAL": "uint32_t", 69e5c31af7Sopenharmony_ci "VK_QUEUE_FAMILY_IGNORED": "uint32_t", 70e5c31af7Sopenharmony_ci "VK_QUEUE_FAMILY_EXTERNAL": "uint32_t", 71e5c31af7Sopenharmony_ci "VK_REMAINING_MIP_LEVELS": "uint32_t", 72e5c31af7Sopenharmony_ci "VK_REMAINING_ARRAY_LAYERS": "uint32_t", 73e5c31af7Sopenharmony_ci "VK_WHOLE_SIZE": "vk::VkDeviceSize", 74e5c31af7Sopenharmony_ci "VK_TRUE": "vk::VkBool32", 75e5c31af7Sopenharmony_ci "VK_FALSE": "vk::VkBool32", 76e5c31af7Sopenharmony_ci} 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ciPLATFORM_TYPES = [ 79e5c31af7Sopenharmony_ci # VK_KHR_xlib_surface 80e5c31af7Sopenharmony_ci (["Display","*"], ["XlibDisplayPtr"], "void*"), 81e5c31af7Sopenharmony_ci (["Window"], ["XlibWindow"], "uintptr_t",), 82e5c31af7Sopenharmony_ci (["VisualID"], ["XlibVisualID"], "uint32_t"), 83e5c31af7Sopenharmony_ci 84e5c31af7Sopenharmony_ci # VK_KHR_xcb_surface 85e5c31af7Sopenharmony_ci (["xcb_connection_t", "*"], ["XcbConnectionPtr"], "void*"), 86e5c31af7Sopenharmony_ci (["xcb_window_t"], ["XcbWindow"], "uintptr_t"), 87e5c31af7Sopenharmony_ci (["xcb_visualid_t"], ["XcbVisualid"], "uint32_t"), 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci # VK_KHR_wayland_surface 90e5c31af7Sopenharmony_ci (["struct", "wl_display","*"], ["WaylandDisplayPtr"], "void*"), 91e5c31af7Sopenharmony_ci (["struct", "wl_surface", "*"], ["WaylandSurfacePtr"], "void*"), 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci # VK_KHR_mir_surface 94e5c31af7Sopenharmony_ci (["MirConnection", "*"], ["MirConnectionPtr"], "void*"), 95e5c31af7Sopenharmony_ci (["MirSurface", "*"], ["MirSurfacePtr"], "void*"), 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci # VK_KHR_android_surface 98e5c31af7Sopenharmony_ci (["ANativeWindow", "*"], ["AndroidNativeWindowPtr"], "void*"), 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci # VK_KHR_win32_surface 101e5c31af7Sopenharmony_ci (["HINSTANCE"], ["Win32InstanceHandle"], "void*"), 102e5c31af7Sopenharmony_ci (["HWND"], ["Win32WindowHandle"], "void*"), 103e5c31af7Sopenharmony_ci (["HANDLE"], ["Win32Handle"], "void*"), 104e5c31af7Sopenharmony_ci (["const", "SECURITY_ATTRIBUTES", "*"], ["Win32SecurityAttributesPtr"], "const void*"), 105e5c31af7Sopenharmony_ci (["AHardwareBuffer", "*"], ["AndroidHardwareBufferPtr"], "void*"), 106e5c31af7Sopenharmony_ci (["HMONITOR"], ["Win32MonitorHandle"], "void*"), 107e5c31af7Sopenharmony_ci (["LPCWSTR"], ["Win32LPCWSTR"], "const void*"), 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci # VK_EXT_acquire_xlib_display 110e5c31af7Sopenharmony_ci (["RROutput"], ["RROutput"], "void*"), 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ci (["zx_handle_t"], ["zx_handle_t"], "uint32_t"), 113e5c31af7Sopenharmony_ci (["GgpFrameToken"], ["GgpFrameToken"], "int32_t"), 114e5c31af7Sopenharmony_ci (["GgpStreamDescriptor"], ["GgpStreamDescriptor"], "int32_t"), 115e5c31af7Sopenharmony_ci (["CAMetalLayer"], ["CAMetalLayer"], "void*"), 116e5c31af7Sopenharmony_ci (["struct", "_screen_context", "*"], ["QNXScreenContextPtr"], "void*"), 117e5c31af7Sopenharmony_ci (["struct", "_screen_window", "*"], ["QNXScreenWindowPtr"], "void*"), 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci # VK_EXT_metal_objects 120e5c31af7Sopenharmony_ci (["MTLDevice_id"], ["MTLDevice_id"], "void*"), 121e5c31af7Sopenharmony_ci (["MTLCommandQueue_id"], ["MTLCommandQueue_id"], "void*"), 122e5c31af7Sopenharmony_ci (["MTLBuffer_id"], ["MTLBuffer_id"], "void*"), 123e5c31af7Sopenharmony_ci (["MTLTexture_id"], ["MTLTexture_id"], "void*"), 124e5c31af7Sopenharmony_ci (["IOSurfaceRef"], ["IOSurfaceRef"], "void*"), 125e5c31af7Sopenharmony_ci (["MTLSharedEvent_id"], ["MTLSharedEvent_id"], "void*"), 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci # VK_NV_external_sci_sync 128e5c31af7Sopenharmony_ci (["NvSciBufObj"], ["NvSciBufObj"], "int"), 129e5c31af7Sopenharmony_ci (["NvSciSyncObj"], ["NvSciSyncObj"], "int"), 130e5c31af7Sopenharmony_ci (["NvSciSyncFence"], ["NvSciSyncFence"], "int"), 131e5c31af7Sopenharmony_ci (["NvSciBufAttrList"], ["NvSciBufAttrList"], "int"), 132e5c31af7Sopenharmony_ci (["NvSciSyncAttrList"], ["NvSciSyncAttrList"], "int"), 133e5c31af7Sopenharmony_ci] 134e5c31af7Sopenharmony_ci 135e5c31af7Sopenharmony_ciPLATFORM_TYPE_NAMESPACE = "pt" 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ciTYPE_SUBSTITUTIONS = [ 138e5c31af7Sopenharmony_ci # Platform-specific 139e5c31af7Sopenharmony_ci ("DWORD", "uint32_t"), 140e5c31af7Sopenharmony_ci ("HANDLE*", PLATFORM_TYPE_NAMESPACE + "::" + "Win32Handle*"), 141e5c31af7Sopenharmony_ci] 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ciEXTENSION_POSTFIXES_STANDARD = ["KHR", "EXT"] 144e5c31af7Sopenharmony_ciEXTENSION_POSTFIXES_VENDOR = ["AMD", "ARM", "NV", 'INTEL', "NVX", "KHX", "NN", "MVK", "FUCHSIA", 'QCOM', "GGP", "QNX", "ANDROID", 'VALVE', 'HUAWEI'] 145e5c31af7Sopenharmony_ciEXTENSION_POSTFIXES = EXTENSION_POSTFIXES_STANDARD + EXTENSION_POSTFIXES_VENDOR 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_cidef substituteType(object): # both CompositeMember and FunctionArgument can be passed to this function 148e5c31af7Sopenharmony_ci for src, dst in TYPE_SUBSTITUTIONS: 149e5c31af7Sopenharmony_ci object.type = object.type.replace(src, dst) 150e5c31af7Sopenharmony_ci for platformType, substitute, _ in PLATFORM_TYPES: 151e5c31af7Sopenharmony_ci platformTypeName = platformType[0] 152e5c31af7Sopenharmony_ci platformTypeName = platformType[-2] if "*" in platformType else platformType[0] 153e5c31af7Sopenharmony_ci if object.type == platformTypeName: 154e5c31af7Sopenharmony_ci object.type = PLATFORM_TYPE_NAMESPACE + '::' + substitute[0] 155e5c31af7Sopenharmony_ci object.qualifiers = None if 'struct' in platformType else object.qualifiers 156e5c31af7Sopenharmony_ci object.qualifiers = None if 'const' in platformType else object.qualifiers 157e5c31af7Sopenharmony_ci if "*" in platformType: 158e5c31af7Sopenharmony_ci object.pointer = "*" if object.pointer == "**" else None 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ciclass Define: 161e5c31af7Sopenharmony_ci def __init__ (self, name, aType, alias, value): 162e5c31af7Sopenharmony_ci self.name = name 163e5c31af7Sopenharmony_ci self.type = aType 164e5c31af7Sopenharmony_ci self.alias = alias 165e5c31af7Sopenharmony_ci self.value = value 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ciclass Handle: 168e5c31af7Sopenharmony_ci def __init__ (self, name, aType, alias, parent, objtypeenum): 169e5c31af7Sopenharmony_ci self.name = name 170e5c31af7Sopenharmony_ci self.type = aType 171e5c31af7Sopenharmony_ci self.alias = alias 172e5c31af7Sopenharmony_ci self.parent = parent 173e5c31af7Sopenharmony_ci self.objtypeenum = objtypeenum 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ciclass Bitmask: 176e5c31af7Sopenharmony_ci def __init__ (self, name, aType, requires, bitvalues): 177e5c31af7Sopenharmony_ci self.name = name 178e5c31af7Sopenharmony_ci self.type = aType 179e5c31af7Sopenharmony_ci self.alias = None # initialy None but may be filled while parsing next tag 180e5c31af7Sopenharmony_ci self.requires = requires 181e5c31af7Sopenharmony_ci self.bitvalues = bitvalues 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_ciclass Enumerator: 184e5c31af7Sopenharmony_ci def __init__ (self, name, value, bitpos): 185e5c31af7Sopenharmony_ci self.name = name 186e5c31af7Sopenharmony_ci self.aliasList = [] # list of strings 187e5c31af7Sopenharmony_ci self.value = value # some enums specify value and some bitpos 188e5c31af7Sopenharmony_ci self.bitpos = bitpos 189e5c31af7Sopenharmony_ci self.extension = None # name of extension that added this enumerator 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ciclass Enum: 192e5c31af7Sopenharmony_ci def __init__ (self, name): 193e5c31af7Sopenharmony_ci self.name = name 194e5c31af7Sopenharmony_ci self.alias = None # name of enum alias or None 195e5c31af7Sopenharmony_ci self.type = None # enum or bitmask 196e5c31af7Sopenharmony_ci self.bitwidth = "32" 197e5c31af7Sopenharmony_ci self.enumeratorList = [] # list of Enumerator objects 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci def areValuesLinear (self): 200e5c31af7Sopenharmony_ci if self.type == 'bitmask': 201e5c31af7Sopenharmony_ci return False 202e5c31af7Sopenharmony_ci curIndex = 0 203e5c31af7Sopenharmony_ci for enumerator in self.enumeratorList: 204e5c31af7Sopenharmony_ci intValue = parseInt(enumerator.value) 205e5c31af7Sopenharmony_ci if intValue != curIndex: 206e5c31af7Sopenharmony_ci return False 207e5c31af7Sopenharmony_ci curIndex += 1 208e5c31af7Sopenharmony_ci return True 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ciclass CompositeMember: 211e5c31af7Sopenharmony_ci def __init__ (self, name, aType, pointer, qualifiers, arraySizeList, optional, limittype, values, fieldWidth): 212e5c31af7Sopenharmony_ci self.name = name 213e5c31af7Sopenharmony_ci self.type = aType # member type 214e5c31af7Sopenharmony_ci self.pointer = pointer # None, '*' or '**' 215e5c31af7Sopenharmony_ci self.qualifiers = qualifiers # 'const' or 'struct' or None 216e5c31af7Sopenharmony_ci self.arraySizeList = arraySizeList # can contain digits or enums 217e5c31af7Sopenharmony_ci self.optional = optional 218e5c31af7Sopenharmony_ci self.limittype = limittype 219e5c31af7Sopenharmony_ci self.values = values # allowed member values 220e5c31af7Sopenharmony_ci self.fieldWidth = fieldWidth # ':' followed by number of bits 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_ci # check if type should be swaped 223e5c31af7Sopenharmony_ci substituteType(self) 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_ciclass Composite: 226e5c31af7Sopenharmony_ci def __init__ (self, name, category, allowduplicate, structextends, returnedonly, members): 227e5c31af7Sopenharmony_ci self.name = name 228e5c31af7Sopenharmony_ci self.category = category # is it struct or union 229e5c31af7Sopenharmony_ci self.aliasList = [] # most composite types have single alias but there are cases like VkPhysicalDeviceVariablePointersFeatures that have 3 230e5c31af7Sopenharmony_ci self.allowduplicate = allowduplicate 231e5c31af7Sopenharmony_ci self.structextends = structextends 232e5c31af7Sopenharmony_ci self.returnedonly = returnedonly 233e5c31af7Sopenharmony_ci self.members = members # list of CompositeMember objects 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ciclass FunctionArgument: 236e5c31af7Sopenharmony_ci def __init__ (self, name, qualifiers, aType, pointer = None, secondPointerIsConst = False, arraySize = None, len = None): 237e5c31af7Sopenharmony_ci self.name = name 238e5c31af7Sopenharmony_ci self.qualifiers = qualifiers 239e5c31af7Sopenharmony_ci self.type = aType 240e5c31af7Sopenharmony_ci self.pointer = pointer # None, '*' or '**' 241e5c31af7Sopenharmony_ci self.secondPointerIsConst = secondPointerIsConst 242e5c31af7Sopenharmony_ci self.arraySize = arraySize 243e5c31af7Sopenharmony_ci self.len = len 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ci # check if type should be swaped 246e5c31af7Sopenharmony_ci substituteType(self) 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ciclass Function: 249e5c31af7Sopenharmony_ci TYPE_PLATFORM = 0 # Not bound to anything 250e5c31af7Sopenharmony_ci TYPE_INSTANCE = 1 # Bound to VkInstance 251e5c31af7Sopenharmony_ci TYPE_DEVICE = 2 # Bound to VkDevice 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci def __init__ (self, name, returnType = None, arguments = None): 254e5c31af7Sopenharmony_ci self.name = name 255e5c31af7Sopenharmony_ci self.aliasList = [] 256e5c31af7Sopenharmony_ci self.returnType = returnType 257e5c31af7Sopenharmony_ci self.arguments = arguments # list of FunctionArgument objects 258e5c31af7Sopenharmony_ci self.functionType = Function.TYPE_PLATFORM 259e5c31af7Sopenharmony_ci 260e5c31af7Sopenharmony_ci # Determine function type based on first argument but use TYPE_PLATFORM for vkGetInstanceProcAddr 261e5c31af7Sopenharmony_ci if self.name == "vkGetInstanceProcAddr": 262e5c31af7Sopenharmony_ci return 263e5c31af7Sopenharmony_ci assert len(self.arguments) > 0 264e5c31af7Sopenharmony_ci firstArgType = self.arguments[0].type 265e5c31af7Sopenharmony_ci if firstArgType in ["VkInstance", "VkPhysicalDevice"]: 266e5c31af7Sopenharmony_ci self.functionType = Function.TYPE_INSTANCE 267e5c31af7Sopenharmony_ci elif firstArgType in ["VkDevice", "VkCommandBuffer", "VkQueue"]: 268e5c31af7Sopenharmony_ci self.functionType = Function.TYPE_DEVICE 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_ci def getType (self): 271e5c31af7Sopenharmony_ci return self.functionType 272e5c31af7Sopenharmony_ci 273e5c31af7Sopenharmony_ciclass FeatureEnumerator: 274e5c31af7Sopenharmony_ci def __init__ (self, name, extends): 275e5c31af7Sopenharmony_ci self.name = name 276e5c31af7Sopenharmony_ci self.extends = extends 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ciclass FeatureRequirement: 279e5c31af7Sopenharmony_ci def __init__ (self, operation, comment, enumList, typeList, commandList): 280e5c31af7Sopenharmony_ci self.operation = operation # "require" or "remove" 281e5c31af7Sopenharmony_ci self.comment = comment 282e5c31af7Sopenharmony_ci self.enumList = enumList # list of FeatureEnumerator objects 283e5c31af7Sopenharmony_ci self.typeList = typeList # list of strings, each representing required structure name 284e5c31af7Sopenharmony_ci self.commandList = commandList # list of strings, each representing required function name 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ciclass Feature: 287e5c31af7Sopenharmony_ci def __init__ (self, api, name, number, requirementsList): 288e5c31af7Sopenharmony_ci self.api = api 289e5c31af7Sopenharmony_ci self.name = name 290e5c31af7Sopenharmony_ci self.number = number 291e5c31af7Sopenharmony_ci self.requirementsList = requirementsList # list of FeatureRequirement objects 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ciclass ExtensionEnumerator: 294e5c31af7Sopenharmony_ci def __init__ (self, name, extends, alias, value, extnumber, offset, bitpos, vdir, comment): 295e5c31af7Sopenharmony_ci self.name = name 296e5c31af7Sopenharmony_ci self.extends = extends 297e5c31af7Sopenharmony_ci self.alias = alias 298e5c31af7Sopenharmony_ci self.value = value 299e5c31af7Sopenharmony_ci self.extnumber = extnumber 300e5c31af7Sopenharmony_ci self.offset = offset 301e5c31af7Sopenharmony_ci self.bitpos = bitpos 302e5c31af7Sopenharmony_ci self.dir = vdir 303e5c31af7Sopenharmony_ci self.comment = comment # note: comment is used to mark not promoted features for partially promoted extensions 304e5c31af7Sopenharmony_ci 305e5c31af7Sopenharmony_ciclass ExtensionCommand: 306e5c31af7Sopenharmony_ci def __init__ (self, name, comment): 307e5c31af7Sopenharmony_ci self.name = name 308e5c31af7Sopenharmony_ci self.comment = comment 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_ciclass ExtensionType: 311e5c31af7Sopenharmony_ci def __init__ (self, name, comment): 312e5c31af7Sopenharmony_ci self.name = name 313e5c31af7Sopenharmony_ci self.comment = comment 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ciclass ExtensionRequirements: 316e5c31af7Sopenharmony_ci def __init__ (self, depends, extendedEnums, newCommands, newTypes): 317e5c31af7Sopenharmony_ci self.depends = depends # None when requirement apply to all implementations of extension or string with dependencies 318e5c31af7Sopenharmony_ci # string with extension name when requirements apply to implementations that also support given extension 319e5c31af7Sopenharmony_ci self.extendedEnums = extendedEnums # list of ExtensionEnumerator objects 320e5c31af7Sopenharmony_ci self.newCommands = newCommands # list of ExtensionCommand objects 321e5c31af7Sopenharmony_ci self.newTypes = newTypes # list of ExtensionType objects 322e5c31af7Sopenharmony_ci 323e5c31af7Sopenharmony_ciclass Extension: 324e5c31af7Sopenharmony_ci def __init__ (self, name, number, type, depends, platform, promotedto, partiallyPromoted, requirementsList): 325e5c31af7Sopenharmony_ci self.name = name # extension name 326e5c31af7Sopenharmony_ci self.number = number # extension version 327e5c31af7Sopenharmony_ci self.type = type # extension type - "device" or "instance" 328e5c31af7Sopenharmony_ci self.depends = depends # string containig grammar for required core vulkan version and/or other extensions 329e5c31af7Sopenharmony_ci self.platform = platform # None, "win32", "ios", "android" etc. 330e5c31af7Sopenharmony_ci self.promotedto = promotedto # vulkan version, other extension or None 331e5c31af7Sopenharmony_ci self.partiallyPromoted = partiallyPromoted # when True then some of requirements were not promoted 332e5c31af7Sopenharmony_ci self.requirementsList = requirementsList # list of ExtensionRequirements objects 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ciclass API: 335e5c31af7Sopenharmony_ci def __init__ (self, apiName): 336e5c31af7Sopenharmony_ci self.apiName = apiName # string "vulkan" or "vulkansc" 337e5c31af7Sopenharmony_ci self.versions = [] 338e5c31af7Sopenharmony_ci self.basetypes = {} # dictionary, e.g. one of keys is VkFlags and its value is uint32_t 339e5c31af7Sopenharmony_ci self.defines = [] 340e5c31af7Sopenharmony_ci self.handles = [] # list of Handle objects 341e5c31af7Sopenharmony_ci self.bitmasks = [] # list of Bitmask objects 342e5c31af7Sopenharmony_ci self.enums = [] # list of Enum objects - each contains individual enum definition (including extension enums) 343e5c31af7Sopenharmony_ci self.compositeTypes = [] # list of Composite objects - each contains individual structure/union definition (including extension structures) 344e5c31af7Sopenharmony_ci self.functions = [] # list of Function objects - each contains individual command definition (including extension functions) 345e5c31af7Sopenharmony_ci self.features = [] # list of Feature objects 346e5c31af7Sopenharmony_ci self.extensions = [] # list of Extension objects - each contains individual, supported extension definition 347e5c31af7Sopenharmony_ci self.notSupportedExtensions = [] # list of Extension objects - it contains NOT supported extensions; this is filled and needed only for SC 348e5c31af7Sopenharmony_ci self.basicCTypes = [] # list of basic C types e.g. 'void', 'int8_t' 349e5c31af7Sopenharmony_ci self.tempAliasesList = [] # list of aliases for enums that could not be added because enum is defined later than its alias; this is needed for SC 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci # read all files from extensions directory 352e5c31af7Sopenharmony_ci additionalExtensionData = {} 353e5c31af7Sopenharmony_ci for fileName in glob.glob(os.path.join(SCRIPTS_SRC_DIR, "extensions", "*.json")): 354e5c31af7Sopenharmony_ci if "schema.json" in fileName: 355e5c31af7Sopenharmony_ci continue 356e5c31af7Sopenharmony_ci extensionName = os.path.basename(fileName)[:-5] 357e5c31af7Sopenharmony_ci fileContent = readFile(fileName) 358e5c31af7Sopenharmony_ci try: 359e5c31af7Sopenharmony_ci additionalExtensionData[extensionName] = json.loads(fileContent) 360e5c31af7Sopenharmony_ci except ValueError as err: 361e5c31af7Sopenharmony_ci print("Error in %s: %s" % (os.path.basename(fileName), str(err))) 362e5c31af7Sopenharmony_ci sys.exit(-1) 363e5c31af7Sopenharmony_ci self.additionalExtensionData = sorted(additionalExtensionData.items(), key=lambda e: e[0]) 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci def addEnumerator(self, targetEnum, name, value, offset, extnumber, bitpos, dir = None): 366e5c31af7Sopenharmony_ci # calculate enumerator value if offset attribute is present 367e5c31af7Sopenharmony_ci if value is None and offset is not None: 368e5c31af7Sopenharmony_ci value = 1000000000 + (int(extnumber) - 1) * 1000 + int(offset) 369e5c31af7Sopenharmony_ci # check if value should be negative 370e5c31af7Sopenharmony_ci value = -value if dir == "-" else value 371e5c31af7Sopenharmony_ci # convert to string so that type matches the type in which values 372e5c31af7Sopenharmony_ci # are stored for enums that were read from enums xml section 373e5c31af7Sopenharmony_ci value = str(value) 374e5c31af7Sopenharmony_ci # add new enumerator 375e5c31af7Sopenharmony_ci targetEnum.enumeratorList.append(Enumerator(name, value, bitpos)) 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci def addAliasToEnumerator (self, targetEnum, name, alias): 378e5c31af7Sopenharmony_ci assert(alias is not None) 379e5c31af7Sopenharmony_ci for e in reversed(targetEnum.enumeratorList): 380e5c31af7Sopenharmony_ci if alias == e.name or alias in e.aliasList: 381e5c31af7Sopenharmony_ci # make sure same alias is not already on the list; this handles special case like 382e5c31af7Sopenharmony_ci # VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR alais which is defined in three places 383e5c31af7Sopenharmony_ci if name not in e.aliasList: 384e5c31af7Sopenharmony_ci e.aliasList.append(name) 385e5c31af7Sopenharmony_ci return True 386e5c31af7Sopenharmony_ci return False 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci def readEnum (self, enumsNode): 389e5c31af7Sopenharmony_ci enumName = enumsNode.get("name") 390e5c31af7Sopenharmony_ci # special case for vulkan hardcoded constants that are specified as enum in vk.xml 391e5c31af7Sopenharmony_ci if enumName == "API Constants": 392e5c31af7Sopenharmony_ci for enumItem in enumsNode: 393e5c31af7Sopenharmony_ci self.defines.append(Define( 394e5c31af7Sopenharmony_ci enumItem.get("name"), 395e5c31af7Sopenharmony_ci enumItem.get("type"), 396e5c31af7Sopenharmony_ci enumItem.get("alias"), 397e5c31af7Sopenharmony_ci enumItem.get("value") 398e5c31af7Sopenharmony_ci )) 399e5c31af7Sopenharmony_ci return 400e5c31af7Sopenharmony_ci # initial enum definition is read while processing types section; 401e5c31af7Sopenharmony_ci # we need to find this enum definition and add data to it 402e5c31af7Sopenharmony_ci enumDefinition = [enumDef for enumDef in self.enums if enumName == enumDef.name][0] 403e5c31af7Sopenharmony_ci # add type and bitwidth to enum definition 404e5c31af7Sopenharmony_ci enumDefinition.type = enumsNode.get("type") 405e5c31af7Sopenharmony_ci enumDefinition.bitwidth = enumsNode.get("bitwidth") 406e5c31af7Sopenharmony_ci if enumDefinition.bitwidth is None: 407e5c31af7Sopenharmony_ci enumDefinition.bitwidth = "32" 408e5c31af7Sopenharmony_ci # add components to enum definition 409e5c31af7Sopenharmony_ci for enumeratorItem in enumsNode: 410e5c31af7Sopenharmony_ci # skip comment tags 411e5c31af7Sopenharmony_ci if enumeratorItem.tag != "enum": 412e5c31af7Sopenharmony_ci continue 413e5c31af7Sopenharmony_ci name = enumeratorItem.get("name") 414e5c31af7Sopenharmony_ci alias = enumeratorItem.get("alias") 415e5c31af7Sopenharmony_ci if alias is None: 416e5c31af7Sopenharmony_ci self.addEnumerator( 417e5c31af7Sopenharmony_ci enumDefinition, 418e5c31af7Sopenharmony_ci name, 419e5c31af7Sopenharmony_ci enumeratorItem.get("value"), 420e5c31af7Sopenharmony_ci enumeratorItem.get("offset"), 421e5c31af7Sopenharmony_ci enumeratorItem.get("extnumber"), 422e5c31af7Sopenharmony_ci enumeratorItem.get("bitpos"), 423e5c31af7Sopenharmony_ci enumeratorItem.get("dir")) 424e5c31af7Sopenharmony_ci else: 425e5c31af7Sopenharmony_ci self.addAliasToEnumerator(enumDefinition, name, alias) 426e5c31af7Sopenharmony_ci 427e5c31af7Sopenharmony_ci def readCommand (self, commandNode): 428e5c31af7Sopenharmony_ci protoNode = None # proto is a first child of every command node 429e5c31af7Sopenharmony_ci # check if this is alias 430e5c31af7Sopenharmony_ci alias = commandNode.get("alias") 431e5c31af7Sopenharmony_ci # if node is alias then use the fact that alias definition follows aliased structure 432e5c31af7Sopenharmony_ci if alias is not None: 433e5c31af7Sopenharmony_ci # aliased command has usually been added recently, so we iterate in reverse order 434e5c31af7Sopenharmony_ci found = False 435e5c31af7Sopenharmony_ci for f in reversed(self.functions): 436e5c31af7Sopenharmony_ci found = (f.name == alias) 437e5c31af7Sopenharmony_ci if found: 438e5c31af7Sopenharmony_ci f.aliasList.append(commandNode.get("name")) 439e5c31af7Sopenharmony_ci break 440e5c31af7Sopenharmony_ci assert found 441e5c31af7Sopenharmony_ci # go to next node 442e5c31af7Sopenharmony_ci return 443e5c31af7Sopenharmony_ci # memorize all parameters 444e5c31af7Sopenharmony_ci functionParams = [] 445e5c31af7Sopenharmony_ci for paramNode in commandNode: 446e5c31af7Sopenharmony_ci # memorize prototype node 447e5c31af7Sopenharmony_ci if paramNode.tag == "proto": 448e5c31af7Sopenharmony_ci protoNode = paramNode 449e5c31af7Sopenharmony_ci continue 450e5c31af7Sopenharmony_ci # skip implicitexternsyncparams 451e5c31af7Sopenharmony_ci if paramNode.tag != "param": 452e5c31af7Sopenharmony_ci continue 453e5c31af7Sopenharmony_ci nameNode = paramNode.find("name") 454e5c31af7Sopenharmony_ci typeNode = paramNode.find("type") 455e5c31af7Sopenharmony_ci starCount = typeNode.tail.count('*') 456e5c31af7Sopenharmony_ci lenAttr = paramNode.get("len") 457e5c31af7Sopenharmony_ci functionParams.append(FunctionArgument( 458e5c31af7Sopenharmony_ci nameNode.text, 459e5c31af7Sopenharmony_ci paramNode.text, 460e5c31af7Sopenharmony_ci paramNode.find("type").text, 461e5c31af7Sopenharmony_ci '*' * starCount if starCount > 0 else None, 462e5c31af7Sopenharmony_ci 'const' in typeNode.tail, 463e5c31af7Sopenharmony_ci nameNode.tail, 464e5c31af7Sopenharmony_ci lenAttr 465e5c31af7Sopenharmony_ci )) 466e5c31af7Sopenharmony_ci # memorize whole function 467e5c31af7Sopenharmony_ci self.functions.append(Function( 468e5c31af7Sopenharmony_ci protoNode.find("name").text, 469e5c31af7Sopenharmony_ci protoNode.find("type").text, 470e5c31af7Sopenharmony_ci functionParams, 471e5c31af7Sopenharmony_ci )) 472e5c31af7Sopenharmony_ci 473e5c31af7Sopenharmony_ci def readExtension (self, extensionNode): 474e5c31af7Sopenharmony_ci # check to which list this extension should be added 475e5c31af7Sopenharmony_ci supportedList = extensionNode.get("supported") 476e5c31af7Sopenharmony_ci isExtensionSupported = self.apiName in supportedList.split(',') 477e5c31af7Sopenharmony_ci targetExtensionList = self.extensions if isExtensionSupported else self.notSupportedExtensions 478e5c31af7Sopenharmony_ci # read extension definition to proper list 479e5c31af7Sopenharmony_ci extensionName = extensionNode.get("name") 480e5c31af7Sopenharmony_ci extensionNumber = extensionNode.get("number") 481e5c31af7Sopenharmony_ci partiallyPromoted = False 482e5c31af7Sopenharmony_ci # before reading extension data first read extension 483e5c31af7Sopenharmony_ci # requirements by iterating over all require tags 484e5c31af7Sopenharmony_ci requirementsList = [] 485e5c31af7Sopenharmony_ci for requireItem in extensionNode: 486e5c31af7Sopenharmony_ci extendedEnums = [] 487e5c31af7Sopenharmony_ci newCommands = [] 488e5c31af7Sopenharmony_ci newTypes = [] 489e5c31af7Sopenharmony_ci # iterate over all children in current require tag 490e5c31af7Sopenharmony_ci # and add them to proper list 491e5c31af7Sopenharmony_ci for individualRequirement in requireItem: 492e5c31af7Sopenharmony_ci requirementName = individualRequirement.get("name") 493e5c31af7Sopenharmony_ci requirementComment = individualRequirement.get("comment") 494e5c31af7Sopenharmony_ci # check if this requirement was not promoted and mark 495e5c31af7Sopenharmony_ci # this extension as not fully promoted 496e5c31af7Sopenharmony_ci if requirementComment is not None and "Not promoted to" in requirementComment: 497e5c31af7Sopenharmony_ci partiallyPromoted = True 498e5c31af7Sopenharmony_ci # check if this requirement describes enum, command or type 499e5c31af7Sopenharmony_ci if individualRequirement.tag == "enum": 500e5c31af7Sopenharmony_ci extendedEnumName = individualRequirement.get("extends") 501e5c31af7Sopenharmony_ci extendedEnums.append(ExtensionEnumerator( 502e5c31af7Sopenharmony_ci requirementName, 503e5c31af7Sopenharmony_ci extendedEnumName, 504e5c31af7Sopenharmony_ci individualRequirement.get("alias"), 505e5c31af7Sopenharmony_ci individualRequirement.get("value"), 506e5c31af7Sopenharmony_ci individualRequirement.get("extnumber"), 507e5c31af7Sopenharmony_ci individualRequirement.get("offset"), 508e5c31af7Sopenharmony_ci individualRequirement.get("bitpos"), 509e5c31af7Sopenharmony_ci individualRequirement.get("dir"), 510e5c31af7Sopenharmony_ci requirementComment)) 511e5c31af7Sopenharmony_ci elif individualRequirement.tag == "command": 512e5c31af7Sopenharmony_ci newCommands.append(ExtensionCommand(requirementName, requirementComment)) 513e5c31af7Sopenharmony_ci elif individualRequirement.tag == "type": 514e5c31af7Sopenharmony_ci newTypes.append(ExtensionType(requirementName, requirementComment)) 515e5c31af7Sopenharmony_ci elif individualRequirement.tag == "comment" and "not promoted to" in individualRequirement.text: 516e5c31af7Sopenharmony_ci # partial promotion of VK_EXT_ycbcr_2plane_444_formats and VK_EXT_4444_formats 517e5c31af7Sopenharmony_ci # is marked with comment tag in first require section 518e5c31af7Sopenharmony_ci partiallyPromoted = True 519e5c31af7Sopenharmony_ci # construct requirement object and add it to the list 520e5c31af7Sopenharmony_ci requirementsList.append(ExtensionRequirements( 521e5c31af7Sopenharmony_ci requireItem.get("depends"), # dependencies that can include "and/or" grammar 522e5c31af7Sopenharmony_ci extendedEnums, # extendedEnums 523e5c31af7Sopenharmony_ci newCommands, # newCommands 524e5c31af7Sopenharmony_ci newTypes # newTypes 525e5c31af7Sopenharmony_ci )) 526e5c31af7Sopenharmony_ci # add extension definition to proper api object 527e5c31af7Sopenharmony_ci targetExtensionList.append(Extension( 528e5c31af7Sopenharmony_ci extensionName, # name 529e5c31af7Sopenharmony_ci extensionNumber, # number 530e5c31af7Sopenharmony_ci extensionNode.get("type"), # type 531e5c31af7Sopenharmony_ci extensionNode.get("depends"), # depends 532e5c31af7Sopenharmony_ci extensionNode.get("platform"), # platform 533e5c31af7Sopenharmony_ci extensionNode.get("promotedto"), # promotedto 534e5c31af7Sopenharmony_ci partiallyPromoted, # partiallyPromoted 535e5c31af7Sopenharmony_ci requirementsList # requirementsList 536e5c31af7Sopenharmony_ci )) 537e5c31af7Sopenharmony_ci 538e5c31af7Sopenharmony_ci def readFeature (self, featureNode): 539e5c31af7Sopenharmony_ci requirementsList = [] 540e5c31af7Sopenharmony_ci for requirementGroup in featureNode: 541e5c31af7Sopenharmony_ci enumList = [] 542e5c31af7Sopenharmony_ci typeList = [] 543e5c31af7Sopenharmony_ci commandList = [] 544e5c31af7Sopenharmony_ci for requirement in requirementGroup: 545e5c31af7Sopenharmony_ci requirementName = requirement.get("name") 546e5c31af7Sopenharmony_ci if requirement.tag == "enum": 547e5c31af7Sopenharmony_ci extendedEnumName = requirement.get("extends") 548e5c31af7Sopenharmony_ci enumList.append(FeatureEnumerator(requirementName, extendedEnumName)) 549e5c31af7Sopenharmony_ci if extendedEnumName is not None: 550e5c31af7Sopenharmony_ci # find extended enum in api.enums list 551e5c31af7Sopenharmony_ci for e in self.enums: 552e5c31af7Sopenharmony_ci if extendedEnumName == e.name: 553e5c31af7Sopenharmony_ci # read enumerator and add it to enum 554e5c31af7Sopenharmony_ci alias = requirement.get("alias") 555e5c31af7Sopenharmony_ci if alias is None: 556e5c31af7Sopenharmony_ci self.addEnumerator( 557e5c31af7Sopenharmony_ci e, 558e5c31af7Sopenharmony_ci requirementName, 559e5c31af7Sopenharmony_ci requirement.get("value"), 560e5c31af7Sopenharmony_ci requirement.get("offset"), 561e5c31af7Sopenharmony_ci requirement.get("extnumber"), 562e5c31af7Sopenharmony_ci requirement.get("bitpos"), 563e5c31af7Sopenharmony_ci requirement.get("dir")) 564e5c31af7Sopenharmony_ci elif not self.addAliasToEnumerator(e, requirementName, alias): 565e5c31af7Sopenharmony_ci self.tempAliasesList.append((e, requirementName, alias)) 566e5c31af7Sopenharmony_ci break 567e5c31af7Sopenharmony_ci elif requirement.tag == "type": 568e5c31af7Sopenharmony_ci typeList.append(requirementName) 569e5c31af7Sopenharmony_ci elif requirement.tag == "command": 570e5c31af7Sopenharmony_ci commandList.append(requirementName) 571e5c31af7Sopenharmony_ci requirementsList.append(FeatureRequirement( 572e5c31af7Sopenharmony_ci requirementGroup.tag, 573e5c31af7Sopenharmony_ci requirementGroup.get("comment"), 574e5c31af7Sopenharmony_ci enumList, 575e5c31af7Sopenharmony_ci typeList, 576e5c31af7Sopenharmony_ci commandList 577e5c31af7Sopenharmony_ci )) 578e5c31af7Sopenharmony_ci self.features.append(Feature( 579e5c31af7Sopenharmony_ci featureNode.get("api"), 580e5c31af7Sopenharmony_ci featureNode.get("name"), 581e5c31af7Sopenharmony_ci featureNode.get("number"), 582e5c31af7Sopenharmony_ci requirementsList 583e5c31af7Sopenharmony_ci )) 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci def readType (self, typeNode): 586e5c31af7Sopenharmony_ci name = typeNode.get("name") 587e5c31af7Sopenharmony_ci alias = typeNode.get("alias") 588e5c31af7Sopenharmony_ci category = typeNode.get("category") 589e5c31af7Sopenharmony_ci if category == "enum": 590e5c31af7Sopenharmony_ci if alias is None: 591e5c31af7Sopenharmony_ci self.enums.append(Enum(name)) 592e5c31af7Sopenharmony_ci else: 593e5c31af7Sopenharmony_ci for e in reversed(self.enums): 594e5c31af7Sopenharmony_ci if alias == e.name: 595e5c31af7Sopenharmony_ci e.alias = name 596e5c31af7Sopenharmony_ci break 597e5c31af7Sopenharmony_ci elif category == "handle": 598e5c31af7Sopenharmony_ci type = None 599e5c31af7Sopenharmony_ci if alias is None: 600e5c31af7Sopenharmony_ci name = typeNode.find("name").text 601e5c31af7Sopenharmony_ci type = typeNode.find("type").text 602e5c31af7Sopenharmony_ci self.handles.append(Handle( 603e5c31af7Sopenharmony_ci name, 604e5c31af7Sopenharmony_ci type, 605e5c31af7Sopenharmony_ci alias, 606e5c31af7Sopenharmony_ci typeNode.get("parent"), 607e5c31af7Sopenharmony_ci typeNode.get("objtypeenum"), 608e5c31af7Sopenharmony_ci )) 609e5c31af7Sopenharmony_ci else: 610e5c31af7Sopenharmony_ci for h in reversed(self.handles): 611e5c31af7Sopenharmony_ci if alias == h.name: 612e5c31af7Sopenharmony_ci h.alias = name 613e5c31af7Sopenharmony_ci break 614e5c31af7Sopenharmony_ci elif category == "basetype": 615e5c31af7Sopenharmony_ci # processing only those basetypes that have type child 616e5c31af7Sopenharmony_ci type = typeNode.find("type") 617e5c31af7Sopenharmony_ci if type is not None: 618e5c31af7Sopenharmony_ci self.basetypes[typeNode.find("name").text] = type.text 619e5c31af7Sopenharmony_ci elif category == "bitmask": 620e5c31af7Sopenharmony_ci # if node is alias then use the fact that alias definition follows aliased bitmasks; 621e5c31af7Sopenharmony_ci # in majoriti of cases it follows directly aliased bitmasks but in some cases there 622e5c31af7Sopenharmony_ci # is a unrelated bitmasks definition in between - to handle this traverse in reverse order 623e5c31af7Sopenharmony_ci if alias is not None: 624e5c31af7Sopenharmony_ci for bm in reversed(self.bitmasks): 625e5c31af7Sopenharmony_ci if alias == bm.name: 626e5c31af7Sopenharmony_ci bm.alias = name 627e5c31af7Sopenharmony_ci break 628e5c31af7Sopenharmony_ci else: 629e5c31af7Sopenharmony_ci self.bitmasks.append(Bitmask( 630e5c31af7Sopenharmony_ci typeNode.find("name").text, 631e5c31af7Sopenharmony_ci typeNode.find("type").text, 632e5c31af7Sopenharmony_ci typeNode.get("requires"), 633e5c31af7Sopenharmony_ci typeNode.get("bitvalues") 634e5c31af7Sopenharmony_ci )) 635e5c31af7Sopenharmony_ci elif category in ["struct", "union"]: 636e5c31af7Sopenharmony_ci # if node is alias then use the fact that alias definition follows aliased structure; 637e5c31af7Sopenharmony_ci # in majoriti of cases it follows directly aliased structure but in some cases there 638e5c31af7Sopenharmony_ci # is a unrelated structure definition in between - to handle this traverse in reverse order 639e5c31af7Sopenharmony_ci if alias is not None: 640e5c31af7Sopenharmony_ci for ct in reversed(self.compositeTypes): 641e5c31af7Sopenharmony_ci if alias == ct.name: 642e5c31af7Sopenharmony_ci ct.aliasList.append(name) 643e5c31af7Sopenharmony_ci break 644e5c31af7Sopenharmony_ci # go to next node 645e5c31af7Sopenharmony_ci return 646e5c31af7Sopenharmony_ci # read structure members 647e5c31af7Sopenharmony_ci structMembers = [] 648e5c31af7Sopenharmony_ci for memberNode in typeNode: 649e5c31af7Sopenharmony_ci if memberNode.tag != "member": 650e5c31af7Sopenharmony_ci continue 651e5c31af7Sopenharmony_ci # handle enum nodes that can be used for array dimensions 652e5c31af7Sopenharmony_ci arraySizeList = [] 653e5c31af7Sopenharmony_ci for node in memberNode: 654e5c31af7Sopenharmony_ci if node.tag == "enum": 655e5c31af7Sopenharmony_ci arraySizeList.append(node.text) 656e5c31af7Sopenharmony_ci # check if there are array dimension that are not enums 657e5c31af7Sopenharmony_ci if '[' in node.tail and len(node.tail) > 2: 658e5c31af7Sopenharmony_ci arraySizeList += node.tail.replace(']', ' ').replace('[', ' ').split() 659e5c31af7Sopenharmony_ci # handle additional text after name tag; it can represent array 660e5c31af7Sopenharmony_ci # size like in VkPipelineFragmentShadingRateEnumStateCreateInfoNV 661e5c31af7Sopenharmony_ci # or number of bits like in VkAccelerationStructureInstanceKHR 662e5c31af7Sopenharmony_ci nameNode = memberNode.find("name") 663e5c31af7Sopenharmony_ci nameTail = nameNode.tail 664e5c31af7Sopenharmony_ci fieldWidth = None 665e5c31af7Sopenharmony_ci if nameTail: 666e5c31af7Sopenharmony_ci if ':' in nameTail: 667e5c31af7Sopenharmony_ci fieldWidth = nameTail.replace(':', '').replace(' ', '') 668e5c31af7Sopenharmony_ci elif '[' in nameTail and ']' in nameTail: 669e5c31af7Sopenharmony_ci nameTail = nameTail.replace(']', ' ').replace('[', ' ') 670e5c31af7Sopenharmony_ci arraySizeList = nameTail.split() + arraySizeList 671e5c31af7Sopenharmony_ci # handle additional text after type tag; it can represent pointers like *pNext 672e5c31af7Sopenharmony_ci memberTypeNode = memberNode.find("type") 673e5c31af7Sopenharmony_ci pointer = memberTypeNode.tail.strip() if memberTypeNode.tail is not None else None 674e5c31af7Sopenharmony_ci structMembers.append(CompositeMember( 675e5c31af7Sopenharmony_ci nameNode.text, # name 676e5c31af7Sopenharmony_ci memberTypeNode.text, # type 677e5c31af7Sopenharmony_ci pointer, # pointer 678e5c31af7Sopenharmony_ci memberNode.text, # qualifiers 679e5c31af7Sopenharmony_ci arraySizeList, # arraySizeList 680e5c31af7Sopenharmony_ci memberNode.get("optional"), # optional 681e5c31af7Sopenharmony_ci memberNode.get("limittype"), # limittype 682e5c31af7Sopenharmony_ci memberNode.get("values"), # values 683e5c31af7Sopenharmony_ci fieldWidth # fieldWidth 684e5c31af7Sopenharmony_ci )) 685e5c31af7Sopenharmony_ci # create structure definition 686e5c31af7Sopenharmony_ci self.compositeTypes.append(Composite( 687e5c31af7Sopenharmony_ci name, 688e5c31af7Sopenharmony_ci category, 689e5c31af7Sopenharmony_ci typeNode.get("allowduplicate"), 690e5c31af7Sopenharmony_ci typeNode.get("structextends"), 691e5c31af7Sopenharmony_ci typeNode.get("returnedonly"), 692e5c31af7Sopenharmony_ci structMembers 693e5c31af7Sopenharmony_ci )) 694e5c31af7Sopenharmony_ci elif category == "define": 695e5c31af7Sopenharmony_ci nNode = typeNode.find("name") 696e5c31af7Sopenharmony_ci tNode = typeNode.find("type") 697e5c31af7Sopenharmony_ci if nNode == None or tNode == None: 698e5c31af7Sopenharmony_ci return 699e5c31af7Sopenharmony_ci requires = typeNode.get("requires") 700e5c31af7Sopenharmony_ci name = nNode.text 701e5c31af7Sopenharmony_ci if "API_VERSION_" in name or requires == "VK_MAKE_VIDEO_STD_VERSION": 702e5c31af7Sopenharmony_ci value = tNode.tail 703e5c31af7Sopenharmony_ci value = tNode.text + value[:value.find(')')+1] 704e5c31af7Sopenharmony_ci value = value.replace('VKSC_API_VARIANT', '1') 705e5c31af7Sopenharmony_ci self.defines.append(Define( 706e5c31af7Sopenharmony_ci name, 707e5c31af7Sopenharmony_ci "uint32_t", 708e5c31af7Sopenharmony_ci None, 709e5c31af7Sopenharmony_ci value 710e5c31af7Sopenharmony_ci )) 711e5c31af7Sopenharmony_ci else: 712e5c31af7Sopenharmony_ci requires = typeNode.get("requires") 713e5c31af7Sopenharmony_ci if requires == 'vk_platform': 714e5c31af7Sopenharmony_ci self.basicCTypes.append(name) 715e5c31af7Sopenharmony_ci 716e5c31af7Sopenharmony_ci def build (self, rawVkXml): 717e5c31af7Sopenharmony_ci # iterate over all *.xml root children 718e5c31af7Sopenharmony_ci for rootChild in rawVkXml.getroot(): 719e5c31af7Sopenharmony_ci 720e5c31af7Sopenharmony_ci # each enum is defined in separate enums node directly under root node 721e5c31af7Sopenharmony_ci if rootChild.tag == "enums": 722e5c31af7Sopenharmony_ci self.readEnum(rootChild) 723e5c31af7Sopenharmony_ci 724e5c31af7Sopenharmony_ci # read function definitions 725e5c31af7Sopenharmony_ci if rootChild.tag == "commands": 726e5c31af7Sopenharmony_ci commandsNode = rootChild 727e5c31af7Sopenharmony_ci for commandItem in commandsNode: 728e5c31af7Sopenharmony_ci self.readCommand(commandItem) 729e5c31af7Sopenharmony_ci 730e5c31af7Sopenharmony_ci # read vulkan versions 731e5c31af7Sopenharmony_ci if rootChild.tag == "feature": 732e5c31af7Sopenharmony_ci self.readFeature(rootChild) 733e5c31af7Sopenharmony_ci 734e5c31af7Sopenharmony_ci # read extensions 735e5c31af7Sopenharmony_ci if rootChild.tag == "extensions": 736e5c31af7Sopenharmony_ci extensionsNode = rootChild 737e5c31af7Sopenharmony_ci for extensionItem in extensionsNode: 738e5c31af7Sopenharmony_ci self.readExtension(extensionItem) 739e5c31af7Sopenharmony_ci 740e5c31af7Sopenharmony_ci # "types" is a first child of root so it's optimal to check for it 741e5c31af7Sopenharmony_ci # last and don't repeat this check for all other iterations 742e5c31af7Sopenharmony_ci if rootChild.tag == "types": 743e5c31af7Sopenharmony_ci typesNode = rootChild 744e5c31af7Sopenharmony_ci for typeItem in typesNode: 745e5c31af7Sopenharmony_ci self.readType(typeItem) 746e5c31af7Sopenharmony_ci 747e5c31af7Sopenharmony_ci # Verify that promotedto extensions are supported by the api 748e5c31af7Sopenharmony_ci for ext in self.extensions: 749e5c31af7Sopenharmony_ci if ext.promotedto is not None and "VK_VERSION" not in ext.promotedto: 750e5c31af7Sopenharmony_ci if not any(x.name == ext.promotedto for x in self.extensions): 751e5c31af7Sopenharmony_ci ext.promotedto = None 752e5c31af7Sopenharmony_ci 753e5c31af7Sopenharmony_ci def postProcess (self): 754e5c31af7Sopenharmony_ci 755e5c31af7Sopenharmony_ci # temporary workaround for extensions that are marked only for vulkan api in xml while 756e5c31af7Sopenharmony_ci # they are need by vulkan_json_data.hpp and vulkan_json_parser.hpp in vulkansc 757e5c31af7Sopenharmony_ci if self.apiName == "vulkansc": 758e5c31af7Sopenharmony_ci deviceDiagnosticCheckpoints = [e for e in self.notSupportedExtensions if e.name == "VK_NV_device_diagnostic_checkpoints"] 759e5c31af7Sopenharmony_ci if len(deviceDiagnosticCheckpoints): 760e5c31af7Sopenharmony_ci deviceDiagnosticCheckpoints = deviceDiagnosticCheckpoints[0] 761e5c31af7Sopenharmony_ci self.extensions.append(deviceDiagnosticCheckpoints) 762e5c31af7Sopenharmony_ci self.notSupportedExtensions.remove(deviceDiagnosticCheckpoints) 763e5c31af7Sopenharmony_ci formatFeatureFlags2 = [e for e in self.notSupportedExtensions if e.name == "VK_KHR_format_feature_flags2"] 764e5c31af7Sopenharmony_ci if len(formatFeatureFlags2): 765e5c31af7Sopenharmony_ci formatFeatureFlags2 = formatFeatureFlags2[0] 766e5c31af7Sopenharmony_ci self.extensions.append(formatFeatureFlags2) 767e5c31af7Sopenharmony_ci self.notSupportedExtensions.remove(formatFeatureFlags2) 768e5c31af7Sopenharmony_ci 769e5c31af7Sopenharmony_ci # add new enumerators that were added by extensions to api.enums 770e5c31af7Sopenharmony_ci # we have to do it at the end for SC becouse some enums are dependednt from extensions/api versions 771e5c31af7Sopenharmony_ci # and those dependencies can be checked only after all extensions were read 772e5c31af7Sopenharmony_ci for ext in self.extensions: 773e5c31af7Sopenharmony_ci for requirement in ext.requirementsList: 774e5c31af7Sopenharmony_ci # check if this requirement is supported by current implementation 775e5c31af7Sopenharmony_ci isRequirementSupported = True 776e5c31af7Sopenharmony_ci dependencies = requirement.depends 777e5c31af7Sopenharmony_ci if dependencies is not None: 778e5c31af7Sopenharmony_ci # check if dependency extension or api version is part of this api 779e5c31af7Sopenharmony_ci # note: this logic will have to changed if there are dependencies with "and/or" grammar 780e5c31af7Sopenharmony_ci assert((',' not in dependencies) or ('+' not in dependencies)) 781e5c31af7Sopenharmony_ci isRequirementSupported = '_VERSION_' in dependencies 782e5c31af7Sopenharmony_ci if isRequirementSupported == False: 783e5c31af7Sopenharmony_ci for e in self.extensions: 784e5c31af7Sopenharmony_ci if e.name in dependencies: 785e5c31af7Sopenharmony_ci isRequirementSupported = True 786e5c31af7Sopenharmony_ci break 787e5c31af7Sopenharmony_ci # add enumerator to proper enum from api.enums 788e5c31af7Sopenharmony_ci if isRequirementSupported: 789e5c31af7Sopenharmony_ci for enumerator in requirement.extendedEnums: 790e5c31af7Sopenharmony_ci if enumerator.extends is None: 791e5c31af7Sopenharmony_ci continue 792e5c31af7Sopenharmony_ci # find enum in api.enums 793e5c31af7Sopenharmony_ci matchedEnum = [enum for enum in api.enums if enumerator.extends == enum.name][0] 794e5c31af7Sopenharmony_ci # add enumerator only when it is not already in enum 795e5c31af7Sopenharmony_ci if len([e for e in matchedEnum.enumeratorList if e.name == enumerator.name]) == 0: 796e5c31af7Sopenharmony_ci if enumerator.alias == None: 797e5c31af7Sopenharmony_ci self.addEnumerator( 798e5c31af7Sopenharmony_ci matchedEnum, 799e5c31af7Sopenharmony_ci enumerator.name, 800e5c31af7Sopenharmony_ci enumerator.value, 801e5c31af7Sopenharmony_ci enumerator.offset, 802e5c31af7Sopenharmony_ci enumerator.extnumber if enumerator.extnumber else ext.number, 803e5c31af7Sopenharmony_ci enumerator.bitpos, 804e5c31af7Sopenharmony_ci enumerator.dir) 805e5c31af7Sopenharmony_ci elif not self.addAliasToEnumerator(matchedEnum, enumerator.name, enumerator.alias): 806e5c31af7Sopenharmony_ci # we might not be able to add alias as we might be missing what we are aliasing 807e5c31af7Sopenharmony_ci # this will hapen when aliased enum is added later then definition of alias 808e5c31af7Sopenharmony_ci self.tempAliasesList.append((matchedEnum, enumerator.name, enumerator.alias)) 809e5c31af7Sopenharmony_ci 810e5c31af7Sopenharmony_ci # add aliases to enumerators that were defined after alias definition 811e5c31af7Sopenharmony_ci for enum, name, alias in self.tempAliasesList: 812e5c31af7Sopenharmony_ci if not self.addAliasToEnumerator(enum, name, alias): 813e5c31af7Sopenharmony_ci # if enumerator that should be aliased was not found then try to insert it without alias 814e5c31af7Sopenharmony_ci # (this happens for vulkansc as in xml enumerator might be defined in extension that is not supported by sc) 815e5c31af7Sopenharmony_ci def tryToFindEnumValue(searchedName): 816e5c31af7Sopenharmony_ci for nsExt in self.notSupportedExtensions: 817e5c31af7Sopenharmony_ci for r in nsExt.requirementsList: 818e5c31af7Sopenharmony_ci for enumerator in r.extendedEnums: 819e5c31af7Sopenharmony_ci if enumerator.name == searchedName: 820e5c31af7Sopenharmony_ci self.addEnumerator( 821e5c31af7Sopenharmony_ci enum, 822e5c31af7Sopenharmony_ci name, 823e5c31af7Sopenharmony_ci enumerator.value, 824e5c31af7Sopenharmony_ci enumerator.offset, 825e5c31af7Sopenharmony_ci enumerator.extnumber if enumerator.extnumber else ext.number, 826e5c31af7Sopenharmony_ci enumerator.bitpos, 827e5c31af7Sopenharmony_ci enumerator.dir) 828e5c31af7Sopenharmony_ci # there are ~2 cases where alias that is not part of SC still needs to be added for SC 829e5c31af7Sopenharmony_ci self.addAliasToEnumerator(enum, alias, name) 830e5c31af7Sopenharmony_ci return 831e5c31af7Sopenharmony_ci # using function for easy stack unwinding 832e5c31af7Sopenharmony_ci tryToFindEnumValue(alias) 833e5c31af7Sopenharmony_ci self.tempAliasesList = None 834e5c31af7Sopenharmony_ci 835e5c31af7Sopenharmony_ci if self.apiName == "vulkan": 836e5c31af7Sopenharmony_ci def removeExtensionFromApi(extName, structureNameList, commandNameList): 837e5c31af7Sopenharmony_ci extObjectList = [e for e in api.extensions if e.name == extName] 838e5c31af7Sopenharmony_ci if len(extObjectList) > 0: 839e5c31af7Sopenharmony_ci api.extensions.remove(extObjectList[0]) 840e5c31af7Sopenharmony_ci structObjectList = [ct for ct in api.compositeTypes if ct.name in structureNameList] 841e5c31af7Sopenharmony_ci for s in structObjectList: 842e5c31af7Sopenharmony_ci api.compositeTypes.remove(s) 843e5c31af7Sopenharmony_ci commandObjectList = [f for f in api.functions if f.name in commandNameList] 844e5c31af7Sopenharmony_ci for f in commandObjectList: 845e5c31af7Sopenharmony_ci api.functions.remove(f) 846e5c31af7Sopenharmony_ci 847e5c31af7Sopenharmony_ci # remove structures and commands added by VK_EXT_directfb_surface extension 848e5c31af7Sopenharmony_ci removeExtensionFromApi("VK_EXT_directfb_surface", 849e5c31af7Sopenharmony_ci ["VkDirectFBSurfaceCreateFlagsEXT", "VkDirectFBSurfaceCreateInfoEXT"], 850e5c31af7Sopenharmony_ci ["vkCreateDirectFBSurfaceEXT", "vkGetPhysicalDeviceDirectFBPresentationSupportEXT"]) 851e5c31af7Sopenharmony_ci 852e5c31af7Sopenharmony_ci # remove structures and commands added by disabled VK_ANDROID_native_buffer extension; 853e5c31af7Sopenharmony_ci # disabled extensions aren't read but their structures and commands will be in types and commands sections in vk.xml 854e5c31af7Sopenharmony_ci removeExtensionFromApi("VK_ANDROID_native_buffer", 855e5c31af7Sopenharmony_ci ["VkNativeBufferANDROID", "VkSwapchainImageCreateInfoANDROID", 856e5c31af7Sopenharmony_ci "VkPhysicalDevicePresentationPropertiesANDROID", "VkNativeBufferUsage2ANDROID", 857e5c31af7Sopenharmony_ci "VkSwapchainImageUsageFlagBitsANDROID", "VkSwapchainImageUsageFlagsANDROID"], 858e5c31af7Sopenharmony_ci ["vkGetSwapchainGrallocUsageANDROID", "vkAcquireImageANDROID", 859e5c31af7Sopenharmony_ci "vkQueueSignalReleaseImageANDROID", "vkGetSwapchainGrallocUsage2ANDROID"]) 860e5c31af7Sopenharmony_ci 861e5c31af7Sopenharmony_ci # remove empty enums e.g. VkQueryPoolCreateFlagBits, VkDeviceCreateFlagBits 862e5c31af7Sopenharmony_ci enumsToRemove = [enum for enum in self.enums if len(enum.enumeratorList) == 0] 863e5c31af7Sopenharmony_ci for er in enumsToRemove: 864e5c31af7Sopenharmony_ci self.enums.remove(er) 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci # add alias for VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR (in vk.xml for this struct alias is defined before struct 867e5c31af7Sopenharmony_ci # where in all other cases it is defined after structure definition) 868e5c31af7Sopenharmony_ci barycentricFeaturesStruct = [c for c in api.compositeTypes if c.name == 'VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR'][0] 869e5c31af7Sopenharmony_ci barycentricFeaturesStruct.aliasList.append('VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV') 870e5c31af7Sopenharmony_ci 871e5c31af7Sopenharmony_ci elif self.apiName == "vulkansc": 872e5c31af7Sopenharmony_ci # remove commands that are marked with <remove> tag in SC feature specification; 873e5c31af7Sopenharmony_ci # e.g. there is no vkCreateShaderModule in SC 874e5c31af7Sopenharmony_ci functionsToRemove = [] 875e5c31af7Sopenharmony_ci scFeatures = [f for f in self.features if f.api == "vulkansc"][0] 876e5c31af7Sopenharmony_ci for featureRequirement in scFeatures.requirementsList: 877e5c31af7Sopenharmony_ci if featureRequirement.operation == "remove": 878e5c31af7Sopenharmony_ci for removeFun in featureRequirement.commandList: 879e5c31af7Sopenharmony_ci # find function in the list of all functions 880e5c31af7Sopenharmony_ci for fun in self.functions: 881e5c31af7Sopenharmony_ci if removeFun == fun.name: 882e5c31af7Sopenharmony_ci functionsToRemove.append(fun) 883e5c31af7Sopenharmony_ci break 884e5c31af7Sopenharmony_ci for fun in functionsToRemove: 885e5c31af7Sopenharmony_ci self.functions.remove(fun) 886e5c31af7Sopenharmony_ci # sc is based on vk1.2 so we need to check features of vk1.3+ 887e5c31af7Sopenharmony_ci # and rename functions and structures that were promoted in 888e5c31af7Sopenharmony_ci # those versions to their previous names (aliases) 889e5c31af7Sopenharmony_ci renamedStructuresDict = {} 890e5c31af7Sopenharmony_ci for feature in self.features: 891e5c31af7Sopenharmony_ci # skip vk versions smaller than 1.3 892e5c31af7Sopenharmony_ci if int(feature.number[-1]) < 3: 893e5c31af7Sopenharmony_ci continue 894e5c31af7Sopenharmony_ci # iterate over all requirements and enums/commands/structs added in them 895e5c31af7Sopenharmony_ci for featureRequirement in feature.requirementsList: 896e5c31af7Sopenharmony_ci for promotedEnumerator in featureRequirement.enumList: 897e5c31af7Sopenharmony_ci # iterate over all enums and find one that was extended 898e5c31af7Sopenharmony_ci for enum in self.enums: 899e5c31af7Sopenharmony_ci if enum.name != promotedEnumerator.extends: 900e5c31af7Sopenharmony_ci continue 901e5c31af7Sopenharmony_ci enumeratorReplaced = False 902e5c31af7Sopenharmony_ci # find enumerator that should have changed name 903e5c31af7Sopenharmony_ci for enumerator in enum.enumeratorList: 904e5c31af7Sopenharmony_ci if enumerator.name != promotedEnumerator.name or len(enumerator.aliasList) == 0: 905e5c31af7Sopenharmony_ci continue 906e5c31af7Sopenharmony_ci # replace enumerator name with its first alias 907e5c31af7Sopenharmony_ci enumerator.name = enumerator.aliasList[0] 908e5c31af7Sopenharmony_ci enumerator.aliasList = enumerator.aliasList[1:] 909e5c31af7Sopenharmony_ci # first member of almost all structures is VkStructureType and in xml that member 910e5c31af7Sopenharmony_ci # has defined value - we need to change those values to versions supported by SC 911e5c31af7Sopenharmony_ci if "STRUCTURE_TYPE" in enumerator.name: 912e5c31af7Sopenharmony_ci for struct in self.compositeTypes: 913e5c31af7Sopenharmony_ci if struct.members[0].values == promotedEnumerator.name: 914e5c31af7Sopenharmony_ci struct.members[0].values = enumerator.name 915e5c31af7Sopenharmony_ci break 916e5c31af7Sopenharmony_ci enumeratorReplaced = True 917e5c31af7Sopenharmony_ci break 918e5c31af7Sopenharmony_ci if enumeratorReplaced: 919e5c31af7Sopenharmony_ci break 920e5c31af7Sopenharmony_ci renamedFunctionsList = [] 921e5c31af7Sopenharmony_ci for promotedFun in featureRequirement.commandList: 922e5c31af7Sopenharmony_ci # find promotedFun in list of all functions 923e5c31af7Sopenharmony_ci for fun in self.functions: 924e5c31af7Sopenharmony_ci if fun.name != promotedFun: 925e5c31af7Sopenharmony_ci continue 926e5c31af7Sopenharmony_ci # replace function name with its first alias 927e5c31af7Sopenharmony_ci fun.name = fun.aliasList[0] 928e5c31af7Sopenharmony_ci fun.aliasList = fun.aliasList[1:] 929e5c31af7Sopenharmony_ci # memorize renamed functions 930e5c31af7Sopenharmony_ci renamedFunctionsList.append(fun) 931e5c31af7Sopenharmony_ci break 932e5c31af7Sopenharmony_ci for promotedStruct in featureRequirement.typeList: 933e5c31af7Sopenharmony_ci # find promotedStruct in list of all structures 934e5c31af7Sopenharmony_ci for struct in self.compositeTypes: 935e5c31af7Sopenharmony_ci if struct.name != promotedStruct: 936e5c31af7Sopenharmony_ci continue 937e5c31af7Sopenharmony_ci # skip structures without alias 938e5c31af7Sopenharmony_ci if len(struct.aliasList) == 0: 939e5c31af7Sopenharmony_ci break 940e5c31af7Sopenharmony_ci # replace struct name with its first alias 941e5c31af7Sopenharmony_ci struct.name = struct.aliasList[0] 942e5c31af7Sopenharmony_ci struct.aliasList = struct.aliasList[1:] 943e5c31af7Sopenharmony_ci # memorize all renamed structures 944e5c31af7Sopenharmony_ci renamedStructuresDict[promotedStruct] = struct 945e5c31af7Sopenharmony_ci # check all all renamed functions and make sure that argument types are also renamed 946e5c31af7Sopenharmony_ci for renamedFun in renamedFunctionsList: 947e5c31af7Sopenharmony_ci for arg in renamedFun.arguments: 948e5c31af7Sopenharmony_ci if arg.type == promotedStruct: 949e5c31af7Sopenharmony_ci arg.type = struct.name 950e5c31af7Sopenharmony_ci break 951e5c31af7Sopenharmony_ci # iterate over all renamed structures and make sure that all their attributes are also renamed 952e5c31af7Sopenharmony_ci for newName in renamedStructuresDict: 953e5c31af7Sopenharmony_ci for member in renamedStructuresDict[newName].members: 954e5c31af7Sopenharmony_ci if member.type in renamedStructuresDict: 955e5c31af7Sopenharmony_ci member.type = renamedStructuresDict[member.type].name 956e5c31af7Sopenharmony_ci 957e5c31af7Sopenharmony_ci # remove enums that are not part of any vulkan version nor extension 958e5c31af7Sopenharmony_ci # (SC specific enums are in vk.xml without any attribute identifying that they are SC specific; same for enums for disabled extensions) 959e5c31af7Sopenharmony_ci def isEnumUsed(featureList, extensionList, enumName, enumAlias): 960e5c31af7Sopenharmony_ci for feature in featureList: 961e5c31af7Sopenharmony_ci for requirement in feature.requirementsList: 962e5c31af7Sopenharmony_ci for typeName in requirement.typeList: 963e5c31af7Sopenharmony_ci if (typeName == enumName) or (typeName == enumAlias): 964e5c31af7Sopenharmony_ci return True 965e5c31af7Sopenharmony_ci for ext in extensionList: 966e5c31af7Sopenharmony_ci for requirement in ext.requirementsList: 967e5c31af7Sopenharmony_ci for newType in requirement.newTypes: 968e5c31af7Sopenharmony_ci if (newType.name == enumName) or (newType.name == enumAlias): 969e5c31af7Sopenharmony_ci return True 970e5c31af7Sopenharmony_ci return False 971e5c31af7Sopenharmony_ci # do removal using above function 972e5c31af7Sopenharmony_ci enumsToRemove = [] 973e5c31af7Sopenharmony_ci for enum in self.enums: 974e5c31af7Sopenharmony_ci if isEnumUsed(self.features, self.extensions, enum.name, enum.alias): 975e5c31af7Sopenharmony_ci continue 976e5c31af7Sopenharmony_ci enumsToRemove.append(enum) 977e5c31af7Sopenharmony_ci for er in enumsToRemove: 978e5c31af7Sopenharmony_ci self.enums.remove(er) 979e5c31af7Sopenharmony_ci 980e5c31af7Sopenharmony_ci # helper function that check if dependency is in list of extension 981e5c31af7Sopenharmony_ci def isDependencyMeet(dependency, extensionList): 982e5c31af7Sopenharmony_ci if dependency == None: 983e5c31af7Sopenharmony_ci return True 984e5c31af7Sopenharmony_ci # check if requirement dependencies are meet; if not then struct/function is not used 985e5c31af7Sopenharmony_ci # note: this logic will have to changed if there are dependencies with "and/or" grammar 986e5c31af7Sopenharmony_ci if '_VERSION_' in dependency: 987e5c31af7Sopenharmony_ci return True 988e5c31af7Sopenharmony_ci dependency = dependency.split(',')[0] 989e5c31af7Sopenharmony_ci for e in extensionList: 990e5c31af7Sopenharmony_ci if dependency == e.name: 991e5c31af7Sopenharmony_ci return True 992e5c31af7Sopenharmony_ci return False 993e5c31af7Sopenharmony_ci 994e5c31af7Sopenharmony_ci # remove structures that are not part of any vulkan version nor extension 995e5c31af7Sopenharmony_ci # (SC specific structures are in vk.xml without any attribute identifying that they are SC specific) 996e5c31af7Sopenharmony_ci def isStructUsed(featureList, extensionList, structNameList): 997e5c31af7Sopenharmony_ci for feature in featureList: 998e5c31af7Sopenharmony_ci for requirement in feature.requirementsList: 999e5c31af7Sopenharmony_ci for typeName in requirement.typeList: 1000e5c31af7Sopenharmony_ci if typeName in structNameList: 1001e5c31af7Sopenharmony_ci return True 1002e5c31af7Sopenharmony_ci for ext in extensionList: 1003e5c31af7Sopenharmony_ci for requirement in ext.requirementsList: 1004e5c31af7Sopenharmony_ci for newType in requirement.newTypes: 1005e5c31af7Sopenharmony_ci if newType.name in structNameList: 1006e5c31af7Sopenharmony_ci return isDependencyMeet(requirement.depends, extensionList) 1007e5c31af7Sopenharmony_ci return False 1008e5c31af7Sopenharmony_ci 1009e5c31af7Sopenharmony_ci structsToRemove = [] 1010e5c31af7Sopenharmony_ci for struct in self.compositeTypes: 1011e5c31af7Sopenharmony_ci structNameList = [struct.name] + struct.aliasList 1012e5c31af7Sopenharmony_ci if isStructUsed(self.features, self.extensions, structNameList): 1013e5c31af7Sopenharmony_ci continue 1014e5c31af7Sopenharmony_ci structsToRemove.append(struct) 1015e5c31af7Sopenharmony_ci for st in structsToRemove: 1016e5c31af7Sopenharmony_ci self.compositeTypes.remove(st) 1017e5c31af7Sopenharmony_ci 1018e5c31af7Sopenharmony_ci # remove commands that are not part of any vulkan version nor extension 1019e5c31af7Sopenharmony_ci # (SC specific commands are in vk.xml without any attribute identifying that they are SC specific) 1020e5c31af7Sopenharmony_ci def isFunctionUsed(featureList, extensionList, functionNameList): 1021e5c31af7Sopenharmony_ci for feature in featureList: 1022e5c31af7Sopenharmony_ci for requirement in feature.requirementsList: 1023e5c31af7Sopenharmony_ci for commandName in requirement.commandList: 1024e5c31af7Sopenharmony_ci if commandName in functionNameList: 1025e5c31af7Sopenharmony_ci return True 1026e5c31af7Sopenharmony_ci for ext in extensionList: 1027e5c31af7Sopenharmony_ci for requirement in ext.requirementsList: 1028e5c31af7Sopenharmony_ci for newCommand in requirement.newCommands: 1029e5c31af7Sopenharmony_ci if newCommand.name in functionNameList: 1030e5c31af7Sopenharmony_ci return isDependencyMeet(requirement.depends, extensionList) 1031e5c31af7Sopenharmony_ci return False 1032e5c31af7Sopenharmony_ci 1033e5c31af7Sopenharmony_ci functionsToRemove = [] 1034e5c31af7Sopenharmony_ci for fun in self.functions: 1035e5c31af7Sopenharmony_ci functionNameList = [fun.name] + fun.aliasList 1036e5c31af7Sopenharmony_ci if isFunctionUsed(self.features, self.extensions, functionNameList): 1037e5c31af7Sopenharmony_ci continue 1038e5c31af7Sopenharmony_ci functionsToRemove.append(fun) 1039e5c31af7Sopenharmony_ci for fun in functionsToRemove: 1040e5c31af7Sopenharmony_ci self.functions.remove(fun) 1041e5c31af7Sopenharmony_ci 1042e5c31af7Sopenharmony_ci # remove handles that are not part of any vulkan command or structure 1043e5c31af7Sopenharmony_ci def isHandleUsed(structList, functionList, handleName): 1044e5c31af7Sopenharmony_ci for struct in structList: 1045e5c31af7Sopenharmony_ci for member in struct.members: 1046e5c31af7Sopenharmony_ci if handleName in member.type: 1047e5c31af7Sopenharmony_ci return True 1048e5c31af7Sopenharmony_ci for fun in functionList: 1049e5c31af7Sopenharmony_ci for arg in fun.arguments: 1050e5c31af7Sopenharmony_ci if handleName in arg.type: 1051e5c31af7Sopenharmony_ci return True 1052e5c31af7Sopenharmony_ci return False 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_ci handlesToRemove = [] 1055e5c31af7Sopenharmony_ci for h in self.handles: 1056e5c31af7Sopenharmony_ci if isHandleUsed(self.compositeTypes, self.functions, h.name): 1057e5c31af7Sopenharmony_ci continue 1058e5c31af7Sopenharmony_ci handlesToRemove.append(h) 1059e5c31af7Sopenharmony_ci for h in handlesToRemove: 1060e5c31af7Sopenharmony_ci self.handles.remove(h) 1061e5c31af7Sopenharmony_ci 1062e5c31af7Sopenharmony_ci # sort enumerators in enums 1063e5c31af7Sopenharmony_ci sortLambda = lambda enumerator: int(enumerator.bitpos) if enumerator.value is None else int(enumerator.value, 16 if 'x' in enumerator.value else 10) 1064e5c31af7Sopenharmony_ci for enum in self.enums: 1065e5c31af7Sopenharmony_ci # skip enums that have no items or just one in enumeratorList (e.g. VkQueryPoolCreateFlagBits) 1066e5c31af7Sopenharmony_ci if len(enum.enumeratorList) < 2: 1067e5c31af7Sopenharmony_ci continue 1068e5c31af7Sopenharmony_ci # construct list of enumerators in which value and bitpos are not None 1069e5c31af7Sopenharmony_ci enumeratorsToSort = [e for e in enum.enumeratorList if e.value != e.bitpos] 1070e5c31af7Sopenharmony_ci # construct list of enumerators in which value and bitpos are equal to None 1071e5c31af7Sopenharmony_ci remainingEnumerators = [e for e in enum.enumeratorList if e.value == e.bitpos] 1072e5c31af7Sopenharmony_ci # construct sorted enumerator list with aliases at the end 1073e5c31af7Sopenharmony_ci enum.enumeratorList = sorted(enumeratorsToSort, key=sortLambda) 1074e5c31af7Sopenharmony_ci enum.enumeratorList.extend(remainingEnumerators) 1075e5c31af7Sopenharmony_ci 1076e5c31af7Sopenharmony_cidef prefixName (prefix, name): 1077e5c31af7Sopenharmony_ci name = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', name[2:]) 1078e5c31af7Sopenharmony_ci name = re.sub(r'([a-zA-Z])([0-9])', r'\1_\2', name) 1079e5c31af7Sopenharmony_ci name = name.upper() 1080e5c31af7Sopenharmony_ci return prefix + name 1081e5c31af7Sopenharmony_ci 1082e5c31af7Sopenharmony_cidef parseInt (value): 1083e5c31af7Sopenharmony_ci return int(value, 16 if ("0x" in value) else 10) 1084e5c31af7Sopenharmony_ci 1085e5c31af7Sopenharmony_cidef getApiVariantIndexByName(variantName): 1086e5c31af7Sopenharmony_ci apiVariant = { 1087e5c31af7Sopenharmony_ci None : 0, 1088e5c31af7Sopenharmony_ci '' : 0, 1089e5c31af7Sopenharmony_ci 'SC' : 1 1090e5c31af7Sopenharmony_ci } 1091e5c31af7Sopenharmony_ci return apiVariant[variantName] 1092e5c31af7Sopenharmony_ci 1093e5c31af7Sopenharmony_cidef getApiVariantNameByIndex(variantIndex): 1094e5c31af7Sopenharmony_ci apiVariant = { 1095e5c31af7Sopenharmony_ci None : '', 1096e5c31af7Sopenharmony_ci 0 : '', 1097e5c31af7Sopenharmony_ci 1 : 'SC' 1098e5c31af7Sopenharmony_ci } 1099e5c31af7Sopenharmony_ci return apiVariant[variantIndex] 1100e5c31af7Sopenharmony_ci 1101e5c31af7Sopenharmony_cidef readFile (filename): 1102e5c31af7Sopenharmony_ci with open(filename, 'rt') as f: 1103e5c31af7Sopenharmony_ci return f.read() 1104e5c31af7Sopenharmony_ci 1105e5c31af7Sopenharmony_cidef getInterfaceName (functionName): 1106e5c31af7Sopenharmony_ci assert functionName[:2] == "vk" 1107e5c31af7Sopenharmony_ci return functionName[2].lower() + functionName[3:] 1108e5c31af7Sopenharmony_ci 1109e5c31af7Sopenharmony_cidef getFunctionTypeName (functionName): 1110e5c31af7Sopenharmony_ci assert functionName[:2] == "vk" 1111e5c31af7Sopenharmony_ci return functionName[2:] + "Func" 1112e5c31af7Sopenharmony_ci 1113e5c31af7Sopenharmony_cidef endsWith (str, postfix): 1114e5c31af7Sopenharmony_ci return str[-len(postfix):] == postfix 1115e5c31af7Sopenharmony_ci 1116e5c31af7Sopenharmony_cidef writeHandleType (api, filename): 1117e5c31af7Sopenharmony_ci 1118e5c31af7Sopenharmony_ci def getHandleName (name): 1119e5c31af7Sopenharmony_ci return prefixName("HANDLE_TYPE_", name) 1120e5c31af7Sopenharmony_ci 1121e5c31af7Sopenharmony_ci def genHandles (): 1122e5c31af7Sopenharmony_ci yield "\t%s\t= 0," % getHandleName(api.handles[0].name) 1123e5c31af7Sopenharmony_ci for h in api.handles[1:]: 1124e5c31af7Sopenharmony_ci yield "\t%s," % getHandleName(h.name) 1125e5c31af7Sopenharmony_ci for h in api.handles: 1126e5c31af7Sopenharmony_ci if h.alias is not None: 1127e5c31af7Sopenharmony_ci yield "\t%s\t= %s," % (getHandleName(h.alias), getHandleName(h.name)) 1128e5c31af7Sopenharmony_ci yield "\tHANDLE_TYPE_LAST\t= %s + 1" % (getHandleName(api.handles[-1].name)) 1129e5c31af7Sopenharmony_ci 1130e5c31af7Sopenharmony_ci def genHandlesBlock (): 1131e5c31af7Sopenharmony_ci yield "enum HandleType" 1132e5c31af7Sopenharmony_ci yield "{" 1133e5c31af7Sopenharmony_ci 1134e5c31af7Sopenharmony_ci for line in indentLines(genHandles()): 1135e5c31af7Sopenharmony_ci yield line 1136e5c31af7Sopenharmony_ci 1137e5c31af7Sopenharmony_ci yield "};" 1138e5c31af7Sopenharmony_ci yield "" 1139e5c31af7Sopenharmony_ci 1140e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, genHandlesBlock()) 1141e5c31af7Sopenharmony_ci 1142e5c31af7Sopenharmony_cidef getEnumValuePrefixAndPostfix (enum): 1143e5c31af7Sopenharmony_ci prefix = enum.name[0] 1144e5c31af7Sopenharmony_ci for i in range(1, len(enum.name)): 1145e5c31af7Sopenharmony_ci if enum.name[i].isupper() and not enum.name[i-1].isupper(): 1146e5c31af7Sopenharmony_ci prefix += "_" 1147e5c31af7Sopenharmony_ci prefix += enum.name[i].upper() 1148e5c31af7Sopenharmony_ci for p in EXTENSION_POSTFIXES: 1149e5c31af7Sopenharmony_ci if prefix.endswith(p): 1150e5c31af7Sopenharmony_ci return prefix[:-len(p)-1], '_'+p 1151e5c31af7Sopenharmony_ci return prefix, '' 1152e5c31af7Sopenharmony_ci 1153e5c31af7Sopenharmony_cidef genEnumSrc (enum): 1154e5c31af7Sopenharmony_ci yield "enum %s" % enum.name 1155e5c31af7Sopenharmony_ci yield "{" 1156e5c31af7Sopenharmony_ci lines = [] 1157e5c31af7Sopenharmony_ci for ed in enum.enumeratorList: 1158e5c31af7Sopenharmony_ci if ed.value is not None: 1159e5c31af7Sopenharmony_ci lines.append(f"\t{ed.name}\t= {ed.value},") 1160e5c31af7Sopenharmony_ci for ed in enum.enumeratorList: 1161e5c31af7Sopenharmony_ci for alias in ed.aliasList: 1162e5c31af7Sopenharmony_ci lines.append(f"\t{alias}\t= {ed.name},") 1163e5c31af7Sopenharmony_ci 1164e5c31af7Sopenharmony_ci # add *_LAST item when enum is linear 1165e5c31af7Sopenharmony_ci prefix, postfix = getEnumValuePrefixAndPostfix(enum) 1166e5c31af7Sopenharmony_ci if enum.areValuesLinear(): 1167e5c31af7Sopenharmony_ci lines.append(f"\t{prefix}{postfix}_LAST,") 1168e5c31af7Sopenharmony_ci 1169e5c31af7Sopenharmony_ci # add _MAX_ENUM item with the ext postifix at the end 1170e5c31af7Sopenharmony_ci lines.append(f"\t{prefix}_MAX_ENUM{postfix}\t= 0x7FFFFFFF") 1171e5c31af7Sopenharmony_ci 1172e5c31af7Sopenharmony_ci for line in indentLines(lines): 1173e5c31af7Sopenharmony_ci yield line 1174e5c31af7Sopenharmony_ci 1175e5c31af7Sopenharmony_ci yield "};" 1176e5c31af7Sopenharmony_ci 1177e5c31af7Sopenharmony_cidef genBitfieldSrc (bitfield): 1178e5c31af7Sopenharmony_ci lines = [] 1179e5c31af7Sopenharmony_ci for ev in bitfield.enumeratorList: 1180e5c31af7Sopenharmony_ci # bitfields may use mix of bitpos and values 1181e5c31af7Sopenharmony_ci if ev.bitpos is not None: 1182e5c31af7Sopenharmony_ci value = pow(2, int(ev.bitpos)) 1183e5c31af7Sopenharmony_ci lines.append(f"\t{ev.name}\t= {value:#010x},") 1184e5c31af7Sopenharmony_ci if ev.value is not None: 1185e5c31af7Sopenharmony_ci lines.append(f"\t{ev.name}\t= {ev.value},") 1186e5c31af7Sopenharmony_ci for ev in bitfield.enumeratorList: 1187e5c31af7Sopenharmony_ci for alias in ev.aliasList: 1188e5c31af7Sopenharmony_ci lines.append(f"\t{alias}\t= {ev.name},") 1189e5c31af7Sopenharmony_ci # add _MAX_ENUM item 1190e5c31af7Sopenharmony_ci prefix, postfix = getEnumValuePrefixAndPostfix(bitfield) 1191e5c31af7Sopenharmony_ci lines.append(f"\t{prefix}_MAX_ENUM{postfix}\t= 0x7FFFFFFF") 1192e5c31af7Sopenharmony_ci yield f"enum {bitfield.name}" 1193e5c31af7Sopenharmony_ci yield "{" 1194e5c31af7Sopenharmony_ci for line in indentLines(lines): 1195e5c31af7Sopenharmony_ci yield line 1196e5c31af7Sopenharmony_ci yield "};" 1197e5c31af7Sopenharmony_ci 1198e5c31af7Sopenharmony_cidef genBitfield64Src (bitfield64): 1199e5c31af7Sopenharmony_ci def generateEntry(lines, bitfieldName, entryName, bitpos, value): 1200e5c31af7Sopenharmony_ci if entryName is None: 1201e5c31af7Sopenharmony_ci return 1202e5c31af7Sopenharmony_ci # bitfields may use mix of bitpos and values 1203e5c31af7Sopenharmony_ci if ev.bitpos is not None: 1204e5c31af7Sopenharmony_ci v = pow(2, int(bitpos)) 1205e5c31af7Sopenharmony_ci lines.append(f"static const {bitfieldName} {entryName}\t= {v:#010x}ULL;") 1206e5c31af7Sopenharmony_ci if value is not None: 1207e5c31af7Sopenharmony_ci lines.append(f"static const {bitfieldName} {entryName}\t= {value}ULL;") 1208e5c31af7Sopenharmony_ci 1209e5c31af7Sopenharmony_ci yield f"typedef uint64_t {bitfield64.name};" 1210e5c31af7Sopenharmony_ci lines = [] 1211e5c31af7Sopenharmony_ci for ev in bitfield64.enumeratorList: 1212e5c31af7Sopenharmony_ci generateEntry(lines, bitfield64.name, ev.name, ev.bitpos, ev.value) 1213e5c31af7Sopenharmony_ci for alias in ev.aliasList: 1214e5c31af7Sopenharmony_ci generateEntry(lines, bitfield64.name, alias, ev.bitpos, ev.value) 1215e5c31af7Sopenharmony_ci # write indented lines 1216e5c31af7Sopenharmony_ci for line in indentLines(lines): 1217e5c31af7Sopenharmony_ci yield line 1218e5c31af7Sopenharmony_ci yield "" 1219e5c31af7Sopenharmony_ci 1220e5c31af7Sopenharmony_cidef genDefinesSrc (apiName, defines): 1221e5c31af7Sopenharmony_ci def genLines (defines): 1222e5c31af7Sopenharmony_ci for d in defines: 1223e5c31af7Sopenharmony_ci if d.alias is not None: 1224e5c31af7Sopenharmony_ci continue 1225e5c31af7Sopenharmony_ci defineType = DEFINITIONS.get(d.name, d.type) 1226e5c31af7Sopenharmony_ci yield f"#define {d.name}\t(static_cast<{defineType}>\t({d.value}))" 1227e5c31af7Sopenharmony_ci for line in indentLines(genLines(defines)): 1228e5c31af7Sopenharmony_ci yield line 1229e5c31af7Sopenharmony_ci # add VK_API_MAX_FRAMEWORK_VERSION 1230e5c31af7Sopenharmony_ci major, minor = api.features[-1].number.split('.') 1231e5c31af7Sopenharmony_ci yield f"#define VK{apiName}_API_MAX_FRAMEWORK_VERSION\tVK{apiName}_API_VERSION_{major}_{minor}" 1232e5c31af7Sopenharmony_ci 1233e5c31af7Sopenharmony_cidef genHandlesSrc (handles): 1234e5c31af7Sopenharmony_ci def genLines (handles): 1235e5c31af7Sopenharmony_ci for h in handles: 1236e5c31af7Sopenharmony_ci handleType = h.type 1237e5c31af7Sopenharmony_ci handleObjtype = h.objtypeenum 1238e5c31af7Sopenharmony_ci if h.alias is not None: 1239e5c31af7Sopenharmony_ci # search for aliased handle 1240e5c31af7Sopenharmony_ci for searchedHandle in handles: 1241e5c31af7Sopenharmony_ci if h.alias == searchedHandle.name: 1242e5c31af7Sopenharmony_ci handleType = searchedHandle.type 1243e5c31af7Sopenharmony_ci handleObjtype = searchedHandle.objtypeenum 1244e5c31af7Sopenharmony_ci break 1245e5c31af7Sopenharmony_ci yield f"{handleType}\t({h.name},\tHANDLE{handleObjtype[9:]});" 1246e5c31af7Sopenharmony_ci for line in indentLines(genLines(handles)): 1247e5c31af7Sopenharmony_ci yield line 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_cidef genHandlesSrc (handles): 1250e5c31af7Sopenharmony_ci def genLines (handles): 1251e5c31af7Sopenharmony_ci for h in handles: 1252e5c31af7Sopenharmony_ci handleType = h.type 1253e5c31af7Sopenharmony_ci handleObjtype = h.objtypeenum 1254e5c31af7Sopenharmony_ci line = f"{handleType}\t({{}},\tHANDLE{handleObjtype[9:]});" 1255e5c31af7Sopenharmony_ci yield line.format(h.name) 1256e5c31af7Sopenharmony_ci if h.alias is not None: 1257e5c31af7Sopenharmony_ci yield line.format(h.alias) 1258e5c31af7Sopenharmony_ci 1259e5c31af7Sopenharmony_ci for line in indentLines(genLines(handles)): 1260e5c31af7Sopenharmony_ci yield line 1261e5c31af7Sopenharmony_ci 1262e5c31af7Sopenharmony_cidef writeBasicTypes (api, filename): 1263e5c31af7Sopenharmony_ci 1264e5c31af7Sopenharmony_ci def gen (): 1265e5c31af7Sopenharmony_ci 1266e5c31af7Sopenharmony_ci for line in genDefinesSrc("SC" if api.apiName == "vulkansc" else "", api.defines): 1267e5c31af7Sopenharmony_ci yield line 1268e5c31af7Sopenharmony_ci yield "" 1269e5c31af7Sopenharmony_ci 1270e5c31af7Sopenharmony_ci for line in genHandlesSrc(api.handles): 1271e5c31af7Sopenharmony_ci yield line 1272e5c31af7Sopenharmony_ci yield "" 1273e5c31af7Sopenharmony_ci 1274e5c31af7Sopenharmony_ci for enum in api.enums: 1275e5c31af7Sopenharmony_ci # skip empty enums only for vulkan 1276e5c31af7Sopenharmony_ci # vulkan_json_data.hpp and vulkan_json_parser.hpp in SC need many empty enums 1277e5c31af7Sopenharmony_ci if len(enum.enumeratorList) == 0 and api.apiName == "vulkan": 1278e5c31af7Sopenharmony_ci continue 1279e5c31af7Sopenharmony_ci if enum.type == "bitmask": 1280e5c31af7Sopenharmony_ci if enum.bitwidth == "32": 1281e5c31af7Sopenharmony_ci for line in genBitfieldSrc(enum): 1282e5c31af7Sopenharmony_ci yield line 1283e5c31af7Sopenharmony_ci else: 1284e5c31af7Sopenharmony_ci for line in genBitfield64Src(enum): 1285e5c31af7Sopenharmony_ci yield line 1286e5c31af7Sopenharmony_ci else: 1287e5c31af7Sopenharmony_ci for line in genEnumSrc(enum): 1288e5c31af7Sopenharmony_ci yield line 1289e5c31af7Sopenharmony_ci if enum.alias is not None: 1290e5c31af7Sopenharmony_ci yield f"typedef {enum.name} {enum.alias};" 1291e5c31af7Sopenharmony_ci yield "" 1292e5c31af7Sopenharmony_ci 1293e5c31af7Sopenharmony_ci for bitmask in api.bitmasks: 1294e5c31af7Sopenharmony_ci plainType = api.basetypes[bitmask.type] 1295e5c31af7Sopenharmony_ci yield f"typedef {plainType} {bitmask.name};\n" 1296e5c31af7Sopenharmony_ci if bitmask.alias: 1297e5c31af7Sopenharmony_ci yield f"typedef {bitmask.name} {bitmask.alias};\n" 1298e5c31af7Sopenharmony_ci 1299e5c31af7Sopenharmony_ci yield "" 1300e5c31af7Sopenharmony_ci for line in indentLines(["VK_DEFINE_PLATFORM_TYPE(%s,\t%s)" % (s[0], c) for n, s, c in PLATFORM_TYPES]): 1301e5c31af7Sopenharmony_ci yield line 1302e5c31af7Sopenharmony_ci yield "" 1303e5c31af7Sopenharmony_ci 1304e5c31af7Sopenharmony_ci for ext in api.extensions: 1305e5c31af7Sopenharmony_ci firstRequirementEnums = ext.requirementsList[0].extendedEnums 1306e5c31af7Sopenharmony_ci for e in firstRequirementEnums: 1307e5c31af7Sopenharmony_ci if e.extends is None and e.value is not None: 1308e5c31af7Sopenharmony_ci yield "#define " + e.name + " " + e.value 1309e5c31af7Sopenharmony_ci 1310e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, gen()) 1311e5c31af7Sopenharmony_ci 1312e5c31af7Sopenharmony_cidef writeCompositeTypes (api, filename): 1313e5c31af7Sopenharmony_ci # function that returns definition of structure member 1314e5c31af7Sopenharmony_ci def memberAsString (member): 1315e5c31af7Sopenharmony_ci result = '' 1316e5c31af7Sopenharmony_ci if member.qualifiers: 1317e5c31af7Sopenharmony_ci result += member.qualifiers 1318e5c31af7Sopenharmony_ci result += member.type 1319e5c31af7Sopenharmony_ci if member.pointer: 1320e5c31af7Sopenharmony_ci result += member.pointer 1321e5c31af7Sopenharmony_ci result += '\t' + member.name 1322e5c31af7Sopenharmony_ci for size in member.arraySizeList: 1323e5c31af7Sopenharmony_ci result += f"[{size}]" 1324e5c31af7Sopenharmony_ci if member.fieldWidth: 1325e5c31af7Sopenharmony_ci result += f":{member.fieldWidth}" 1326e5c31af7Sopenharmony_ci return result 1327e5c31af7Sopenharmony_ci 1328e5c31af7Sopenharmony_ci # function that prints single structure definition 1329e5c31af7Sopenharmony_ci def genCompositeTypeSrc (type): 1330e5c31af7Sopenharmony_ci structLines = "%s %s\n{\n" % (type.category, type.name) 1331e5c31af7Sopenharmony_ci for line in indentLines(['\t'+memberAsString(m)+';' for m in type.members]): 1332e5c31af7Sopenharmony_ci structLines += line + '\n' 1333e5c31af7Sopenharmony_ci return structLines + "};\n" 1334e5c31af7Sopenharmony_ci 1335e5c31af7Sopenharmony_ci # function that prints all structure definitions and alias typedefs 1336e5c31af7Sopenharmony_ci def gen (): 1337e5c31af7Sopenharmony_ci # structures in xml are not ordered in a correct way for C++ 1338e5c31af7Sopenharmony_ci # we need to save structures that are used in other structures first 1339e5c31af7Sopenharmony_ci allStructureNamesList = [s.name for s in api.compositeTypes] 1340e5c31af7Sopenharmony_ci commonTypesList = api.basicCTypes + ['VkStructureType'] 1341e5c31af7Sopenharmony_ci savedStructureNamesList = [] 1342e5c31af7Sopenharmony_ci delayedStructureObjectsList = [] 1343e5c31af7Sopenharmony_ci 1344e5c31af7Sopenharmony_ci # helper function that checks if all structure members were already saved 1345e5c31af7Sopenharmony_ci def canStructBeSaved(compositeObject): 1346e5c31af7Sopenharmony_ci for m in compositeObject.members: 1347e5c31af7Sopenharmony_ci # check first commonTypesList to speed up the algorithm 1348e5c31af7Sopenharmony_ci if m.type in commonTypesList: 1349e5c31af7Sopenharmony_ci continue 1350e5c31af7Sopenharmony_ci # make sure that member is not of same type as compositeObject 1351e5c31af7Sopenharmony_ci # (this hadles cases like VkBaseOutStructure) 1352e5c31af7Sopenharmony_ci if m.type == compositeObject.name: 1353e5c31af7Sopenharmony_ci continue 1354e5c31af7Sopenharmony_ci # if member is of compositeType that was not saved we cant save it now 1355e5c31af7Sopenharmony_ci if m.type in allStructureNamesList and m.type not in savedStructureNamesList: 1356e5c31af7Sopenharmony_ci return False 1357e5c31af7Sopenharmony_ci return True 1358e5c31af7Sopenharmony_ci 1359e5c31af7Sopenharmony_ci # iterate over all composite types 1360e5c31af7Sopenharmony_ci lastDelayedComposite = None 1361e5c31af7Sopenharmony_ci for ct in api.compositeTypes: 1362e5c31af7Sopenharmony_ci # check if one of delayed structures can be saved 1363e5c31af7Sopenharmony_ci delayedButSaved = [] 1364e5c31af7Sopenharmony_ci for dct in delayedStructureObjectsList: 1365e5c31af7Sopenharmony_ci if lastDelayedComposite != dct and canStructBeSaved(dct): 1366e5c31af7Sopenharmony_ci yield genCompositeTypeSrc(dct) 1367e5c31af7Sopenharmony_ci delayedButSaved.append(dct) 1368e5c31af7Sopenharmony_ci lastDelayedComposite = None 1369e5c31af7Sopenharmony_ci for dsct in delayedButSaved: 1370e5c31af7Sopenharmony_ci savedStructureNamesList.append(dsct.name) 1371e5c31af7Sopenharmony_ci delayedStructureObjectsList.remove(dsct) 1372e5c31af7Sopenharmony_ci # check if current structure can be saved 1373e5c31af7Sopenharmony_ci if canStructBeSaved(ct): 1374e5c31af7Sopenharmony_ci yield genCompositeTypeSrc(ct) 1375e5c31af7Sopenharmony_ci savedStructureNamesList.append(ct.name) 1376e5c31af7Sopenharmony_ci else: 1377e5c31af7Sopenharmony_ci delayedStructureObjectsList.append(ct) 1378e5c31af7Sopenharmony_ci # memorize structure that was delayed in last iteration to 1379e5c31af7Sopenharmony_ci # avoid calling for it canStructBeSaved in next iteration 1380e5c31af7Sopenharmony_ci lastDelayedComposite = ct 1381e5c31af7Sopenharmony_ci # save remaining delayed composite types (~4 video related structures) 1382e5c31af7Sopenharmony_ci while len(delayedStructureObjectsList) > 0: 1383e5c31af7Sopenharmony_ci for dct in delayedStructureObjectsList: 1384e5c31af7Sopenharmony_ci if canStructBeSaved(dct): 1385e5c31af7Sopenharmony_ci yield genCompositeTypeSrc(dct) 1386e5c31af7Sopenharmony_ci savedStructureNamesList.append(dct.name) 1387e5c31af7Sopenharmony_ci delayedStructureObjectsList.remove(dct) 1388e5c31af7Sopenharmony_ci break 1389e5c31af7Sopenharmony_ci # write all alias typedefs 1390e5c31af7Sopenharmony_ci for ct in api.compositeTypes: 1391e5c31af7Sopenharmony_ci for alias in ct.aliasList: 1392e5c31af7Sopenharmony_ci yield "typedef %s %s;" % (ct.name, alias) 1393e5c31af7Sopenharmony_ci yield "" 1394e5c31af7Sopenharmony_ci 1395e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, gen()) 1396e5c31af7Sopenharmony_ci 1397e5c31af7Sopenharmony_cidef argListToStr (args): 1398e5c31af7Sopenharmony_ci def argumentToString(arg): 1399e5c31af7Sopenharmony_ci # args can be instance of FunctionArgument or CompositeMember 1400e5c31af7Sopenharmony_ci # but CompositeMember has no arraySize atrribute nor secondPointerIsConst 1401e5c31af7Sopenharmony_ci workingOnFunctionArgument = True if hasattr(arg, 'arraySize') else False 1402e5c31af7Sopenharmony_ci result = '' 1403e5c31af7Sopenharmony_ci if arg.qualifiers: 1404e5c31af7Sopenharmony_ci result += arg.qualifiers 1405e5c31af7Sopenharmony_ci result += arg.type 1406e5c31af7Sopenharmony_ci if arg.pointer: 1407e5c31af7Sopenharmony_ci if workingOnFunctionArgument and arg.secondPointerIsConst: 1408e5c31af7Sopenharmony_ci result += '* const*' 1409e5c31af7Sopenharmony_ci else: 1410e5c31af7Sopenharmony_ci result += arg.pointer 1411e5c31af7Sopenharmony_ci result += ' ' + arg.name 1412e5c31af7Sopenharmony_ci if workingOnFunctionArgument: 1413e5c31af7Sopenharmony_ci if arg.arraySize: 1414e5c31af7Sopenharmony_ci result += arg.arraySize 1415e5c31af7Sopenharmony_ci return result 1416e5c31af7Sopenharmony_ci return ", ".join(argumentToString(arg) for arg in args) 1417e5c31af7Sopenharmony_ci 1418e5c31af7Sopenharmony_cidef writeInterfaceDecl (api, filename, functionTypes, concrete): 1419e5c31af7Sopenharmony_ci def genProtos (): 1420e5c31af7Sopenharmony_ci postfix = "" if concrete else " = 0" 1421e5c31af7Sopenharmony_ci for function in api.functions: 1422e5c31af7Sopenharmony_ci if not function.getType() in functionTypes: 1423e5c31af7Sopenharmony_ci continue 1424e5c31af7Sopenharmony_ci yield "virtual %s\t%s\t(%s) const%s;" % (function.returnType, getInterfaceName(function.name), argListToStr(function.arguments), postfix) 1425e5c31af7Sopenharmony_ci 1426e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, indentLines(genProtos())) 1427e5c31af7Sopenharmony_ci 1428e5c31af7Sopenharmony_cidef writeFunctionPtrTypes (api, filename): 1429e5c31af7Sopenharmony_ci def genTypes (): 1430e5c31af7Sopenharmony_ci pattern = "typedef VKAPI_ATTR {}\t(VKAPI_CALL* {})\t({});" 1431e5c31af7Sopenharmony_ci for function in api.functions: 1432e5c31af7Sopenharmony_ci argList = argListToStr(function.arguments) 1433e5c31af7Sopenharmony_ci yield pattern.format(function.returnType, getFunctionTypeName(function.name), argList) 1434e5c31af7Sopenharmony_ci for alias in function.aliasList: 1435e5c31af7Sopenharmony_ci yield pattern.format(function.returnType, getFunctionTypeName(alias), argList) 1436e5c31af7Sopenharmony_ci 1437e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, indentLines(genTypes())) 1438e5c31af7Sopenharmony_ci 1439e5c31af7Sopenharmony_cidef writeFunctionPointers (api, filename, functionTypes): 1440e5c31af7Sopenharmony_ci def FunctionsYielder (): 1441e5c31af7Sopenharmony_ci for function in api.functions: 1442e5c31af7Sopenharmony_ci if function.getType() in functionTypes: 1443e5c31af7Sopenharmony_ci interfaceName = getInterfaceName(function.name) 1444e5c31af7Sopenharmony_ci functionTypeName = getFunctionTypeName(function.name) 1445e5c31af7Sopenharmony_ci yield f"{functionTypeName}\t{interfaceName};" 1446e5c31af7Sopenharmony_ci if function.getType() == Function.TYPE_INSTANCE: 1447e5c31af7Sopenharmony_ci for alias in function.aliasList: 1448e5c31af7Sopenharmony_ci interfaceName = getInterfaceName(alias) 1449e5c31af7Sopenharmony_ci functionTypeName = getFunctionTypeName(alias) 1450e5c31af7Sopenharmony_ci yield f"{functionTypeName}\t{interfaceName};" 1451e5c31af7Sopenharmony_ci 1452e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, indentLines(FunctionsYielder())) 1453e5c31af7Sopenharmony_ci 1454e5c31af7Sopenharmony_cidef getPromotedFunctions (api): 1455e5c31af7Sopenharmony_ci apiNum = 0 if api.apiName == "vulkan" else 1 1456e5c31af7Sopenharmony_ci promotedFunctions = collections.defaultdict(lambda: list()) 1457e5c31af7Sopenharmony_ci for feature in api.features: 1458e5c31af7Sopenharmony_ci versionSplit = feature.name.split('_') 1459e5c31af7Sopenharmony_ci apiMajor = versionSplit[-2] 1460e5c31af7Sopenharmony_ci apiMinor = versionSplit[-1] 1461e5c31af7Sopenharmony_ci apituple = (apiNum, apiMajor, apiMinor) 1462e5c31af7Sopenharmony_ci for featureRequirement in feature.requirementsList: 1463e5c31af7Sopenharmony_ci for promotedFun in featureRequirement.commandList: 1464e5c31af7Sopenharmony_ci promotedFunctions[promotedFun].append(apituple) 1465e5c31af7Sopenharmony_ci return promotedFunctions 1466e5c31af7Sopenharmony_ci 1467e5c31af7Sopenharmony_cidef writeInitFunctionPointers (api, filename, functionTypes, cond = None): 1468e5c31af7Sopenharmony_ci promotedFunctions = getPromotedFunctions(api) if Function.TYPE_DEVICE in functionTypes else None 1469e5c31af7Sopenharmony_ci def makeInitFunctionPointers (): 1470e5c31af7Sopenharmony_ci for function in api.functions: 1471e5c31af7Sopenharmony_ci if function.getType() in functionTypes and (cond == None or cond(function)): 1472e5c31af7Sopenharmony_ci condition = '' 1473e5c31af7Sopenharmony_ci if function.getType() == Function.TYPE_DEVICE: 1474e5c31af7Sopenharmony_ci versionCheck = '' 1475e5c31af7Sopenharmony_ci if function.name in promotedFunctions: 1476e5c31af7Sopenharmony_ci for versionTuple in promotedFunctions[function.name]: 1477e5c31af7Sopenharmony_ci if len(versionCheck) > 0: 1478e5c31af7Sopenharmony_ci versionCheck += ' || ' 1479e5c31af7Sopenharmony_ci versionCheck = 'usedApiVersion >= VK_MAKE_API_VERSION(%s, %s, %s, 0)' % versionTuple 1480e5c31af7Sopenharmony_ci if len(versionCheck) > 0: 1481e5c31af7Sopenharmony_ci condition = f"if ({versionCheck})\n " 1482e5c31af7Sopenharmony_ci interfaceName = getInterfaceName(function.name) 1483e5c31af7Sopenharmony_ci functionTypeName = getFunctionTypeName(function.name) 1484e5c31af7Sopenharmony_ci yield f"{condition}m_vk.{interfaceName} = ({functionTypeName}) GET_PROC_ADDR(\"{function.name}\");" 1485e5c31af7Sopenharmony_ci for alias in function.aliasList: 1486e5c31af7Sopenharmony_ci yield f"if (!m_vk.{interfaceName})" 1487e5c31af7Sopenharmony_ci yield f" m_vk.{interfaceName} = ({functionTypeName}) GET_PROC_ADDR(\"{alias}\");" 1488e5c31af7Sopenharmony_ci if function.getType() == Function.TYPE_INSTANCE and function.arguments[0].type == "VkPhysicalDevice": 1489e5c31af7Sopenharmony_ci interfaceName = getInterfaceName(alias) 1490e5c31af7Sopenharmony_ci functionTypeName = getFunctionTypeName(alias) 1491e5c31af7Sopenharmony_ci yield f"m_vk.{interfaceName} = ({functionTypeName}) GET_PROC_ADDR(\"{alias}\");" 1492e5c31af7Sopenharmony_ci 1493e5c31af7Sopenharmony_ci lines = makeInitFunctionPointers() 1494e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, lines) 1495e5c31af7Sopenharmony_ci 1496e5c31af7Sopenharmony_cidef writeFuncPtrInterfaceImpl (api, filename, functionTypes, className): 1497e5c31af7Sopenharmony_ci def makeFuncPtrInterfaceImpl (): 1498e5c31af7Sopenharmony_ci for function in api.functions: 1499e5c31af7Sopenharmony_ci if function.getType() in functionTypes: 1500e5c31af7Sopenharmony_ci yield "" 1501e5c31af7Sopenharmony_ci yield "%s %s::%s (%s) const" % (function.returnType, className, getInterfaceName(function.name), argListToStr(function.arguments)) 1502e5c31af7Sopenharmony_ci yield "{" 1503e5c31af7Sopenharmony_ci if function.name == "vkEnumerateInstanceVersion": 1504e5c31af7Sopenharmony_ci yield " if (m_vk.enumerateInstanceVersion)" 1505e5c31af7Sopenharmony_ci yield " return m_vk.enumerateInstanceVersion(pApiVersion);" 1506e5c31af7Sopenharmony_ci yield "" 1507e5c31af7Sopenharmony_ci yield " *pApiVersion = VK_API_VERSION_1_0;" 1508e5c31af7Sopenharmony_ci yield " return VK_SUCCESS;" 1509e5c31af7Sopenharmony_ci elif function.getType() == Function.TYPE_INSTANCE and function.arguments[0].type == "VkPhysicalDevice" and len(function.aliasList) > 0: 1510e5c31af7Sopenharmony_ci yield " vk::VkPhysicalDeviceProperties props;" 1511e5c31af7Sopenharmony_ci yield " m_vk.getPhysicalDeviceProperties(physicalDevice, &props);" 1512e5c31af7Sopenharmony_ci yield " if (props.apiVersion >= VK_API_VERSION_1_1)" 1513e5c31af7Sopenharmony_ci yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function.name), ", ".join(a.name for a in function.arguments)) 1514e5c31af7Sopenharmony_ci yield " else" 1515e5c31af7Sopenharmony_ci yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function.aliasList[0]), ", ".join(a.name for a in function.arguments)) 1516e5c31af7Sopenharmony_ci else: 1517e5c31af7Sopenharmony_ci yield " %sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", getInterfaceName(function.name), ", ".join(a.name for a in function.arguments)) 1518e5c31af7Sopenharmony_ci yield "}" 1519e5c31af7Sopenharmony_ci 1520e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceImpl()) 1521e5c31af7Sopenharmony_ci 1522e5c31af7Sopenharmony_cidef writeFuncPtrInterfaceSCImpl (api, filename, functionTypes, className): 1523e5c31af7Sopenharmony_ci normFuncs = { 1524e5c31af7Sopenharmony_ci "createGraphicsPipelines" : "\t\treturn createGraphicsPipelinesHandlerNorm(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);", 1525e5c31af7Sopenharmony_ci "createComputePipelines" : "\t\treturn createComputePipelinesHandlerNorm(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);", 1526e5c31af7Sopenharmony_ci "createSampler" : "\t\treturn createSamplerHandlerNorm(device, pCreateInfo, pAllocator, pSampler);", 1527e5c31af7Sopenharmony_ci "createSamplerYcbcrConversion" : "\t\treturn createSamplerYcbcrConversionHandlerNorm(device, pCreateInfo, pAllocator, pYcbcrConversion);", 1528e5c31af7Sopenharmony_ci "createDescriptorSetLayout" : "\t\treturn createDescriptorSetLayoutHandlerNorm(device, pCreateInfo, pAllocator, pSetLayout);", 1529e5c31af7Sopenharmony_ci "createPipelineLayout" : "\t\treturn createPipelineLayoutHandlerNorm(device, pCreateInfo, pAllocator, pPipelineLayout);", 1530e5c31af7Sopenharmony_ci "createRenderPass" : "\t\treturn createRenderPassHandlerNorm(device, pCreateInfo, pAllocator, pRenderPass);", 1531e5c31af7Sopenharmony_ci "createRenderPass2" : "\t\treturn createRenderPass2HandlerNorm(device, pCreateInfo, pAllocator, pRenderPass);", 1532e5c31af7Sopenharmony_ci "createCommandPool" : "\t\treturn createCommandPoolHandlerNorm(device, pCreateInfo, pAllocator, pCommandPool);", 1533e5c31af7Sopenharmony_ci "resetCommandPool" : "\t\treturn resetCommandPoolHandlerNorm(device, commandPool, flags);", 1534e5c31af7Sopenharmony_ci "createFramebuffer" : "\t\treturn createFramebufferHandlerNorm(device, pCreateInfo, pAllocator, pFramebuffer);", 1535e5c31af7Sopenharmony_ci } 1536e5c31af7Sopenharmony_ci statFuncs = { 1537e5c31af7Sopenharmony_ci "destroyDevice" : "\t\tdestroyDeviceHandler(device, pAllocator);", 1538e5c31af7Sopenharmony_ci "createDescriptorSetLayout" : "\t\tcreateDescriptorSetLayoutHandlerStat(device, pCreateInfo, pAllocator, pSetLayout);", 1539e5c31af7Sopenharmony_ci "destroyDescriptorSetLayout" : "\t\tdestroyDescriptorSetLayoutHandler(device, descriptorSetLayout, pAllocator);", 1540e5c31af7Sopenharmony_ci "createImageView" : "\t\tcreateImageViewHandler(device, pCreateInfo, pAllocator, pView);", 1541e5c31af7Sopenharmony_ci "destroyImageView" : "\t\tdestroyImageViewHandler(device, imageView, pAllocator);", 1542e5c31af7Sopenharmony_ci "createSemaphore" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(semaphoreRequestCount,1);\n\t\t*pSemaphore = Handle<HANDLE_TYPE_SEMAPHORE>(m_resourceInterface->incResourceCounter());\n\t}", 1543e5c31af7Sopenharmony_ci "destroySemaphore" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(semaphore,semaphoreRequestCount,1);\n\t}", 1544e5c31af7Sopenharmony_ci "createFence" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(fenceRequestCount,1);\n\t\t*pFence = Handle<HANDLE_TYPE_FENCE>(m_resourceInterface->incResourceCounter());\n\t}", 1545e5c31af7Sopenharmony_ci "destroyFence" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(fence,fenceRequestCount,1);\n\t}", 1546e5c31af7Sopenharmony_ci "allocateMemory" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(deviceMemoryRequestCount,1);\n\t\t*pMemory = Handle<HANDLE_TYPE_DEVICE_MEMORY>(m_resourceInterface->incResourceCounter());\n\t}", 1547e5c31af7Sopenharmony_ci "createBuffer" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(bufferRequestCount,1);\n\t\t*pBuffer = Handle<HANDLE_TYPE_BUFFER>(m_resourceInterface->incResourceCounter());\n\t}", 1548e5c31af7Sopenharmony_ci "destroyBuffer" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(buffer,bufferRequestCount,1);\n\t}", 1549e5c31af7Sopenharmony_ci "createImage" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(imageRequestCount,1);\n\t\t*pImage = Handle<HANDLE_TYPE_IMAGE>(m_resourceInterface->incResourceCounter());\n\t}", 1550e5c31af7Sopenharmony_ci "destroyImage" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(image,imageRequestCount,1);\n\t}", 1551e5c31af7Sopenharmony_ci "createEvent" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(eventRequestCount,1);\n\t\t*pEvent = Handle<HANDLE_TYPE_EVENT>(m_resourceInterface->incResourceCounter());\n\t}", 1552e5c31af7Sopenharmony_ci "destroyEvent" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(event,eventRequestCount,1);\n\t}", 1553e5c31af7Sopenharmony_ci "createQueryPool" : "\t\tcreateQueryPoolHandler(device, pCreateInfo, pAllocator, pQueryPool);", 1554e5c31af7Sopenharmony_ci "createBufferView" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(bufferViewRequestCount,1);\n\t\t*pView = Handle<HANDLE_TYPE_BUFFER_VIEW>(m_resourceInterface->incResourceCounter());\n\t}", 1555e5c31af7Sopenharmony_ci "destroyBufferView" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(bufferView,bufferViewRequestCount,1);\n\t}", 1556e5c31af7Sopenharmony_ci "createPipelineLayout" : "\t\tcreatePipelineLayoutHandlerStat(device, pCreateInfo, pAllocator, pPipelineLayout);", 1557e5c31af7Sopenharmony_ci "destroyPipelineLayout" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(pipelineLayout,pipelineLayoutRequestCount,1);\n\t}", 1558e5c31af7Sopenharmony_ci "createRenderPass" : "\t\tcreateRenderPassHandlerStat(device, pCreateInfo, pAllocator, pRenderPass);", 1559e5c31af7Sopenharmony_ci "createRenderPass2" : "\t\tcreateRenderPass2HandlerStat(device, pCreateInfo, pAllocator, pRenderPass);", 1560e5c31af7Sopenharmony_ci "destroyRenderPass" : "\t\tdestroyRenderPassHandler(device, renderPass, pAllocator);", 1561e5c31af7Sopenharmony_ci "createGraphicsPipelines" : "\t\tcreateGraphicsPipelinesHandlerStat(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);", 1562e5c31af7Sopenharmony_ci "createComputePipelines" : "\t\tcreateComputePipelinesHandlerStat(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);", 1563e5c31af7Sopenharmony_ci "destroyPipeline" : "\t\tdestroyPipelineHandler(device, pipeline, pAllocator);", 1564e5c31af7Sopenharmony_ci "createSampler" : "\t\tcreateSamplerHandlerStat(device, pCreateInfo, pAllocator, pSampler);", 1565e5c31af7Sopenharmony_ci "destroySampler" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(sampler,samplerRequestCount,1);\n\t}", 1566e5c31af7Sopenharmony_ci "createDescriptorPool" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(descriptorPoolRequestCount,1);\n\t\t*pDescriptorPool = Handle<HANDLE_TYPE_DESCRIPTOR_POOL>(m_resourceInterface->incResourceCounter());\n\t}", 1567e5c31af7Sopenharmony_ci "resetDescriptorPool" : "\t\tresetDescriptorPoolHandlerStat(device, descriptorPool, flags);", 1568e5c31af7Sopenharmony_ci "allocateDescriptorSets" : "\t\tallocateDescriptorSetsHandlerStat(device, pAllocateInfo, pDescriptorSets);", 1569e5c31af7Sopenharmony_ci "freeDescriptorSets" : "\t\tfreeDescriptorSetsHandlerStat(device, descriptorPool, descriptorSetCount, pDescriptorSets);", 1570e5c31af7Sopenharmony_ci "createFramebuffer" : "\t\tcreateFramebufferHandlerStat(device, pCreateInfo, pAllocator, pFramebuffer);", 1571e5c31af7Sopenharmony_ci "destroyFramebuffer" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(framebuffer,framebufferRequestCount,1);\n\t}", 1572e5c31af7Sopenharmony_ci "createCommandPool" : "\t\tcreateCommandPoolHandlerStat(device, pCreateInfo, pAllocator, pCommandPool);", 1573e5c31af7Sopenharmony_ci "resetCommandPool" : "\t\tresetCommandPoolHandlerStat(device, commandPool, flags);", 1574e5c31af7Sopenharmony_ci "allocateCommandBuffers" : "\t\tallocateCommandBuffersHandler(device, pAllocateInfo, pCommandBuffers);", 1575e5c31af7Sopenharmony_ci "freeCommandBuffers" : "\t\tfreeCommandBuffersHandler(device, commandPool, commandBufferCount, pCommandBuffers);", 1576e5c31af7Sopenharmony_ci "createSamplerYcbcrConversion" : "\t\tcreateSamplerYcbcrConversionHandlerStat(device, pCreateInfo, pAllocator, pYcbcrConversion);", 1577e5c31af7Sopenharmony_ci "destroySamplerYcbcrConversion" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(ycbcrConversion,samplerYcbcrConversionRequestCount,1);\n\t}", 1578e5c31af7Sopenharmony_ci "getDescriptorSetLayoutSupport" : "\t\tgetDescriptorSetLayoutSupportHandler(device, pCreateInfo, pSupport);", 1579e5c31af7Sopenharmony_ci# "" : "surfaceRequestCount", 1580e5c31af7Sopenharmony_ci# "" : "swapchainRequestCount", 1581e5c31af7Sopenharmony_ci# "" : "displayModeRequestCount" 1582e5c31af7Sopenharmony_ci "mapMemory" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tif(m_falseMemory.size() < (static_cast<std::size_t>(offset+size)))\n\t\t\tm_falseMemory.resize(static_cast<std::size_t>(offset+size));\n\t\t*ppData = (void*)m_falseMemory.data();\n\t}", 1583e5c31af7Sopenharmony_ci "getBufferMemoryRequirements" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->size = 1048576U;\n\t\tpMemoryRequirements->alignment = 1U;\n\t\tpMemoryRequirements->memoryTypeBits = ~0U;\n\t}", 1584e5c31af7Sopenharmony_ci "getImageMemoryRequirements" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->size = 1048576U;\n\t\tpMemoryRequirements->alignment = 1U;\n\t\tpMemoryRequirements->memoryTypeBits = ~0U;\n\t}", 1585e5c31af7Sopenharmony_ci "getBufferMemoryRequirements2" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->memoryRequirements.size = 1048576U;\n\t\tpMemoryRequirements->memoryRequirements.alignment = 1U;\n\t\tpMemoryRequirements->memoryRequirements.memoryTypeBits = ~0U;\n\t}", 1586e5c31af7Sopenharmony_ci "getImageMemoryRequirements2" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpMemoryRequirements->memoryRequirements.size = 1048576U;\n\t\tpMemoryRequirements->memoryRequirements.alignment = 1U;\n\t\tpMemoryRequirements->memoryRequirements.memoryTypeBits = ~0U;\n\t}", 1587e5c31af7Sopenharmony_ci "getImageSubresourceLayout" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tpLayout->offset = 0U;\n\t\tpLayout->size = 1048576U;\n\t\tpLayout->rowPitch = 0U;\n\t\tpLayout->arrayPitch = 0U;\n\t\tpLayout->depthPitch = 0U;\n\t}", 1588e5c31af7Sopenharmony_ci "createPipelineCache" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_CREATE(pipelineCacheRequestCount,1);\n\t\t*pPipelineCache = Handle<HANDLE_TYPE_PIPELINE_CACHE>(m_resourceInterface->incResourceCounter());\n\t}", 1589e5c31af7Sopenharmony_ci "destroyPipelineCache" : "\t{\n\t\tDDSTAT_LOCK();\n\t\tDDSTAT_HANDLE_DESTROY_IF(pipelineCache,pipelineCacheRequestCount,1);\n\t}", 1590e5c31af7Sopenharmony_ci "cmdUpdateBuffer" : "\t\tincreaseCommandBufferSize(commandBuffer, dataSize);", 1591e5c31af7Sopenharmony_ci "getDeviceQueue" : "\t\tm_vk.getDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);", 1592e5c31af7Sopenharmony_ci } 1593e5c31af7Sopenharmony_ci 1594e5c31af7Sopenharmony_ci statReturns = { 1595e5c31af7Sopenharmony_ci "VkResult" : "return VK_SUCCESS;", 1596e5c31af7Sopenharmony_ci "VkDeviceAddress" : "return 0u;", 1597e5c31af7Sopenharmony_ci "uint64_t" : "return 0u;", 1598e5c31af7Sopenharmony_ci } 1599e5c31af7Sopenharmony_ci def makeFuncPtrInterfaceStatisticsImpl (): 1600e5c31af7Sopenharmony_ci for function in api.functions: 1601e5c31af7Sopenharmony_ci if function.getType() in functionTypes: 1602e5c31af7Sopenharmony_ci ifaceName = getInterfaceName(function.name) 1603e5c31af7Sopenharmony_ci yield "" 1604e5c31af7Sopenharmony_ci yield "%s %s::%s (%s) const" % (function.returnType, className, ifaceName, argListToStr(function.arguments)) 1605e5c31af7Sopenharmony_ci yield "{" 1606e5c31af7Sopenharmony_ci if ( ifaceName in normFuncs ) or ( ifaceName in statFuncs ): 1607e5c31af7Sopenharmony_ci yield "\tstd::lock_guard<std::mutex> lock(functionMutex);" 1608e5c31af7Sopenharmony_ci if ifaceName != "getDeviceProcAddr" : 1609e5c31af7Sopenharmony_ci yield "\tif (m_normalMode)" 1610e5c31af7Sopenharmony_ci if ifaceName in normFuncs : 1611e5c31af7Sopenharmony_ci yield "%s" % ( normFuncs[ifaceName] ) 1612e5c31af7Sopenharmony_ci else: 1613e5c31af7Sopenharmony_ci yield "\t\t%sm_vk.%s(%s);" % ("return " if function.returnType != "void" else "", ifaceName, ", ".join(a.name for a in function.arguments)) 1614e5c31af7Sopenharmony_ci if ifaceName in statFuncs : 1615e5c31af7Sopenharmony_ci yield "\telse" 1616e5c31af7Sopenharmony_ci yield "%s" % ( statFuncs[ifaceName] ) 1617e5c31af7Sopenharmony_ci elif ifaceName[:3] == "cmd" : 1618e5c31af7Sopenharmony_ci yield "\telse" 1619e5c31af7Sopenharmony_ci yield "\t\tincreaseCommandBufferSize(commandBuffer, 0u);" 1620e5c31af7Sopenharmony_ci if function.returnType in statReturns: 1621e5c31af7Sopenharmony_ci yield "\t%s" % ( statReturns[function.returnType] ) 1622e5c31af7Sopenharmony_ci yield "}" 1623e5c31af7Sopenharmony_ci 1624e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, makeFuncPtrInterfaceStatisticsImpl()) 1625e5c31af7Sopenharmony_ci 1626e5c31af7Sopenharmony_cidef writeStrUtilProto (api, filename): 1627e5c31af7Sopenharmony_ci def makeStrUtilProto (): 1628e5c31af7Sopenharmony_ci for line in indentLines(["const char*\tget%sName\t(%s value);" % (enum.name[2:], enum.name) for enum in api.enums if enum.type == "enum"]): 1629e5c31af7Sopenharmony_ci yield line 1630e5c31af7Sopenharmony_ci yield "" 1631e5c31af7Sopenharmony_ci for line in indentLines(["inline tcu::Format::Enum<%s>\tget%sStr\t(%s value)\t{ return tcu::Format::Enum<%s>(get%sName, value);\t}" % (e.name, e.name[2:], e.name, e.name, e.name[2:]) for e in api.enums if e.type == "enum"]): 1632e5c31af7Sopenharmony_ci yield line 1633e5c31af7Sopenharmony_ci yield "" 1634e5c31af7Sopenharmony_ci for line in indentLines(["inline std::ostream&\toperator<<\t(std::ostream& s, %s value)\t{ return s << get%sStr(value);\t}" % (e.name, e.name[2:]) for e in api.enums if e.type == "enum"]): 1635e5c31af7Sopenharmony_ci yield line 1636e5c31af7Sopenharmony_ci yield "" 1637e5c31af7Sopenharmony_ci for line in indentLines(["tcu::Format::Bitfield<%s>\tget%sStr\t(%s value);" % (("64" if b.type == "VkFlags64" else "32"), b.name[2:], b.name) for b in api.bitmasks]): 1638e5c31af7Sopenharmony_ci yield line 1639e5c31af7Sopenharmony_ci yield "" 1640e5c31af7Sopenharmony_ci for line in indentLines(["std::ostream&\toperator<<\t(std::ostream& s, const %s& value);" % (s.name) for s in api.compositeTypes]): 1641e5c31af7Sopenharmony_ci yield line 1642e5c31af7Sopenharmony_ci 1643e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, makeStrUtilProto()) 1644e5c31af7Sopenharmony_ci 1645e5c31af7Sopenharmony_cidef writeStrUtilImpl (api, filename): 1646e5c31af7Sopenharmony_ci def makeStrUtilImpl (): 1647e5c31af7Sopenharmony_ci for line in indentLines(["template<> const char*\tgetTypeName<%s>\t(void) { return \"%s\";\t}" % (handle.name, handle.name) for handle in api.handles]): 1648e5c31af7Sopenharmony_ci yield line 1649e5c31af7Sopenharmony_ci 1650e5c31af7Sopenharmony_ci yield "" 1651e5c31af7Sopenharmony_ci yield "namespace %s" % PLATFORM_TYPE_NAMESPACE 1652e5c31af7Sopenharmony_ci yield "{" 1653e5c31af7Sopenharmony_ci 1654e5c31af7Sopenharmony_ci for line in indentLines("std::ostream& operator<< (std::ostream& s, %s\tv) { return s << tcu::toHex(v.internal); }" % ''.join(s) for n, s, c in PLATFORM_TYPES): 1655e5c31af7Sopenharmony_ci yield line 1656e5c31af7Sopenharmony_ci 1657e5c31af7Sopenharmony_ci yield "}" 1658e5c31af7Sopenharmony_ci 1659e5c31af7Sopenharmony_ci savedBitmasks = [] 1660e5c31af7Sopenharmony_ci for enum in api.enums: 1661e5c31af7Sopenharmony_ci if enum.type == "enum": 1662e5c31af7Sopenharmony_ci yield "" 1663e5c31af7Sopenharmony_ci yield "const char* get%sName (%s value)" % (enum.name[2:], enum.name) 1664e5c31af7Sopenharmony_ci yield "{" 1665e5c31af7Sopenharmony_ci yield "\tswitch (value)" 1666e5c31af7Sopenharmony_ci yield "\t{" 1667e5c31af7Sopenharmony_ci enumValues = [] 1668e5c31af7Sopenharmony_ci lastValue = 0x7FFFFFFF 1669e5c31af7Sopenharmony_ci for e in enum.enumeratorList: 1670e5c31af7Sopenharmony_ci enumValues.append(f"\t\tcase {e.name}:\treturn \"{e.name}\";") 1671e5c31af7Sopenharmony_ci enumValues.append("\t\tdefault:\treturn DE_NULL;") 1672e5c31af7Sopenharmony_ci for line in indentLines(enumValues): 1673e5c31af7Sopenharmony_ci yield line 1674e5c31af7Sopenharmony_ci yield "\t}" 1675e5c31af7Sopenharmony_ci yield "}" 1676e5c31af7Sopenharmony_ci elif enum.type == "bitmask": 1677e5c31af7Sopenharmony_ci # find bitfield that uses those bitmasks 1678e5c31af7Sopenharmony_ci foundBitmask = None 1679e5c31af7Sopenharmony_ci for bitmask in api.bitmasks: 1680e5c31af7Sopenharmony_ci if bitmask.requires == enum.name or bitmask.bitvalues == enum.name: 1681e5c31af7Sopenharmony_ci foundBitmask = bitmask 1682e5c31af7Sopenharmony_ci break 1683e5c31af7Sopenharmony_ci if foundBitmask == None: 1684e5c31af7Sopenharmony_ci continue 1685e5c31af7Sopenharmony_ci savedBitmasks.append(foundBitmask.name) 1686e5c31af7Sopenharmony_ci bitSize = "64" if foundBitmask.type == "VkFlags64" else "32" 1687e5c31af7Sopenharmony_ci yield "" 1688e5c31af7Sopenharmony_ci yield f"tcu::Format::Bitfield<{bitSize}> get{bitmask.name[2:]}Str ({bitmask.name} value)" 1689e5c31af7Sopenharmony_ci yield "{" 1690e5c31af7Sopenharmony_ci yield "\tstatic const tcu::Format::BitDesc s_desc[] =" 1691e5c31af7Sopenharmony_ci yield "\t{" 1692e5c31af7Sopenharmony_ci if len(enum.enumeratorList) == 0: 1693e5c31af7Sopenharmony_ci # some bitfields in SC have no items 1694e5c31af7Sopenharmony_ci yield f"\t\ttcu::Format::BitDesc(0, \"0\")" 1695e5c31af7Sopenharmony_ci else: 1696e5c31af7Sopenharmony_ci for line in indentLines([f"\t\ttcu::Format::BitDesc({e.name},\t\"{e.name}\")," for e in enum.enumeratorList]): 1697e5c31af7Sopenharmony_ci yield line 1698e5c31af7Sopenharmony_ci yield "\t};" 1699e5c31af7Sopenharmony_ci yield f"\treturn tcu::Format::Bitfield<{bitSize}>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc));" 1700e5c31af7Sopenharmony_ci yield "}" 1701e5c31af7Sopenharmony_ci 1702e5c31af7Sopenharmony_ci for bitmask in api.bitmasks: 1703e5c31af7Sopenharmony_ci if bitmask.name not in savedBitmasks: 1704e5c31af7Sopenharmony_ci bitSize = "64" if bitmask.type == "VkFlags64" else "32" 1705e5c31af7Sopenharmony_ci yield "" 1706e5c31af7Sopenharmony_ci yield f"tcu::Format::Bitfield<{bitSize}> get{bitmask.name[2:]}Str ({bitmask.name} value)" 1707e5c31af7Sopenharmony_ci yield "{" 1708e5c31af7Sopenharmony_ci yield f"\treturn tcu::Format::Bitfield<{bitSize}>(value, DE_NULL, DE_NULL);" 1709e5c31af7Sopenharmony_ci yield "}" 1710e5c31af7Sopenharmony_ci 1711e5c31af7Sopenharmony_ci bitfieldTypeNames = set([bitmask.name for bitmask in api.bitmasks]) 1712e5c31af7Sopenharmony_ci 1713e5c31af7Sopenharmony_ci for type in api.compositeTypes: 1714e5c31af7Sopenharmony_ci yield "" 1715e5c31af7Sopenharmony_ci yield "std::ostream& operator<< (std::ostream& s, const %s& value)" % type.name 1716e5c31af7Sopenharmony_ci yield "{" 1717e5c31af7Sopenharmony_ci yield "\ts << \"%s = {\\n\";" % type.name 1718e5c31af7Sopenharmony_ci for member in type.members: 1719e5c31af7Sopenharmony_ci memberName = member.name 1720e5c31af7Sopenharmony_ci valFmt = None 1721e5c31af7Sopenharmony_ci newLine = "" 1722e5c31af7Sopenharmony_ci if member.type in bitfieldTypeNames: 1723e5c31af7Sopenharmony_ci operator = '*' if member.pointer == '*' else '' 1724e5c31af7Sopenharmony_ci valFmt = "get%sStr(%svalue.%s)" % (member.type[2:], operator, member.name) 1725e5c31af7Sopenharmony_ci elif member.type == "char" and member.pointer == '*': 1726e5c31af7Sopenharmony_ci valFmt = "getCharPtrStr(value.%s)" % member.name 1727e5c31af7Sopenharmony_ci elif member.type == PLATFORM_TYPE_NAMESPACE + "::Win32LPCWSTR": 1728e5c31af7Sopenharmony_ci valFmt = "getWStr(value.%s)" % member.name 1729e5c31af7Sopenharmony_ci elif len(member.arraySizeList) == 1: 1730e5c31af7Sopenharmony_ci if member.name in ["extensionName", "deviceName", "layerName", "description"]: 1731e5c31af7Sopenharmony_ci valFmt = "(const char*)value.%s" % member.name 1732e5c31af7Sopenharmony_ci elif member.type == 'char' or member.type == 'uint8_t': 1733e5c31af7Sopenharmony_ci newLine = "'\\n' << " 1734e5c31af7Sopenharmony_ci valFmt = "tcu::formatArray(tcu::Format::HexIterator<%s>(DE_ARRAY_BEGIN(value.%s)), tcu::Format::HexIterator<%s>(DE_ARRAY_END(value.%s)))" % (member.type, member.name, member.type, member.name) 1735e5c31af7Sopenharmony_ci else: 1736e5c31af7Sopenharmony_ci if member.name == "memoryTypes" or member.name == "memoryHeaps": 1737e5c31af7Sopenharmony_ci endIter = "DE_ARRAY_BEGIN(value.%s) + value.%sCount" % (member.name, member.name[:-1]) 1738e5c31af7Sopenharmony_ci else: 1739e5c31af7Sopenharmony_ci endIter = "DE_ARRAY_END(value.%s)" % member.name 1740e5c31af7Sopenharmony_ci newLine = "'\\n' << " 1741e5c31af7Sopenharmony_ci valFmt = "tcu::formatArray(DE_ARRAY_BEGIN(value.%s), %s)" % (member.name, endIter) 1742e5c31af7Sopenharmony_ci memberName = member.name 1743e5c31af7Sopenharmony_ci elif len(member.arraySizeList) > 1: 1744e5c31af7Sopenharmony_ci yield f"\ts << \"\\t{member.name} = \" << '\\n';" 1745e5c31af7Sopenharmony_ci dim = 0 1746e5c31af7Sopenharmony_ci index = '' 1747e5c31af7Sopenharmony_ci dimensionCount = len(member.arraySizeList) 1748e5c31af7Sopenharmony_ci while dim < dimensionCount-1: 1749e5c31af7Sopenharmony_ci yield f"\tfor(deUint32 i{dim} = 0 ; i{dim} < {member.arraySizeList[dim]} ; ++i{dim})" 1750e5c31af7Sopenharmony_ci index += f"[i{dim}]" 1751e5c31af7Sopenharmony_ci dim +=1 1752e5c31af7Sopenharmony_ci yield f"\t\ts << tcu::formatArray(DE_ARRAY_BEGIN(value.{member.name}{index}), DE_ARRAY_END(value.{member.name}{index})) << '\\n';" 1753e5c31af7Sopenharmony_ci # move to next member 1754e5c31af7Sopenharmony_ci continue 1755e5c31af7Sopenharmony_ci else: 1756e5c31af7Sopenharmony_ci valFmt = "value.%s" % member.name 1757e5c31af7Sopenharmony_ci yield ("\ts << \"\\t%s = \" << " % memberName) + newLine + valFmt + " << '\\n';" 1758e5c31af7Sopenharmony_ci yield "\ts << '}';" 1759e5c31af7Sopenharmony_ci yield "\treturn s;" 1760e5c31af7Sopenharmony_ci yield "}" 1761e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, makeStrUtilImpl()) 1762e5c31af7Sopenharmony_ci 1763e5c31af7Sopenharmony_cidef writeObjTypeImpl (api, filename): 1764e5c31af7Sopenharmony_ci def makeObjTypeImpl (): 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci yield "namespace vk" 1767e5c31af7Sopenharmony_ci yield "{" 1768e5c31af7Sopenharmony_ci 1769e5c31af7Sopenharmony_ci yield "template<typename T> VkObjectType getObjectType (void);" 1770e5c31af7Sopenharmony_ci 1771e5c31af7Sopenharmony_ci for line in indentLines(["template<> inline VkObjectType\tgetObjectType<%s>\t(void) { return %s;\t}" % (handle.name, prefixName("VK_OBJECT_TYPE_", handle.name)) for handle in api.handles]): 1772e5c31af7Sopenharmony_ci yield line 1773e5c31af7Sopenharmony_ci 1774e5c31af7Sopenharmony_ci yield "}" 1775e5c31af7Sopenharmony_ci 1776e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, makeObjTypeImpl()) 1777e5c31af7Sopenharmony_ci 1778e5c31af7Sopenharmony_ciclass ConstructorFunction: 1779e5c31af7Sopenharmony_ci def __init__ (self, type, name, objectType, ifaceArgs, arguments): 1780e5c31af7Sopenharmony_ci self.type = type 1781e5c31af7Sopenharmony_ci self.name = name 1782e5c31af7Sopenharmony_ci self.objectType = objectType 1783e5c31af7Sopenharmony_ci self.ifaceArgs = ifaceArgs 1784e5c31af7Sopenharmony_ci self.arguments = arguments 1785e5c31af7Sopenharmony_ci 1786e5c31af7Sopenharmony_cidef getConstructorFunctions (api): 1787e5c31af7Sopenharmony_ci funcs = [] 1788e5c31af7Sopenharmony_ci 1789e5c31af7Sopenharmony_ci ifacesDict = { 1790e5c31af7Sopenharmony_ci Function.TYPE_PLATFORM: [FunctionArgument("vk", "const ", "PlatformInterface&")], 1791e5c31af7Sopenharmony_ci Function.TYPE_INSTANCE: [FunctionArgument("vk", "const ", "InstanceInterface&")], 1792e5c31af7Sopenharmony_ci Function.TYPE_DEVICE: [FunctionArgument("vk", "const ", "DeviceInterface&")]} 1793e5c31af7Sopenharmony_ci 1794e5c31af7Sopenharmony_ci for function in api.functions: 1795e5c31af7Sopenharmony_ci if (function.name[:8] == "vkCreate" or function.name == "vkAllocateMemory") and not "createInfoCount" in [a.name for a in function.arguments]: 1796e5c31af7Sopenharmony_ci if function.name == "vkCreateDisplayModeKHR": 1797e5c31af7Sopenharmony_ci continue # No way to delete display modes (bug?) 1798e5c31af7Sopenharmony_ci 1799e5c31af7Sopenharmony_ci ifaceArgs = [] 1800e5c31af7Sopenharmony_ci if function.name == "vkCreateDevice": 1801e5c31af7Sopenharmony_ci ifaceArgs = [FunctionArgument("vkp", "const ", "PlatformInterface&"), 1802e5c31af7Sopenharmony_ci FunctionArgument("instance", "", "VkInstance")] 1803e5c31af7Sopenharmony_ci ifaceArgs.extend(ifacesDict[function.getType()]) 1804e5c31af7Sopenharmony_ci 1805e5c31af7Sopenharmony_ci assert (function.arguments[-2].type == "VkAllocationCallbacks" and \ 1806e5c31af7Sopenharmony_ci "const" in function.arguments[-2].qualifiers and \ 1807e5c31af7Sopenharmony_ci function.arguments[-2].pointer == "*") 1808e5c31af7Sopenharmony_ci 1809e5c31af7Sopenharmony_ci objectType = function.arguments[-1].type 1810e5c31af7Sopenharmony_ci arguments = function.arguments[:-1] 1811e5c31af7Sopenharmony_ci funcs.append(ConstructorFunction(function.getType(), getInterfaceName(function.name), objectType, ifaceArgs, arguments)) 1812e5c31af7Sopenharmony_ci return funcs 1813e5c31af7Sopenharmony_ci 1814e5c31af7Sopenharmony_cidef addVersionDefines(versionSpectrum): 1815e5c31af7Sopenharmony_ci output = ["#define " + ver.getDefineName() + " " + ver.getInHex() for ver in versionSpectrum if not ver.isStandardVersion()] 1816e5c31af7Sopenharmony_ci return output 1817e5c31af7Sopenharmony_ci 1818e5c31af7Sopenharmony_cidef writeRefUtilProto (api, filename): 1819e5c31af7Sopenharmony_ci functions = getConstructorFunctions(api) 1820e5c31af7Sopenharmony_ci 1821e5c31af7Sopenharmony_ci def makeRefUtilProto (): 1822e5c31af7Sopenharmony_ci unindented = [] 1823e5c31af7Sopenharmony_ci for line in indentLines(["Move<%s>\t%s\t(%s = DE_NULL);" % (function.objectType, function.name, argListToStr(function.ifaceArgs + function.arguments)) for function in functions]): 1824e5c31af7Sopenharmony_ci yield line 1825e5c31af7Sopenharmony_ci 1826e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, makeRefUtilProto()) 1827e5c31af7Sopenharmony_ci 1828e5c31af7Sopenharmony_cidef writeRefUtilImpl (api, filename): 1829e5c31af7Sopenharmony_ci functions = getConstructorFunctions(api) 1830e5c31af7Sopenharmony_ci 1831e5c31af7Sopenharmony_ci def makeRefUtilImpl (): 1832e5c31af7Sopenharmony_ci yield "namespace refdetails" 1833e5c31af7Sopenharmony_ci yield "{" 1834e5c31af7Sopenharmony_ci yield "" 1835e5c31af7Sopenharmony_ci 1836e5c31af7Sopenharmony_ci for function in api.functions: 1837e5c31af7Sopenharmony_ci if function.getType() == Function.TYPE_DEVICE \ 1838e5c31af7Sopenharmony_ci and (function.name[:9] == "vkDestroy" or function.name == "vkFreeMemory") \ 1839e5c31af7Sopenharmony_ci and not function.name == "vkDestroyDevice": 1840e5c31af7Sopenharmony_ci objectType = function.arguments[-2].type 1841e5c31af7Sopenharmony_ci yield "template<>" 1842e5c31af7Sopenharmony_ci yield "void Deleter<%s>::operator() (%s obj) const" % (objectType, objectType) 1843e5c31af7Sopenharmony_ci yield "{" 1844e5c31af7Sopenharmony_ci yield "\tm_deviceIface->%s(m_device, obj, m_allocator);" % (getInterfaceName(function.name)) 1845e5c31af7Sopenharmony_ci yield "}" 1846e5c31af7Sopenharmony_ci yield "" 1847e5c31af7Sopenharmony_ci 1848e5c31af7Sopenharmony_ci yield "} // refdetails" 1849e5c31af7Sopenharmony_ci yield "" 1850e5c31af7Sopenharmony_ci 1851e5c31af7Sopenharmony_ci dtorDict = { 1852e5c31af7Sopenharmony_ci Function.TYPE_PLATFORM: "object", 1853e5c31af7Sopenharmony_ci Function.TYPE_INSTANCE: "instance", 1854e5c31af7Sopenharmony_ci Function.TYPE_DEVICE: "device" 1855e5c31af7Sopenharmony_ci } 1856e5c31af7Sopenharmony_ci 1857e5c31af7Sopenharmony_ci for function in functions: 1858e5c31af7Sopenharmony_ci deleterArgsString = '' 1859e5c31af7Sopenharmony_ci if function.name == "createDevice": 1860e5c31af7Sopenharmony_ci # createDevice requires two additional parameters to setup VkDevice deleter 1861e5c31af7Sopenharmony_ci deleterArgsString = "vkp, instance, object, " + function.arguments[-1].name 1862e5c31af7Sopenharmony_ci else: 1863e5c31af7Sopenharmony_ci deleterArgsString = "vk, %s, %s" % (dtorDict[function.type], function.arguments[-1].name) 1864e5c31af7Sopenharmony_ci 1865e5c31af7Sopenharmony_ci yield "Move<%s> %s (%s)" % (function.objectType, function.name, argListToStr(function.ifaceArgs + function.arguments)) 1866e5c31af7Sopenharmony_ci yield "{" 1867e5c31af7Sopenharmony_ci yield "\t%s object = 0;" % function.objectType 1868e5c31af7Sopenharmony_ci yield "\tVK_CHECK(vk.%s(%s));" % (function.name, ", ".join([a.name for a in function.arguments] + ["&object"])) 1869e5c31af7Sopenharmony_ci yield "\treturn Move<%s>(check<%s>(object), Deleter<%s>(%s));" % (function.objectType, function.objectType, function.objectType, deleterArgsString) 1870e5c31af7Sopenharmony_ci yield "}" 1871e5c31af7Sopenharmony_ci yield "" 1872e5c31af7Sopenharmony_ci 1873e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, makeRefUtilImpl()) 1874e5c31af7Sopenharmony_ci 1875e5c31af7Sopenharmony_cidef writeStructTraitsImpl (api, filename): 1876e5c31af7Sopenharmony_ci def gen (): 1877e5c31af7Sopenharmony_ci for cType in api.compositeTypes: 1878e5c31af7Sopenharmony_ci if cType.category == "struct" and cType.members[0].name == "sType" and cType.name != "VkBaseOutStructure" and cType.name != "VkBaseInStructure": 1879e5c31af7Sopenharmony_ci yield "template<> VkStructureType getStructureType<%s> (void)" % cType.name 1880e5c31af7Sopenharmony_ci yield "{" 1881e5c31af7Sopenharmony_ci yield "\treturn %s;" % cType.members[0].values 1882e5c31af7Sopenharmony_ci yield "}" 1883e5c31af7Sopenharmony_ci yield "" 1884e5c31af7Sopenharmony_ci 1885e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, gen()) 1886e5c31af7Sopenharmony_ci 1887e5c31af7Sopenharmony_cidef writeNullDriverImpl (api, filename): 1888e5c31af7Sopenharmony_ci def genNullDriverImpl (): 1889e5c31af7Sopenharmony_ci specialFuncNames = [ 1890e5c31af7Sopenharmony_ci "vkCreateGraphicsPipelines", 1891e5c31af7Sopenharmony_ci "vkCreateComputePipelines", 1892e5c31af7Sopenharmony_ci "vkCreateRayTracingPipelinesNV", 1893e5c31af7Sopenharmony_ci "vkCreateRayTracingPipelinesKHR", 1894e5c31af7Sopenharmony_ci "vkGetInstanceProcAddr", 1895e5c31af7Sopenharmony_ci "vkGetDeviceProcAddr", 1896e5c31af7Sopenharmony_ci "vkEnumeratePhysicalDevices", 1897e5c31af7Sopenharmony_ci "vkEnumerateInstanceExtensionProperties", 1898e5c31af7Sopenharmony_ci "vkEnumerateDeviceExtensionProperties", 1899e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceFeatures", 1900e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceFeatures2KHR", 1901e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceProperties", 1902e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceProperties2KHR", 1903e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceQueueFamilyProperties", 1904e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceMemoryProperties", 1905e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceFormatProperties", 1906e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceImageFormatProperties", 1907e5c31af7Sopenharmony_ci "vkGetDeviceQueue", 1908e5c31af7Sopenharmony_ci "vkGetBufferMemoryRequirements", 1909e5c31af7Sopenharmony_ci "vkGetBufferMemoryRequirements2KHR", 1910e5c31af7Sopenharmony_ci "vkGetImageMemoryRequirements", 1911e5c31af7Sopenharmony_ci "vkGetImageMemoryRequirements2KHR", 1912e5c31af7Sopenharmony_ci "vkAllocateMemory", 1913e5c31af7Sopenharmony_ci "vkMapMemory", 1914e5c31af7Sopenharmony_ci "vkUnmapMemory", 1915e5c31af7Sopenharmony_ci "vkAllocateDescriptorSets", 1916e5c31af7Sopenharmony_ci "vkFreeDescriptorSets", 1917e5c31af7Sopenharmony_ci "vkResetDescriptorPool", 1918e5c31af7Sopenharmony_ci "vkAllocateCommandBuffers", 1919e5c31af7Sopenharmony_ci "vkFreeCommandBuffers", 1920e5c31af7Sopenharmony_ci "vkCreateDisplayModeKHR", 1921e5c31af7Sopenharmony_ci "vkCreateSharedSwapchainsKHR", 1922e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceExternalBufferPropertiesKHR", 1923e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceImageFormatProperties2KHR", 1924e5c31af7Sopenharmony_ci "vkGetMemoryAndroidHardwareBufferANDROID", 1925e5c31af7Sopenharmony_ci "vkCreateShadersEXT", 1926e5c31af7Sopenharmony_ci ] 1927e5c31af7Sopenharmony_ci 1928e5c31af7Sopenharmony_ci specialFuncs = [f for f in api.functions if f.name in specialFuncNames] 1929e5c31af7Sopenharmony_ci createFuncs = [f for f in api.functions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs] 1930e5c31af7Sopenharmony_ci destroyFuncs = [f for f in api.functions if (f.name[:9] == "vkDestroy" or f.name == "vkFreeMemory") and not f in specialFuncs] 1931e5c31af7Sopenharmony_ci dummyFuncs = [f for f in api.functions if f not in specialFuncs + createFuncs + destroyFuncs] 1932e5c31af7Sopenharmony_ci 1933e5c31af7Sopenharmony_ci def getHandle (name): 1934e5c31af7Sopenharmony_ci for handle in api.handles: 1935e5c31af7Sopenharmony_ci if handle.name == name: 1936e5c31af7Sopenharmony_ci return handle 1937e5c31af7Sopenharmony_ci raise Exception("No such handle: %s" % name) 1938e5c31af7Sopenharmony_ci 1939e5c31af7Sopenharmony_ci for function in createFuncs: 1940e5c31af7Sopenharmony_ci objectType = function.arguments[-1].type 1941e5c31af7Sopenharmony_ci argsStr = ", ".join([a.name for a in function.arguments[:-1]]) 1942e5c31af7Sopenharmony_ci 1943e5c31af7Sopenharmony_ci yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function.name), argListToStr(function.arguments)) 1944e5c31af7Sopenharmony_ci yield "{" 1945e5c31af7Sopenharmony_ci yield "\tDE_UNREF(%s);" % function.arguments[-2].name 1946e5c31af7Sopenharmony_ci 1947e5c31af7Sopenharmony_ci if function.arguments[-1].len != None: 1948e5c31af7Sopenharmony_ci yield "\tVK_NULL_RETURN((allocateNonDispHandleArray<%s, %s>(%s, %s)));" % (objectType[2:], objectType, argsStr, function.arguments[-1].name) 1949e5c31af7Sopenharmony_ci else: 1950e5c31af7Sopenharmony_ci if getHandle(objectType).type == "VK_DEFINE_NON_DISPATCHABLE_HANDLE": 1951e5c31af7Sopenharmony_ci yield "\tVK_NULL_RETURN((*%s = allocateNonDispHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr) 1952e5c31af7Sopenharmony_ci else: 1953e5c31af7Sopenharmony_ci yield "\tVK_NULL_RETURN((*%s = allocateHandle<%s, %s>(%s)));" % (function.arguments[-1].name, objectType[2:], objectType, argsStr) 1954e5c31af7Sopenharmony_ci yield "}" 1955e5c31af7Sopenharmony_ci yield "" 1956e5c31af7Sopenharmony_ci 1957e5c31af7Sopenharmony_ci for function in destroyFuncs: 1958e5c31af7Sopenharmony_ci objectArg = function.arguments[-2] 1959e5c31af7Sopenharmony_ci 1960e5c31af7Sopenharmony_ci yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function.name), argListToStr(function.arguments)) 1961e5c31af7Sopenharmony_ci yield "{" 1962e5c31af7Sopenharmony_ci for arg in function.arguments[:-2]: 1963e5c31af7Sopenharmony_ci yield "\tDE_UNREF(%s);" % arg.name 1964e5c31af7Sopenharmony_ci 1965e5c31af7Sopenharmony_ci if getHandle(objectArg.type).type == 'VK_DEFINE_NON_DISPATCHABLE_HANDLE': 1966e5c31af7Sopenharmony_ci yield "\tfreeNonDispHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name) 1967e5c31af7Sopenharmony_ci else: 1968e5c31af7Sopenharmony_ci yield "\tfreeHandle<%s, %s>(%s, %s);" % (objectArg.type[2:], objectArg.type, objectArg.name, function.arguments[-1].name) 1969e5c31af7Sopenharmony_ci 1970e5c31af7Sopenharmony_ci yield "}" 1971e5c31af7Sopenharmony_ci yield "" 1972e5c31af7Sopenharmony_ci 1973e5c31af7Sopenharmony_ci for function in dummyFuncs: 1974e5c31af7Sopenharmony_ci yield "VKAPI_ATTR %s VKAPI_CALL %s (%s)" % (function.returnType, getInterfaceName(function.name), argListToStr(function.arguments)) 1975e5c31af7Sopenharmony_ci yield "{" 1976e5c31af7Sopenharmony_ci for arg in function.arguments: 1977e5c31af7Sopenharmony_ci yield "\tDE_UNREF(%s);" % arg.name 1978e5c31af7Sopenharmony_ci if function.returnType != "void": 1979e5c31af7Sopenharmony_ci yield "\treturn VK_SUCCESS;" 1980e5c31af7Sopenharmony_ci yield "}" 1981e5c31af7Sopenharmony_ci yield "" 1982e5c31af7Sopenharmony_ci 1983e5c31af7Sopenharmony_ci def genFuncEntryTable (type, name): 1984e5c31af7Sopenharmony_ci 1985e5c31af7Sopenharmony_ci entries = [] 1986e5c31af7Sopenharmony_ci pattern = "\tVK_NULL_FUNC_ENTRY(%s,\t%s)," 1987e5c31af7Sopenharmony_ci for f in api.functions: 1988e5c31af7Sopenharmony_ci if f.getType() != type: 1989e5c31af7Sopenharmony_ci continue 1990e5c31af7Sopenharmony_ci entries.append(pattern % (f.name, getInterfaceName(f.name))) 1991e5c31af7Sopenharmony_ci 1992e5c31af7Sopenharmony_ci yield "static const tcu::StaticFunctionLibrary::Entry %s[] =" % name 1993e5c31af7Sopenharmony_ci yield "{" 1994e5c31af7Sopenharmony_ci 1995e5c31af7Sopenharmony_ci for line in indentLines(entries): 1996e5c31af7Sopenharmony_ci yield line 1997e5c31af7Sopenharmony_ci yield "};" 1998e5c31af7Sopenharmony_ci yield "" 1999e5c31af7Sopenharmony_ci 2000e5c31af7Sopenharmony_ci # Func tables 2001e5c31af7Sopenharmony_ci for line in genFuncEntryTable(Function.TYPE_PLATFORM, "s_platformFunctions"): 2002e5c31af7Sopenharmony_ci yield line 2003e5c31af7Sopenharmony_ci 2004e5c31af7Sopenharmony_ci for line in genFuncEntryTable(Function.TYPE_INSTANCE, "s_instanceFunctions"): 2005e5c31af7Sopenharmony_ci yield line 2006e5c31af7Sopenharmony_ci 2007e5c31af7Sopenharmony_ci for line in genFuncEntryTable(Function.TYPE_DEVICE, "s_deviceFunctions"): 2008e5c31af7Sopenharmony_ci yield line 2009e5c31af7Sopenharmony_ci 2010e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, genNullDriverImpl()) 2011e5c31af7Sopenharmony_ci 2012e5c31af7Sopenharmony_cidef writeTypeUtil (api, filename): 2013e5c31af7Sopenharmony_ci # Structs filled by API queries are not often used in test code 2014e5c31af7Sopenharmony_ci QUERY_RESULT_TYPES = set([ 2015e5c31af7Sopenharmony_ci "VkPhysicalDeviceFeatures", 2016e5c31af7Sopenharmony_ci "VkPhysicalDeviceLimits", 2017e5c31af7Sopenharmony_ci "VkFormatProperties", 2018e5c31af7Sopenharmony_ci "VkImageFormatProperties", 2019e5c31af7Sopenharmony_ci "VkPhysicalDeviceSparseProperties", 2020e5c31af7Sopenharmony_ci "VkQueueFamilyProperties", 2021e5c31af7Sopenharmony_ci "VkMemoryType", 2022e5c31af7Sopenharmony_ci "VkMemoryHeap", 2023e5c31af7Sopenharmony_ci "StdVideoH264SpsVuiFlags", 2024e5c31af7Sopenharmony_ci "StdVideoH264SpsFlags", 2025e5c31af7Sopenharmony_ci "StdVideoH264PpsFlags", 2026e5c31af7Sopenharmony_ci "StdVideoDecodeH264PictureInfoFlags", 2027e5c31af7Sopenharmony_ci "StdVideoDecodeH264ReferenceInfoFlags", 2028e5c31af7Sopenharmony_ci "StdVideoEncodeH264SliceHeaderFlags", 2029e5c31af7Sopenharmony_ci "StdVideoEncodeH264PictureInfoFlags", 2030e5c31af7Sopenharmony_ci "StdVideoEncodeH264ReferenceInfoFlags", 2031e5c31af7Sopenharmony_ci "StdVideoEncodeH264ReferenceInfoFlags", 2032e5c31af7Sopenharmony_ci "StdVideoH265HrdFlags", 2033e5c31af7Sopenharmony_ci "StdVideoH265VpsFlags", 2034e5c31af7Sopenharmony_ci "StdVideoH265SpsVuiFlags", 2035e5c31af7Sopenharmony_ci "StdVideoH265SpsFlags", 2036e5c31af7Sopenharmony_ci "StdVideoH265PpsFlags", 2037e5c31af7Sopenharmony_ci "StdVideoDecodeH265PictureInfoFlags", 2038e5c31af7Sopenharmony_ci "StdVideoDecodeH265ReferenceInfoFlags", 2039e5c31af7Sopenharmony_ci "StdVideoEncodeH265PictureInfoFlags", 2040e5c31af7Sopenharmony_ci "StdVideoEncodeH265ReferenceInfoFlags", 2041e5c31af7Sopenharmony_ci "StdVideoEncodeH265SliceSegmentHeaderFlags", 2042e5c31af7Sopenharmony_ci "StdVideoH265ProfileTierLevelFlags", 2043e5c31af7Sopenharmony_ci "StdVideoH265ShortTermRefPicSetFlags", 2044e5c31af7Sopenharmony_ci "StdVideoEncodeH264ReferenceListsInfoFlags", 2045e5c31af7Sopenharmony_ci "StdVideoEncodeH265ReferenceListsInfoFlags", 2046e5c31af7Sopenharmony_ci ]) 2047e5c31af7Sopenharmony_ci 2048e5c31af7Sopenharmony_ci def isSimpleStruct (type): 2049e5c31af7Sopenharmony_ci def hasArrayMember (type): 2050e5c31af7Sopenharmony_ci for member in type.members: 2051e5c31af7Sopenharmony_ci if len(member.arraySizeList) > 0: 2052e5c31af7Sopenharmony_ci return True 2053e5c31af7Sopenharmony_ci return False 2054e5c31af7Sopenharmony_ci 2055e5c31af7Sopenharmony_ci def hasCompositeMember (type): 2056e5c31af7Sopenharmony_ci for member in type.members: 2057e5c31af7Sopenharmony_ci if member.pointer is not None and '*' not in member.pointer: 2058e5c31af7Sopenharmony_ci match = [c for c in api.compositeTypes if member.type == c.name] 2059e5c31af7Sopenharmony_ci if len(match) > 0: 2060e5c31af7Sopenharmony_ci return True 2061e5c31af7Sopenharmony_ci return False 2062e5c31af7Sopenharmony_ci 2063e5c31af7Sopenharmony_ci return type.category == "struct" and \ 2064e5c31af7Sopenharmony_ci type.members[0].type != "VkStructureType" and \ 2065e5c31af7Sopenharmony_ci not type.name in QUERY_RESULT_TYPES and \ 2066e5c31af7Sopenharmony_ci not hasArrayMember(type) and \ 2067e5c31af7Sopenharmony_ci not hasCompositeMember(type) 2068e5c31af7Sopenharmony_ci 2069e5c31af7Sopenharmony_ci def gen (): 2070e5c31af7Sopenharmony_ci for type in api.compositeTypes: 2071e5c31af7Sopenharmony_ci if not isSimpleStruct(type): 2072e5c31af7Sopenharmony_ci continue 2073e5c31af7Sopenharmony_ci 2074e5c31af7Sopenharmony_ci name = type.name[2:] if type.name[:2].lower() == "vk" else type.name 2075e5c31af7Sopenharmony_ci 2076e5c31af7Sopenharmony_ci yield "" 2077e5c31af7Sopenharmony_ci yield "inline %s make%s (%s)" % (type.name, name, argListToStr(type.members)) 2078e5c31af7Sopenharmony_ci yield "{" 2079e5c31af7Sopenharmony_ci yield "\t%s res;" % type.name 2080e5c31af7Sopenharmony_ci for line in indentLines(["\tres.%s\t= %s;" % (m.name, m.name) for m in type.members]): 2081e5c31af7Sopenharmony_ci yield line 2082e5c31af7Sopenharmony_ci yield "\treturn res;" 2083e5c31af7Sopenharmony_ci yield "}" 2084e5c31af7Sopenharmony_ci 2085e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, gen()) 2086e5c31af7Sopenharmony_ci 2087e5c31af7Sopenharmony_cidef writeDriverIds(api, filename): 2088e5c31af7Sopenharmony_ci driverIdsString = [] 2089e5c31af7Sopenharmony_ci driverIdsString.append("static const struct\n" 2090e5c31af7Sopenharmony_ci "{\n" 2091e5c31af7Sopenharmony_ci "\tstd::string driver;\n" 2092e5c31af7Sopenharmony_ci "\tuint32_t id;\n" 2093e5c31af7Sopenharmony_ci "} driverIds [] =\n" 2094e5c31af7Sopenharmony_ci "{") 2095e5c31af7Sopenharmony_ci driverItems = dict() 2096e5c31af7Sopenharmony_ci driverIdEnum = [enum for enum in api.enums if enum.name == 'VkDriverId'][0] 2097e5c31af7Sopenharmony_ci for enumerator in driverIdEnum.enumeratorList: 2098e5c31af7Sopenharmony_ci driverIdsString.append(f"\t{{\"{enumerator.name}\", {enumerator.value}}},") 2099e5c31af7Sopenharmony_ci driverItems[enumerator.name] = enumerator.value 2100e5c31af7Sopenharmony_ci for enumerator in driverIdEnum.enumeratorList: 2101e5c31af7Sopenharmony_ci if len(enumerator.aliasList) > 0: 2102e5c31af7Sopenharmony_ci driverIdsString.append(f"\t{{\"{enumerator.aliasList[0]}\", {enumerator.value}}},\t// {enumerator.name}") 2103e5c31af7Sopenharmony_ci driverIdsString.append("\t{\"VK_DRIVER_ID_MAX_ENUM\", 0x7FFFFFFF}") 2104e5c31af7Sopenharmony_ci driverIdsString.append("};") 2105e5c31af7Sopenharmony_ci 2106e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, driverIdsString) 2107e5c31af7Sopenharmony_ci 2108e5c31af7Sopenharmony_cidef writeSupportedExtensions(api, filename): 2109e5c31af7Sopenharmony_ci 2110e5c31af7Sopenharmony_ci def writeExtensionsForVersions(map): 2111e5c31af7Sopenharmony_ci result = [] 2112e5c31af7Sopenharmony_ci for version in map: 2113e5c31af7Sopenharmony_ci result.append(" if (coreVersion >= " + str(version) + ")") 2114e5c31af7Sopenharmony_ci result.append(" {") 2115e5c31af7Sopenharmony_ci for extension in map[version]: 2116e5c31af7Sopenharmony_ci result.append(' dst.push_back("' + extension.name + '");') 2117e5c31af7Sopenharmony_ci result.append(" }") 2118e5c31af7Sopenharmony_ci 2119e5c31af7Sopenharmony_ci if not map: 2120e5c31af7Sopenharmony_ci result.append(" DE_UNREF(coreVersion);") 2121e5c31af7Sopenharmony_ci 2122e5c31af7Sopenharmony_ci return result 2123e5c31af7Sopenharmony_ci 2124e5c31af7Sopenharmony_ci isSC = api.apiName == 'vulkansc' 2125e5c31af7Sopenharmony_ci instanceMap = {} 2126e5c31af7Sopenharmony_ci deviceMap = {} 2127e5c31af7Sopenharmony_ci 2128e5c31af7Sopenharmony_ci for ext in api.extensions: 2129e5c31af7Sopenharmony_ci if ext.promotedto is None or "VK_VERSION" not in ext.promotedto: 2130e5c31af7Sopenharmony_ci continue 2131e5c31af7Sopenharmony_ci # skip partialy promoted extensions 2132e5c31af7Sopenharmony_ci if ext.partiallyPromoted is True: 2133e5c31af7Sopenharmony_ci continue 2134e5c31af7Sopenharmony_ci major = int(ext.promotedto[-3]) 2135e5c31af7Sopenharmony_ci minor = int(ext.promotedto[-1]) 2136e5c31af7Sopenharmony_ci currVersion = "VK_API_VERSION_" + ext.promotedto[-3:] 2137e5c31af7Sopenharmony_ci # VulkanSC is based on Vulkan 1.2. Any Vulkan version greater than 1.2 should be excluded 2138e5c31af7Sopenharmony_ci if isSC and major==1 and minor>2: 2139e5c31af7Sopenharmony_ci continue 2140e5c31af7Sopenharmony_ci if ext.type == 'instance': 2141e5c31af7Sopenharmony_ci list = instanceMap.get(currVersion) 2142e5c31af7Sopenharmony_ci instanceMap[currVersion] = list + [ext] if list else [ext] 2143e5c31af7Sopenharmony_ci else: 2144e5c31af7Sopenharmony_ci list = deviceMap.get(currVersion) 2145e5c31af7Sopenharmony_ci deviceMap[currVersion] = list + [ext] if list else [ext] 2146e5c31af7Sopenharmony_ci 2147e5c31af7Sopenharmony_ci # add list of extensions missing in Vulkan SC specification 2148e5c31af7Sopenharmony_ci if isSC: 2149e5c31af7Sopenharmony_ci for extensionName, data in api.additionalExtensionData: 2150e5c31af7Sopenharmony_ci # make sure that this extension was registered 2151e5c31af7Sopenharmony_ci if 'register_extension' not in data.keys(): 2152e5c31af7Sopenharmony_ci continue 2153e5c31af7Sopenharmony_ci # save array containing 'device' or 'instance' string followed by the optional vulkan version in which this extension is core; 2154e5c31af7Sopenharmony_ci # note that register_extension section is also required for partialy promoted extensions like VK_EXT_extended_dynamic_state2 2155e5c31af7Sopenharmony_ci # but those extensions should not fill 'core' tag 2156e5c31af7Sopenharmony_ci match = re.match("(\d).(\d).(\d).(\d)", data['register_extension']['core']) 2157e5c31af7Sopenharmony_ci if match == None: 2158e5c31af7Sopenharmony_ci continue 2159e5c31af7Sopenharmony_ci major = int(match.group(2)) 2160e5c31af7Sopenharmony_ci minor = int(match.group(3)) 2161e5c31af7Sopenharmony_ci if major==1 and minor>2: 2162e5c31af7Sopenharmony_ci continue 2163e5c31af7Sopenharmony_ci currVersion = f"VK_API_VERSION_{major}_{minor}" 2164e5c31af7Sopenharmony_ci ext = Extension(extensionName, 0, 0, 0, 0, 0, 0, 0) 2165e5c31af7Sopenharmony_ci if data['register_extension']['type'] == 'instance': 2166e5c31af7Sopenharmony_ci list = instanceMap.get(currVersion) 2167e5c31af7Sopenharmony_ci instanceMap[currVersion] = list + [ext] if list else [ext] 2168e5c31af7Sopenharmony_ci else: 2169e5c31af7Sopenharmony_ci list = deviceMap.get(currVersion) 2170e5c31af7Sopenharmony_ci deviceMap[currVersion] = list + [ext] if list else [ext] 2171e5c31af7Sopenharmony_ci 2172e5c31af7Sopenharmony_ci lines = [ 2173e5c31af7Sopenharmony_ci "", 2174e5c31af7Sopenharmony_ci "void getCoreDeviceExtensionsImpl (uint32_t coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(deviceMap) != 0 or isSC else ""), 2175e5c31af7Sopenharmony_ci "{"] + writeExtensionsForVersions(deviceMap) + [ 2176e5c31af7Sopenharmony_ci "}", 2177e5c31af7Sopenharmony_ci "", 2178e5c31af7Sopenharmony_ci "void getCoreInstanceExtensionsImpl (uint32_t coreVersion, ::std::vector<const char*>&%s)" % (" dst" if len(instanceMap) != 0 or isSC else ""), 2179e5c31af7Sopenharmony_ci "{"] + writeExtensionsForVersions(instanceMap) + [ 2180e5c31af7Sopenharmony_ci "}", 2181e5c31af7Sopenharmony_ci ""] 2182e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, lines) 2183e5c31af7Sopenharmony_ci 2184e5c31af7Sopenharmony_ci 2185e5c31af7Sopenharmony_cidef writeExtensionFunctions (api, filename): 2186e5c31af7Sopenharmony_ci 2187e5c31af7Sopenharmony_ci def writeExtensionNameArrays (): 2188e5c31af7Sopenharmony_ci instanceExtensionNames = [f"\t\"{ext.name}\"," for ext in api.extensions if ext.type == "instance"] 2189e5c31af7Sopenharmony_ci deviceExtensionNames = [f"\t\"{ext.name}\"," for ext in api.extensions if ext.type == "device"] 2190e5c31af7Sopenharmony_ci yield '::std::string instanceExtensionNames[] =\n{' 2191e5c31af7Sopenharmony_ci for instanceExtName in instanceExtensionNames: 2192e5c31af7Sopenharmony_ci yield instanceExtName 2193e5c31af7Sopenharmony_ci yield '};\n' 2194e5c31af7Sopenharmony_ci yield '::std::string deviceExtensionNames[] =\n{' 2195e5c31af7Sopenharmony_ci for deviceExtName in deviceExtensionNames: 2196e5c31af7Sopenharmony_ci yield deviceExtName 2197e5c31af7Sopenharmony_ci yield '};' 2198e5c31af7Sopenharmony_ci 2199e5c31af7Sopenharmony_ci def writeExtensionFunctions (functionType): 2200e5c31af7Sopenharmony_ci isFirstWrite = True 2201e5c31af7Sopenharmony_ci dg_list = [] # Device groups functions need special casing, as Vulkan 1.0 keeps them in VK_KHR_device_groups whereas 1.1 moved them into VK_KHR_swapchain 2202e5c31af7Sopenharmony_ci if functionType == Function.TYPE_INSTANCE: 2203e5c31af7Sopenharmony_ci yield 'void getInstanceExtensionFunctions (uint32_t apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{' 2204e5c31af7Sopenharmony_ci dg_list = ["vkGetPhysicalDevicePresentRectanglesKHR"] 2205e5c31af7Sopenharmony_ci elif functionType == Function.TYPE_DEVICE: 2206e5c31af7Sopenharmony_ci yield 'void getDeviceExtensionFunctions (uint32_t apiVersion, ::std::string extName, ::std::vector<const char*>& functions)\n{' 2207e5c31af7Sopenharmony_ci dg_list = ["vkGetDeviceGroupPresentCapabilitiesKHR", "vkGetDeviceGroupSurfacePresentModesKHR", "vkAcquireNextImage2KHR"] 2208e5c31af7Sopenharmony_ci for ext in api.extensions: 2209e5c31af7Sopenharmony_ci funcNames = [] 2210e5c31af7Sopenharmony_ci for requirement in ext.requirementsList: 2211e5c31af7Sopenharmony_ci for requiredCommand in requirement.newCommands: 2212e5c31af7Sopenharmony_ci commandName = requiredCommand.name 2213e5c31af7Sopenharmony_ci # find function that has specified name 2214e5c31af7Sopenharmony_ci func = None 2215e5c31af7Sopenharmony_ci funcList = [f for f in api.functions if f.name == commandName] 2216e5c31af7Sopenharmony_ci # if name was not found check if this is alias 2217e5c31af7Sopenharmony_ci if len(funcList) == 0: 2218e5c31af7Sopenharmony_ci for f in api.functions: 2219e5c31af7Sopenharmony_ci for aliasName in f.aliasList: 2220e5c31af7Sopenharmony_ci if aliasName == commandName: 2221e5c31af7Sopenharmony_ci func = f 2222e5c31af7Sopenharmony_ci break 2223e5c31af7Sopenharmony_ci if func: 2224e5c31af7Sopenharmony_ci break 2225e5c31af7Sopenharmony_ci else: 2226e5c31af7Sopenharmony_ci func = funcList[0] 2227e5c31af7Sopenharmony_ci if func == None: 2228e5c31af7Sopenharmony_ci if api.apiName == "vulkansc": 2229e5c31af7Sopenharmony_ci continue 2230e5c31af7Sopenharmony_ci # something went wrong, for "vulkan" func should always be found 2231e5c31af7Sopenharmony_ci assert(False) 2232e5c31af7Sopenharmony_ci if func.getType() == functionType: 2233e5c31af7Sopenharmony_ci # only add functions with same vendor as extension 2234e5c31af7Sopenharmony_ci # this is a workaround for entrypoints requiring more 2235e5c31af7Sopenharmony_ci # than one extension and lack of the dependency in vk.xml 2236e5c31af7Sopenharmony_ci vendor = ext.name.split('_')[1] 2237e5c31af7Sopenharmony_ci if commandName.endswith(vendor): 2238e5c31af7Sopenharmony_ci funcNames.append(commandName) 2239e5c31af7Sopenharmony_ci if ext.name: 2240e5c31af7Sopenharmony_ci yield '\tif (extName == "%s")' % ext.name 2241e5c31af7Sopenharmony_ci yield '\t{' 2242e5c31af7Sopenharmony_ci for funcName in funcNames: 2243e5c31af7Sopenharmony_ci if funcName in dg_list: 2244e5c31af7Sopenharmony_ci yield '\t\tif(apiVersion >= VK_API_VERSION_1_1) functions.push_back("%s");' % funcName 2245e5c31af7Sopenharmony_ci else: 2246e5c31af7Sopenharmony_ci yield '\t\tfunctions.push_back("%s");' % funcName 2247e5c31af7Sopenharmony_ci if ext.name == "VK_KHR_device_group": 2248e5c31af7Sopenharmony_ci for dg_func in dg_list: 2249e5c31af7Sopenharmony_ci yield '\t\tif(apiVersion < VK_API_VERSION_1_1) functions.push_back("%s");' % dg_func 2250e5c31af7Sopenharmony_ci yield '\t\treturn;' 2251e5c31af7Sopenharmony_ci yield '\t}' 2252e5c31af7Sopenharmony_ci isFirstWrite = False 2253e5c31af7Sopenharmony_ci if not isFirstWrite: 2254e5c31af7Sopenharmony_ci yield '\tDE_FATAL("Extension name not found");' 2255e5c31af7Sopenharmony_ci yield '}' 2256e5c31af7Sopenharmony_ci 2257e5c31af7Sopenharmony_ci lines = [''] 2258e5c31af7Sopenharmony_ci for line in writeExtensionFunctions(Function.TYPE_INSTANCE): 2259e5c31af7Sopenharmony_ci lines += [line] 2260e5c31af7Sopenharmony_ci lines += [''] 2261e5c31af7Sopenharmony_ci for line in writeExtensionFunctions(Function.TYPE_DEVICE): 2262e5c31af7Sopenharmony_ci lines += [line] 2263e5c31af7Sopenharmony_ci lines += [''] 2264e5c31af7Sopenharmony_ci for line in writeExtensionNameArrays(): 2265e5c31af7Sopenharmony_ci lines += [line] 2266e5c31af7Sopenharmony_ci 2267e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, lines) 2268e5c31af7Sopenharmony_ci 2269e5c31af7Sopenharmony_cidef writeCoreFunctionalities(api, filename): 2270e5c31af7Sopenharmony_ci functionOriginValues = ["FUNCTIONORIGIN_PLATFORM", "FUNCTIONORIGIN_INSTANCE", "FUNCTIONORIGIN_DEVICE"] 2271e5c31af7Sopenharmony_ci 2272e5c31af7Sopenharmony_ci functionNamesPerApiVersionDict = {} 2273e5c31af7Sopenharmony_ci for feature in api.features: 2274e5c31af7Sopenharmony_ci apiVersion = "VK_API_VERSION_" + feature.number.replace('.', '_') 2275e5c31af7Sopenharmony_ci functionNamesPerApiVersionDict[apiVersion] = [] 2276e5c31af7Sopenharmony_ci for r in feature.requirementsList: 2277e5c31af7Sopenharmony_ci functionNamesPerApiVersionDict[apiVersion].extend(r.commandList) 2278e5c31af7Sopenharmony_ci 2279e5c31af7Sopenharmony_ci lines = [ 2280e5c31af7Sopenharmony_ci "", 2281e5c31af7Sopenharmony_ci 'enum FunctionOrigin', '{'] + [line for line in indentLines([ 2282e5c31af7Sopenharmony_ci '\t' + functionOriginValues[0] + '\t= 0,', 2283e5c31af7Sopenharmony_ci '\t' + functionOriginValues[1] + ',', 2284e5c31af7Sopenharmony_ci '\t' + functionOriginValues[2]])] + [ 2285e5c31af7Sopenharmony_ci "};", 2286e5c31af7Sopenharmony_ci "", 2287e5c31af7Sopenharmony_ci "typedef ::std::pair<const char*, FunctionOrigin> FunctionInfo;", 2288e5c31af7Sopenharmony_ci "typedef ::std::vector<FunctionInfo> FunctionInfosList;", 2289e5c31af7Sopenharmony_ci "typedef ::std::map<uint32_t, FunctionInfosList> ApisMap;", 2290e5c31af7Sopenharmony_ci "", 2291e5c31af7Sopenharmony_ci "void initApisMap (ApisMap& apis)", 2292e5c31af7Sopenharmony_ci "{", 2293e5c31af7Sopenharmony_ci " apis.clear();"] + [ 2294e5c31af7Sopenharmony_ci " apis.insert(::std::pair<uint32_t, FunctionInfosList>(" + v + ", FunctionInfosList()));" for v in functionNamesPerApiVersionDict] + [ 2295e5c31af7Sopenharmony_ci ""] 2296e5c31af7Sopenharmony_ci 2297e5c31af7Sopenharmony_ci apiVersions = [] 2298e5c31af7Sopenharmony_ci functionLines = [] 2299e5c31af7Sopenharmony_ci for apiVersion in functionNamesPerApiVersionDict: 2300e5c31af7Sopenharmony_ci # iterate over names of functions added with api 2301e5c31af7Sopenharmony_ci for functionName in functionNamesPerApiVersionDict[apiVersion]: 2302e5c31af7Sopenharmony_ci # search for data of this function in all functions list 2303e5c31af7Sopenharmony_ci functionData = None 2304e5c31af7Sopenharmony_ci for f in api.functions: 2305e5c31af7Sopenharmony_ci if functionName == f.name or functionName in f.aliasList: 2306e5c31af7Sopenharmony_ci functionData = f 2307e5c31af7Sopenharmony_ci break 2308e5c31af7Sopenharmony_ci if functionData == None: 2309e5c31af7Sopenharmony_ci if api.apiName == "vulkansc": 2310e5c31af7Sopenharmony_ci continue 2311e5c31af7Sopenharmony_ci # something went wrong, for "vulkan" functionData should always be found 2312e5c31af7Sopenharmony_ci assert(False) 2313e5c31af7Sopenharmony_ci # add line coresponding to this function 2314e5c31af7Sopenharmony_ci functionLines.append('\tapis[{0}].push_back(FunctionInfo("' + functionName + '",\t' + functionOriginValues[functionData.getType()] + '));') 2315e5c31af7Sopenharmony_ci # functions for every api version should also include all functions from previous versions 2316e5c31af7Sopenharmony_ci specializedLines = [line.format(apiVersion) for line in functionLines] 2317e5c31af7Sopenharmony_ci # indent all functions of specified api and add them to main list 2318e5c31af7Sopenharmony_ci lines = lines + [line for line in indentLines(specializedLines)] + [""] 2319e5c31af7Sopenharmony_ci 2320e5c31af7Sopenharmony_ci lines = lines + ["}"] 2321e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, lines) 2322e5c31af7Sopenharmony_ci 2323e5c31af7Sopenharmony_cidef camelToSnake(name): 2324e5c31af7Sopenharmony_ci name = re.sub('([a-z])([23])D([A-Z])', r'\1_\2d\3', name) 2325e5c31af7Sopenharmony_ci name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) 2326e5c31af7Sopenharmony_ci return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower() 2327e5c31af7Sopenharmony_ci 2328e5c31af7Sopenharmony_cidef writeDeviceFeatures2(api, filename): 2329e5c31af7Sopenharmony_ci 2330e5c31af7Sopenharmony_ci def structInAPI(compositeObject): 2331e5c31af7Sopenharmony_ci for c in api.compositeTypes: 2332e5c31af7Sopenharmony_ci if c.name == compositeObject.name: 2333e5c31af7Sopenharmony_ci return True 2334e5c31af7Sopenharmony_ci return False 2335e5c31af7Sopenharmony_ci 2336e5c31af7Sopenharmony_ci # helper class used to encapsulate all data needed during generation 2337e5c31af7Sopenharmony_ci class StructureDetail: 2338e5c31af7Sopenharmony_ci def __init__ (self, compositeObject): 2339e5c31af7Sopenharmony_ci self.nameList = [compositeObject.name] + compositeObject.aliasList 2340e5c31af7Sopenharmony_ci self.sType = compositeObject.members[0].values 2341e5c31af7Sopenharmony_ci self.instanceName = 'd' + compositeObject.name[11:] 2342e5c31af7Sopenharmony_ci self.flagName = 'is' + compositeObject.name[16:] 2343e5c31af7Sopenharmony_ci self.extension = None 2344e5c31af7Sopenharmony_ci self.api = None 2345e5c31af7Sopenharmony_ci self.major = None 2346e5c31af7Sopenharmony_ci self.minor = None 2347e5c31af7Sopenharmony_ci structureMembers = compositeObject.members[2:] 2348e5c31af7Sopenharmony_ci self.members = [m.name for m in structureMembers] 2349e5c31af7Sopenharmony_ci 2350e5c31af7Sopenharmony_ci # helper extension class used in algorith below 2351e5c31af7Sopenharmony_ci class StructureFoundContinueToNextOne(Exception): 2352e5c31af7Sopenharmony_ci pass 2353e5c31af7Sopenharmony_ci 2354e5c31af7Sopenharmony_ci # find structures that extend VkPhysicalDeviceFeatures2 2355e5c31af7Sopenharmony_ci structures = [c for c in api.compositeTypes if c.structextends is not None and 'VkPhysicalDeviceFeatures2' in c.structextends] 2356e5c31af7Sopenharmony_ci # remove structures that were added by extensions other than KHR and EXT 2357e5c31af7Sopenharmony_ci testedStructures = [] 2358e5c31af7Sopenharmony_ci for s in structures: 2359e5c31af7Sopenharmony_ci if all([postfix not in s.name for postfix in EXTENSION_POSTFIXES_VENDOR]): 2360e5c31af7Sopenharmony_ci testedStructures.append(s) 2361e5c31af7Sopenharmony_ci 2362e5c31af7Sopenharmony_ci existingStructures = list(filter(structInAPI, testedStructures)) # remove features not found in API ( important for Vulkan SC ) 2363e5c31af7Sopenharmony_ci testedStructureDetail = [StructureDetail(struct) for struct in existingStructures] 2364e5c31af7Sopenharmony_ci # iterate over all searched structures and find extensions that enabled them 2365e5c31af7Sopenharmony_ci for structureDetail in testedStructureDetail: 2366e5c31af7Sopenharmony_ci try: 2367e5c31af7Sopenharmony_ci # iterate over all extensions 2368e5c31af7Sopenharmony_ci for extension in api.extensions: 2369e5c31af7Sopenharmony_ci for requirement in extension.requirementsList: 2370e5c31af7Sopenharmony_ci for extensionStructure in requirement.newTypes: 2371e5c31af7Sopenharmony_ci if extensionStructure.name in structureDetail.nameList: 2372e5c31af7Sopenharmony_ci structureDetail.extension = extension.name 2373e5c31af7Sopenharmony_ci if extension.promotedto is not None and extension.partiallyPromoted is False: 2374e5c31af7Sopenharmony_ci # check if extension was promoted to vulkan version or other extension 2375e5c31af7Sopenharmony_ci if 'VK_VERSION' in extension.promotedto: 2376e5c31af7Sopenharmony_ci versionSplit = extension.promotedto.split('_') 2377e5c31af7Sopenharmony_ci structureDetail.api = 0 if api.apiName == "vulkan" else 1 2378e5c31af7Sopenharmony_ci structureDetail.major = versionSplit[-2] 2379e5c31af7Sopenharmony_ci structureDetail.minor = versionSplit[-1] 2380e5c31af7Sopenharmony_ci else: 2381e5c31af7Sopenharmony_ci structureDetail.extension = extension.promotedto 2382e5c31af7Sopenharmony_ci raise StructureFoundContinueToNextOne 2383e5c31af7Sopenharmony_ci except StructureFoundContinueToNextOne: 2384e5c31af7Sopenharmony_ci continue 2385e5c31af7Sopenharmony_ci structureDetailToRemove = [] 2386e5c31af7Sopenharmony_ci for structureDetail in testedStructureDetail: 2387e5c31af7Sopenharmony_ci if structureDetail.major is not None: 2388e5c31af7Sopenharmony_ci continue 2389e5c31af7Sopenharmony_ci # if structure was not added with extension then check if 2390e5c31af7Sopenharmony_ci # it was added directly with one of vulkan versions 2391e5c31af7Sopenharmony_ci structureName = structureDetail.nameList[0] 2392e5c31af7Sopenharmony_ci for feature in api.features: 2393e5c31af7Sopenharmony_ci for requirement in feature.requirementsList: 2394e5c31af7Sopenharmony_ci if structureName in requirement.typeList: 2395e5c31af7Sopenharmony_ci if api.apiName == "vulkansc" and int(feature.number[-1]) > 2: 2396e5c31af7Sopenharmony_ci structureDetailToRemove.append(structureDetail) 2397e5c31af7Sopenharmony_ci else: 2398e5c31af7Sopenharmony_ci versionSplit = feature.name.split('_') 2399e5c31af7Sopenharmony_ci structureDetail.api = 0 if api.apiName == "vulkan" else 1 2400e5c31af7Sopenharmony_ci structureDetail.major = versionSplit[-2] 2401e5c31af7Sopenharmony_ci structureDetail.minor = versionSplit[-1] 2402e5c31af7Sopenharmony_ci break 2403e5c31af7Sopenharmony_ci if structureDetail.major is not None: 2404e5c31af7Sopenharmony_ci break 2405e5c31af7Sopenharmony_ci # remove structures that should not be tested for given api version 2406e5c31af7Sopenharmony_ci for sd in structureDetailToRemove: 2407e5c31af7Sopenharmony_ci testedStructureDetail.remove(sd) 2408e5c31af7Sopenharmony_ci # generate file content 2409e5c31af7Sopenharmony_ci structureDefinitions = [] 2410e5c31af7Sopenharmony_ci featureEnabledFlags = [] 2411e5c31af7Sopenharmony_ci clearStructures = [] 2412e5c31af7Sopenharmony_ci structureChain = [] 2413e5c31af7Sopenharmony_ci logStructures = [] 2414e5c31af7Sopenharmony_ci verifyStructures = [] 2415e5c31af7Sopenharmony_ci for index, structureDetail in enumerate(testedStructureDetail): 2416e5c31af7Sopenharmony_ci structureName = structureDetail.nameList[0] 2417e5c31af7Sopenharmony_ci # create two instances of each structure 2418e5c31af7Sopenharmony_ci nameSpacing = '\t' 2419e5c31af7Sopenharmony_ci structureDefinitions.append(structureName + nameSpacing + structureDetail.instanceName + '[count];') 2420e5c31af7Sopenharmony_ci # create flags that check if proper extension or vulkan version is available 2421e5c31af7Sopenharmony_ci condition = '' 2422e5c31af7Sopenharmony_ci extension = structureDetail.extension 2423e5c31af7Sopenharmony_ci major = structureDetail.major 2424e5c31af7Sopenharmony_ci if extension is not None: 2425e5c31af7Sopenharmony_ci condition = ' checkExtension(properties, "' + extension + '")' 2426e5c31af7Sopenharmony_ci if major is not None: 2427e5c31af7Sopenharmony_ci condition = ' ' if condition == '' else condition + ' || ' 2428e5c31af7Sopenharmony_ci condition += 'context.contextSupports(vk::ApiVersion(' + str(structureDetail.api) + ', ' + str(major) + ', ' + str(structureDetail.minor) + ', 0))' 2429e5c31af7Sopenharmony_ci if condition == '': 2430e5c31af7Sopenharmony_ci condition = ' true' 2431e5c31af7Sopenharmony_ci condition += ';' 2432e5c31af7Sopenharmony_ci nameSpacing = '\t' * int((len(structureName) - 4) / 4) 2433e5c31af7Sopenharmony_ci featureEnabledFlags.append('const bool' + nameSpacing + structureDetail.flagName + ' =' + condition) 2434e5c31af7Sopenharmony_ci # clear memory of each structure 2435e5c31af7Sopenharmony_ci clearStructures.append('\tdeMemset(&' + structureDetail.instanceName + '[ndx], 0xFF * ndx, sizeof(' + structureName + '));') 2436e5c31af7Sopenharmony_ci # construct structure chain 2437e5c31af7Sopenharmony_ci nextInstanceName = 'DE_NULL'; 2438e5c31af7Sopenharmony_ci if index < len(testedStructureDetail)-1: 2439e5c31af7Sopenharmony_ci nextInstanceName = '&' + testedStructureDetail[index+1].instanceName + '[ndx]' 2440e5c31af7Sopenharmony_ci structureChain.append([ 2441e5c31af7Sopenharmony_ci '\t\t' + structureDetail.instanceName + '[ndx].sType = ' + structureDetail.flagName + ' ? ' + structureDetail.sType + ' : VK_STRUCTURE_TYPE_MAX_ENUM;', 2442e5c31af7Sopenharmony_ci '\t\t' + structureDetail.instanceName + '[ndx].pNext = DE_NULL;']) 2443e5c31af7Sopenharmony_ci # construct log section 2444e5c31af7Sopenharmony_ci logStructures.append([ 2445e5c31af7Sopenharmony_ci '\tif (' + structureDetail.flagName + ')', 2446e5c31af7Sopenharmony_ci '\t\tlog << TestLog::Message << ' + structureDetail.instanceName + '[0] << TestLog::EndMessage;' 2447e5c31af7Sopenharmony_ci ]) 2448e5c31af7Sopenharmony_ci #construct verification section 2449e5c31af7Sopenharmony_ci verifyStructure = [] 2450e5c31af7Sopenharmony_ci verifyStructure.append('\tif (' + structureDetail.flagName + ' &&') 2451e5c31af7Sopenharmony_ci for index, m in enumerate(structureDetail.members): 2452e5c31af7Sopenharmony_ci prefix = '\t\t(' if index == 0 else '\t\t ' 2453e5c31af7Sopenharmony_ci postfix = '))' if index == len(structureDetail.members)-1 else ' ||' 2454e5c31af7Sopenharmony_ci verifyStructure.append(prefix + structureDetail.instanceName + '[0].' + m + ' != ' + structureDetail.instanceName + '[1].' + m + postfix) 2455e5c31af7Sopenharmony_ci if len(structureDetail.members) == 0: 2456e5c31af7Sopenharmony_ci verifyStructure.append('\t\tfalse)') 2457e5c31af7Sopenharmony_ci verifyStructure.append('\t{\n\t\tTCU_FAIL("Mismatch between ' + structureName + '");\n\t}') 2458e5c31af7Sopenharmony_ci verifyStructures.append(verifyStructure) 2459e5c31af7Sopenharmony_ci 2460e5c31af7Sopenharmony_ci # construct file content 2461e5c31af7Sopenharmony_ci stream = [] 2462e5c31af7Sopenharmony_ci 2463e5c31af7Sopenharmony_ci # individual test functions 2464e5c31af7Sopenharmony_ci for n, x in enumerate(testedStructureDetail): 2465e5c31af7Sopenharmony_ci stream.append("tcu::TestStatus testPhysicalDeviceFeature" + x.instanceName[len('device'):]+" (Context& context)") 2466e5c31af7Sopenharmony_ci stream.append("""{ 2467e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 2468e5c31af7Sopenharmony_ci const CustomInstance instance (createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2")); 2469e5c31af7Sopenharmony_ci const InstanceDriver& vki (instance.getDriver()); 2470e5c31af7Sopenharmony_ci const int count = 2u; 2471e5c31af7Sopenharmony_ci TestLog& log = context.getTestContext().getLog(); 2472e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2 extFeatures; 2473e5c31af7Sopenharmony_ci vector<VkExtensionProperties> properties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL); 2474e5c31af7Sopenharmony_ci""") 2475e5c31af7Sopenharmony_ci stream.append("\t"+structureDefinitions[n]) 2476e5c31af7Sopenharmony_ci stream.append("\t"+featureEnabledFlags[n]) 2477e5c31af7Sopenharmony_ci stream.append('') 2478e5c31af7Sopenharmony_ci stream.append('\tfor (int ndx = 0; ndx < count; ++ndx)\n\t{') 2479e5c31af7Sopenharmony_ci stream.append("\t" + clearStructures[n]) 2480e5c31af7Sopenharmony_ci stream.extend(structureChain[n]) 2481e5c31af7Sopenharmony_ci stream.append('') 2482e5c31af7Sopenharmony_ci stream.append( 2483e5c31af7Sopenharmony_ci '\t\tdeMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));\n' 2484e5c31af7Sopenharmony_ci '\t\textFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;\n' 2485e5c31af7Sopenharmony_ci '\t\textFeatures.pNext = &' + testedStructureDetail[n].instanceName + '[ndx];\n\n' 2486e5c31af7Sopenharmony_ci '\t\tvki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);') 2487e5c31af7Sopenharmony_ci stream.append('\t}\n') 2488e5c31af7Sopenharmony_ci stream.extend(logStructures[n]) 2489e5c31af7Sopenharmony_ci stream.append('') 2490e5c31af7Sopenharmony_ci stream.extend(verifyStructures[n]) 2491e5c31af7Sopenharmony_ci stream.append('\treturn tcu::TestStatus::pass("Querying succeeded");') 2492e5c31af7Sopenharmony_ci stream.append("}\n") 2493e5c31af7Sopenharmony_ci 2494e5c31af7Sopenharmony_ci allApiVersions = [f.number for f in api.features] 2495e5c31af7Sopenharmony_ci promotedTests = [] 2496e5c31af7Sopenharmony_ci if api.apiName == "vulkan": 2497e5c31af7Sopenharmony_ci for feature in api.features: 2498e5c31af7Sopenharmony_ci major = feature.number[0] 2499e5c31af7Sopenharmony_ci minor = feature.number[-1] 2500e5c31af7Sopenharmony_ci promotedFeatures = [] 2501e5c31af7Sopenharmony_ci if feature.name == 'VK_VERSION_1_0': 2502e5c31af7Sopenharmony_ci continue 2503e5c31af7Sopenharmony_ci for requirement in feature.requirementsList: 2504e5c31af7Sopenharmony_ci for type in requirement.typeList: 2505e5c31af7Sopenharmony_ci matchedStructType = re.search(f'VkPhysicalDevice(\w+)Features', type, re.IGNORECASE) 2506e5c31af7Sopenharmony_ci matchedCoreStructType = re.search(f'VkPhysicalDeviceVulkan(\d+)Features', type, re.IGNORECASE) 2507e5c31af7Sopenharmony_ci if matchedStructType and not matchedCoreStructType: 2508e5c31af7Sopenharmony_ci promotedFeatures.append(type) 2509e5c31af7Sopenharmony_ci if promotedFeatures: 2510e5c31af7Sopenharmony_ci testName = "createDeviceWithPromoted" + feature.number.replace('.', '') + "Structures" 2511e5c31af7Sopenharmony_ci promotedTests.append(testName) 2512e5c31af7Sopenharmony_ci stream.append("tcu::TestStatus " + testName + " (Context& context)") 2513e5c31af7Sopenharmony_ci stream.append("{") 2514e5c31af7Sopenharmony_ci stream.append( 2515e5c31af7Sopenharmony_ci ' if (!context.contextSupports(vk::ApiVersion(0, ' + major + ', ' + minor + ', 0)))\n' 2516e5c31af7Sopenharmony_ci ' TCU_THROW(NotSupportedError, "Vulkan ' + major + '.' + minor + ' is not supported");') 2517e5c31af7Sopenharmony_ci stream.append(""" 2518e5c31af7Sopenharmony_ci const PlatformInterface& platformInterface = context.getPlatformInterface(); 2519e5c31af7Sopenharmony_ci const CustomInstance instance (createCustomInstanceFromContext(context)); 2520e5c31af7Sopenharmony_ci const InstanceDriver& instanceDriver (instance.getDriver()); 2521e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine()); 2522e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = 0; 2523e5c31af7Sopenharmony_ci const deUint32 queueCount = 1; 2524e5c31af7Sopenharmony_ci const deUint32 queueIndex = 0; 2525e5c31af7Sopenharmony_ci const float queuePriority = 1.0f; 2526e5c31af7Sopenharmony_ci 2527e5c31af7Sopenharmony_ci const vector<VkQueueFamilyProperties> queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice); 2528e5c31af7Sopenharmony_ci 2529e5c31af7Sopenharmony_ci const VkDeviceQueueCreateInfo deviceQueueCreateInfo = 2530e5c31af7Sopenharmony_ci { 2531e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 2532e5c31af7Sopenharmony_ci DE_NULL, 2533e5c31af7Sopenharmony_ci (VkDeviceQueueCreateFlags)0u, 2534e5c31af7Sopenharmony_ci queueFamilyIndex, //queueFamilyIndex; 2535e5c31af7Sopenharmony_ci queueCount, //queueCount; 2536e5c31af7Sopenharmony_ci &queuePriority, //pQueuePriorities; 2537e5c31af7Sopenharmony_ci }; 2538e5c31af7Sopenharmony_ci""") 2539e5c31af7Sopenharmony_ci lastFeature = '' 2540e5c31af7Sopenharmony_ci usedFeatures = [] 2541e5c31af7Sopenharmony_ci for feature in promotedFeatures: 2542e5c31af7Sopenharmony_ci for struct in testedStructureDetail: 2543e5c31af7Sopenharmony_ci if (struct.instanceName in usedFeatures): 2544e5c31af7Sopenharmony_ci continue 2545e5c31af7Sopenharmony_ci if feature in struct.nameList: 2546e5c31af7Sopenharmony_ci if lastFeature: 2547e5c31af7Sopenharmony_ci stream.append("\t" + feature + " " + struct.instanceName + " = initVulkanStructure(&" + lastFeature + ");") 2548e5c31af7Sopenharmony_ci else: 2549e5c31af7Sopenharmony_ci stream.append("\t" + feature + " " + struct.instanceName + " = initVulkanStructure();") 2550e5c31af7Sopenharmony_ci lastFeature = struct.instanceName 2551e5c31af7Sopenharmony_ci usedFeatures.append(struct.instanceName) 2552e5c31af7Sopenharmony_ci break 2553e5c31af7Sopenharmony_ci stream.append("\tVkPhysicalDeviceFeatures2 extFeatures = initVulkanStructure(&" + lastFeature + ");") 2554e5c31af7Sopenharmony_ci stream.append(""" 2555e5c31af7Sopenharmony_ci instanceDriver.getPhysicalDeviceFeatures2 (physicalDevice, &extFeatures); 2556e5c31af7Sopenharmony_ci 2557e5c31af7Sopenharmony_ci const VkDeviceCreateInfo deviceCreateInfo = 2558e5c31af7Sopenharmony_ci { 2559e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType; 2560e5c31af7Sopenharmony_ci &extFeatures, //pNext; 2561e5c31af7Sopenharmony_ci (VkDeviceCreateFlags)0u, 2562e5c31af7Sopenharmony_ci 1, //queueRecordCount; 2563e5c31af7Sopenharmony_ci &deviceQueueCreateInfo, //pRequestedQueues; 2564e5c31af7Sopenharmony_ci 0, //layerCount; 2565e5c31af7Sopenharmony_ci DE_NULL, //ppEnabledLayerNames; 2566e5c31af7Sopenharmony_ci 0, //extensionCount; 2567e5c31af7Sopenharmony_ci DE_NULL, //ppEnabledExtensionNames; 2568e5c31af7Sopenharmony_ci DE_NULL, //pEnabledFeatures; 2569e5c31af7Sopenharmony_ci }; 2570e5c31af7Sopenharmony_ci 2571e5c31af7Sopenharmony_ci const Unique<VkDevice> device (createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo)); 2572e5c31af7Sopenharmony_ci const DeviceDriver deviceDriver (platformInterface, instance, device.get(), context.getUsedApiVersion()); 2573e5c31af7Sopenharmony_ci const VkQueue queue = getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex); 2574e5c31af7Sopenharmony_ci 2575e5c31af7Sopenharmony_ci VK_CHECK(deviceDriver.queueWaitIdle(queue)); 2576e5c31af7Sopenharmony_ci 2577e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Pass"); 2578e5c31af7Sopenharmony_ci} 2579e5c31af7Sopenharmony_ci""") 2580e5c31af7Sopenharmony_ci 2581e5c31af7Sopenharmony_ci # function to create tests 2582e5c31af7Sopenharmony_ci stream.append("void addSeparateFeatureTests (tcu::TestCaseGroup* testGroup)\n{") 2583e5c31af7Sopenharmony_ci for x in testedStructureDetail: 2584e5c31af7Sopenharmony_ci stream.append('\taddFunctionCase(testGroup, "' + camelToSnake(x.instanceName[len('device'):]) + '", testPhysicalDeviceFeature' + x.instanceName[len('device'):] + ');') 2585e5c31af7Sopenharmony_ci for x in promotedTests: 2586e5c31af7Sopenharmony_ci stream.append('\taddFunctionCase(testGroup, "' + camelToSnake(x) + '", ' + x + ');') 2587e5c31af7Sopenharmony_ci stream.append('}\n') 2588e5c31af7Sopenharmony_ci 2589e5c31af7Sopenharmony_ci # write out 2590e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 2591e5c31af7Sopenharmony_ci 2592e5c31af7Sopenharmony_cidef generateDeviceFeaturesOrPropertiesDefs(api, FeaturesOrProperties): 2593e5c31af7Sopenharmony_ci assert(FeaturesOrProperties in ['Features', 'Properties']) 2594e5c31af7Sopenharmony_ci defs = [] 2595e5c31af7Sopenharmony_ci foundStructureEnums = [] 2596e5c31af7Sopenharmony_ci structureEnumPattern = f'VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_(\w+)_{FeaturesOrProperties.upper()}(\w+)' 2597e5c31af7Sopenharmony_ci structureEnumPatternNotExtension = structureEnumPattern[:-5] + '$' 2598e5c31af7Sopenharmony_ci structureTypePattern = f'VkPhysicalDevice(\w+){FeaturesOrProperties}(\w+)' 2599e5c31af7Sopenharmony_ci structureTypePatternNotExtension = structureTypePattern[:-5] + '$' 2600e5c31af7Sopenharmony_ci structureTypeToSkipPattern = f'VkPhysicalDeviceVulkan\d\d{FeaturesOrProperties}' 2601e5c31af7Sopenharmony_ci structureExtendsPattern = f'VkPhysicalDevice{FeaturesOrProperties}2' 2602e5c31af7Sopenharmony_ci # iterate over all extensions to find extension that adds enum value matching pattern; 2603e5c31af7Sopenharmony_ci # this will always be in first requirement section 2604e5c31af7Sopenharmony_ci for ext in api.extensions: 2605e5c31af7Sopenharmony_ci # skip extensions that were promoted to other extensions (not vk version) 2606e5c31af7Sopenharmony_ci if ext.promotedto is not None and "VK_VERSION" not in ext.promotedto: 2607e5c31af7Sopenharmony_ci continue 2608e5c31af7Sopenharmony_ci allExtendedEnums = ext.requirementsList[0].extendedEnums 2609e5c31af7Sopenharmony_ci for extendedEnum in allExtendedEnums: 2610e5c31af7Sopenharmony_ci matchedStructEnum = re.search(structureEnumPattern, extendedEnum.name, re.IGNORECASE) 2611e5c31af7Sopenharmony_ci if matchedStructEnum: 2612e5c31af7Sopenharmony_ci # find feature/property structure type name 2613e5c31af7Sopenharmony_ci structureTypeName = "" 2614e5c31af7Sopenharmony_ci for stRequirement in ext.requirementsList[0].newTypes: 2615e5c31af7Sopenharmony_ci stName = stRequirement.name 2616e5c31af7Sopenharmony_ci matchedStructType = re.search(structureTypePattern, stName, re.IGNORECASE) 2617e5c31af7Sopenharmony_ci if matchedStructType: 2618e5c31af7Sopenharmony_ci structureTypeName = stName 2619e5c31af7Sopenharmony_ci break 2620e5c31af7Sopenharmony_ci # iterate over all composite types to check if structureTypeName is not alias 2621e5c31af7Sopenharmony_ci # this handles case where extension was promoted and with it feature/property structure 2622e5c31af7Sopenharmony_ci structureType = None 2623e5c31af7Sopenharmony_ci for ct in api.compositeTypes: 2624e5c31af7Sopenharmony_ci if structureTypeName == ct.name: 2625e5c31af7Sopenharmony_ci structureType = ct 2626e5c31af7Sopenharmony_ci break 2627e5c31af7Sopenharmony_ci elif structureTypeName in ct.aliasList: 2628e5c31af7Sopenharmony_ci structureType = ct 2629e5c31af7Sopenharmony_ci structureTypeName = structureType.name 2630e5c31af7Sopenharmony_ci break 2631e5c31af7Sopenharmony_ci # use data in structextends to skip structures that should not be passed to vkGetPhysicalDeviceProperties(/Features)2 function 2632e5c31af7Sopenharmony_ci if structureType is None or structureType.structextends is None or structureExtendsPattern not in structureType.structextends: 2633e5c31af7Sopenharmony_ci continue 2634e5c31af7Sopenharmony_ci # meke sure that structure was not added earlier - this handles special 2635e5c31af7Sopenharmony_ci # cases like VkPhysicalDeviceIDPropertiesKHR added by 3 extensions 2636e5c31af7Sopenharmony_ci if len([d for d in defs if d[3] == structureTypeName]) > 0: 2637e5c31af7Sopenharmony_ci continue 2638e5c31af7Sopenharmony_ci # there are cases like VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD 2639e5c31af7Sopenharmony_ci # where 2 is after PROPERTIES - to handle this we need to split suffix to two parts 2640e5c31af7Sopenharmony_ci sSuffix = matchedStructEnum.group(2) 2641e5c31af7Sopenharmony_ci sVerSuffix = '' 2642e5c31af7Sopenharmony_ci sExtSuffix = sSuffix 2643e5c31af7Sopenharmony_ci suffixStart = sSuffix.rfind('_') 2644e5c31af7Sopenharmony_ci if suffixStart > 0: 2645e5c31af7Sopenharmony_ci sVerSuffix = sSuffix[:suffixStart] 2646e5c31af7Sopenharmony_ci sExtSuffix = sSuffix[suffixStart:] 2647e5c31af7Sopenharmony_ci foundStructureEnums.append(matchedStructEnum.group(1)) 2648e5c31af7Sopenharmony_ci defs.append( (matchedStructEnum.group(1), sVerSuffix, sExtSuffix, structureTypeName,\ 2649e5c31af7Sopenharmony_ci ext.name, allExtendedEnums[1].name, allExtendedEnums[0].name) ) 2650e5c31af7Sopenharmony_ci # accept single feature/property structure per extension - this also handles cases 2651e5c31af7Sopenharmony_ci # like VK_KHR_variable_pointers which specify feature structure and its alias 2652e5c31af7Sopenharmony_ci break 2653e5c31af7Sopenharmony_ci 2654e5c31af7Sopenharmony_ci # iterate over all structures to find Feature/Property structures that were not added with extension 2655e5c31af7Sopenharmony_ci # but with vulkan version; to do that we need to skip extension part from pattern 2656e5c31af7Sopenharmony_ci for ct in api.compositeTypes: 2657e5c31af7Sopenharmony_ci matchedStructType = re.search(structureTypePatternNotExtension, ct.name, re.IGNORECASE) 2658e5c31af7Sopenharmony_ci if matchedStructType: 2659e5c31af7Sopenharmony_ci if ct.members[0].name != "sType": 2660e5c31af7Sopenharmony_ci continue 2661e5c31af7Sopenharmony_ci if ct.structextends is None or structureExtendsPattern not in ct.structextends: 2662e5c31af7Sopenharmony_ci continue 2663e5c31af7Sopenharmony_ci matchedStructEnum = re.search(structureEnumPatternNotExtension, ct.members[0].values, re.IGNORECASE) 2664e5c31af7Sopenharmony_ci if (matchedStructEnum.group(1) not in foundStructureEnums) and (re.match(structureTypeToSkipPattern, ct.name) == None): 2665e5c31af7Sopenharmony_ci defs.append( (matchedStructEnum.group(1), '', '', ct.name, None, None, '0') ) 2666e5c31af7Sopenharmony_ci return defs 2667e5c31af7Sopenharmony_ci 2668e5c31af7Sopenharmony_cidef writeDeviceFeatures(api, dfDefs, filename): 2669e5c31af7Sopenharmony_ci # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs 2670e5c31af7Sopenharmony_ci # and construct dictionary with all of their attributes 2671e5c31af7Sopenharmony_ci blobMembers = {} 2672e5c31af7Sopenharmony_ci blobStructs = {} 2673e5c31af7Sopenharmony_ci blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$") 2674e5c31af7Sopenharmony_ci for structureType in api.compositeTypes: 2675e5c31af7Sopenharmony_ci match = blobPattern.match(structureType.name) 2676e5c31af7Sopenharmony_ci if match: 2677e5c31af7Sopenharmony_ci allMembers = [member.name for member in structureType.members] 2678e5c31af7Sopenharmony_ci vkVersion = match.group(1) 2679e5c31af7Sopenharmony_ci blobMembers[vkVersion] = allMembers[2:] 2680e5c31af7Sopenharmony_ci blobStructs[vkVersion] = set() 2681e5c31af7Sopenharmony_ci initFromBlobDefinitions = [] 2682e5c31af7Sopenharmony_ci emptyInitDefinitions = [] 2683e5c31af7Sopenharmony_ci # iterate over all feature structures 2684e5c31af7Sopenharmony_ci allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*") 2685e5c31af7Sopenharmony_ci nonExtFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*$") 2686e5c31af7Sopenharmony_ci for structureType in api.compositeTypes: 2687e5c31af7Sopenharmony_ci # skip structures that are not feature structures 2688e5c31af7Sopenharmony_ci if not allFeaturesPattern.match(structureType.name): 2689e5c31af7Sopenharmony_ci continue 2690e5c31af7Sopenharmony_ci # skip structures that were previously identified as blobs 2691e5c31af7Sopenharmony_ci if blobPattern.match(structureType.name): 2692e5c31af7Sopenharmony_ci continue 2693e5c31af7Sopenharmony_ci # skip sType and pNext and just grab third and next attributes 2694e5c31af7Sopenharmony_ci structureMembers = structureType.members[2:] 2695e5c31af7Sopenharmony_ci notPartOfBlob = True 2696e5c31af7Sopenharmony_ci if nonExtFeaturesPattern.match(structureType.name): 2697e5c31af7Sopenharmony_ci # check if this member is part of any of the blobs 2698e5c31af7Sopenharmony_ci for blobName, blobMemberList in blobMembers.items(): 2699e5c31af7Sopenharmony_ci # if just one member is not part of this blob go to the next blob 2700e5c31af7Sopenharmony_ci # (we asume that all members are part of blob - no need to check all) 2701e5c31af7Sopenharmony_ci if structureMembers[0].name not in blobMemberList: 2702e5c31af7Sopenharmony_ci continue 2703e5c31af7Sopenharmony_ci # add another feature structure name to this blob 2704e5c31af7Sopenharmony_ci blobStructs[blobName].add(structureType) 2705e5c31af7Sopenharmony_ci # add specialization for this feature structure 2706e5c31af7Sopenharmony_ci memberCopying = "" 2707e5c31af7Sopenharmony_ci for member in structureMembers: 2708e5c31af7Sopenharmony_ci memberCopying += "\tfeatureType.{0} = allFeaturesBlobs.vk{1}.{0};\n".format(member.name, blobName) 2709e5c31af7Sopenharmony_ci wholeFunction = \ 2710e5c31af7Sopenharmony_ci "template<> void initFeatureFromBlob<{0}>({0}& featureType, const AllFeaturesBlobs& allFeaturesBlobs)\n" \ 2711e5c31af7Sopenharmony_ci "{{\n" \ 2712e5c31af7Sopenharmony_ci "{1}" \ 2713e5c31af7Sopenharmony_ci "}}".format(structureType.name, memberCopying) 2714e5c31af7Sopenharmony_ci initFromBlobDefinitions.append(wholeFunction) 2715e5c31af7Sopenharmony_ci notPartOfBlob = False 2716e5c31af7Sopenharmony_ci # assuming that all members are part of blob, goto next 2717e5c31af7Sopenharmony_ci break 2718e5c31af7Sopenharmony_ci # add empty template definition as on Fedora there are issue with 2719e5c31af7Sopenharmony_ci # linking using just generic template - all specializations are needed 2720e5c31af7Sopenharmony_ci if notPartOfBlob: 2721e5c31af7Sopenharmony_ci emptyFunction = "template<> void initFeatureFromBlob<{0}>({0}&, const AllFeaturesBlobs&) {{}}" 2722e5c31af7Sopenharmony_ci emptyInitDefinitions.append(emptyFunction.format(structureType.name)) 2723e5c31af7Sopenharmony_ci extensionDefines = [] 2724e5c31af7Sopenharmony_ci makeFeatureDescDefinitions = [] 2725e5c31af7Sopenharmony_ci featureStructWrappers = [] 2726e5c31af7Sopenharmony_ci for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extName, extNameDef, specVersionDef) in enumerate(dfDefs): 2727e5c31af7Sopenharmony_ci extensionNameDefinition = extNameDef 2728e5c31af7Sopenharmony_ci if not extensionNameDefinition: 2729e5c31af7Sopenharmony_ci extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType) 2730e5c31af7Sopenharmony_ci extensionDefines.append(f'#define {extensionNameDefinition} "core_feature"') 2731e5c31af7Sopenharmony_ci # construct makeFeatureDesc template function definitions 2732e5c31af7Sopenharmony_ci sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sVerSuffix + sExtSuffix) 2733e5c31af7Sopenharmony_ci makeFeatureDescDefinitions.append("template<> FeatureDesc makeFeatureDesc<{0}>(void) " \ 2734e5c31af7Sopenharmony_ci "{{ return FeatureDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVersionDef, len(dfDefs)-idx)) 2735e5c31af7Sopenharmony_ci # construct CreateFeatureStruct wrapper block 2736e5c31af7Sopenharmony_ci featureStructWrappers.append("\t{{ createFeatureStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVersionDef)) 2737e5c31af7Sopenharmony_ci # construct function that will check for which vk version structure sType is part of blob 2738e5c31af7Sopenharmony_ci blobChecker = "deUint32 getBlobFeaturesVersion (VkStructureType sType)\n{\n" \ 2739e5c31af7Sopenharmony_ci "\tconst std::map<VkStructureType, deUint32> sTypeBlobMap\n" \ 2740e5c31af7Sopenharmony_ci "\t{\n" 2741e5c31af7Sopenharmony_ci # iterate over blobs with list of structures 2742e5c31af7Sopenharmony_ci for blobName in sorted(blobStructs.keys()): 2743e5c31af7Sopenharmony_ci blobChecker += "\t\t// Vulkan{0}\n".format(blobName) 2744e5c31af7Sopenharmony_ci # iterate over all feature structures in current blob 2745e5c31af7Sopenharmony_ci structuresList = list(blobStructs[blobName]) 2746e5c31af7Sopenharmony_ci structuresList = sorted(structuresList, key=lambda s: s.name) 2747e5c31af7Sopenharmony_ci for structType in structuresList: 2748e5c31af7Sopenharmony_ci # find definition of this structure in dfDefs 2749e5c31af7Sopenharmony_ci structDef = None 2750e5c31af7Sopenharmony_ci allNamesToCheck = [structType.name] 2751e5c31af7Sopenharmony_ci if len(structType.aliasList) > 0: 2752e5c31af7Sopenharmony_ci allNamesToCheck.extend(structType.aliasList) 2753e5c31af7Sopenharmony_ci for structName in allNamesToCheck: 2754e5c31af7Sopenharmony_ci structDefList = [s for s in dfDefs if s[3] == structName] 2755e5c31af7Sopenharmony_ci if len(structDefList) > 0: 2756e5c31af7Sopenharmony_ci structDef = structDefList[0] 2757e5c31af7Sopenharmony_ci break 2758e5c31af7Sopenharmony_ci sType = structDef[0] 2759e5c31af7Sopenharmony_ci sSuffix = structDef[1] + structDef[2] 2760e5c31af7Sopenharmony_ci sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_FEATURES{1}".format(sType, sSuffix) 2761e5c31af7Sopenharmony_ci tabs = "\t" * int((88 - len(sTypeName)) / 4) 2762e5c31af7Sopenharmony_ci blobChecker += "\t\t{{ {0},{1}VK_API_VERSION_{2}_{3} }},\n".format(sTypeName, tabs, blobName[0], blobName[1]) 2763e5c31af7Sopenharmony_ci blobChecker += "\t};\n\n" \ 2764e5c31af7Sopenharmony_ci "\tauto it = sTypeBlobMap.find(sType);\n" \ 2765e5c31af7Sopenharmony_ci "\tif(it == sTypeBlobMap.end())\n" \ 2766e5c31af7Sopenharmony_ci "\t\treturn 0;\n" \ 2767e5c31af7Sopenharmony_ci "\treturn it->second;\n" \ 2768e5c31af7Sopenharmony_ci "}\n" 2769e5c31af7Sopenharmony_ci # combine all definition lists 2770e5c31af7Sopenharmony_ci stream = [ 2771e5c31af7Sopenharmony_ci '#include "vkDeviceFeatures.hpp"\n', 2772e5c31af7Sopenharmony_ci 'namespace vk\n{'] 2773e5c31af7Sopenharmony_ci stream.extend(extensionDefines) 2774e5c31af7Sopenharmony_ci stream.append('\n') 2775e5c31af7Sopenharmony_ci stream.extend(initFromBlobDefinitions) 2776e5c31af7Sopenharmony_ci stream.append('\n// generic template is not enough for some compilers') 2777e5c31af7Sopenharmony_ci stream.extend(emptyInitDefinitions) 2778e5c31af7Sopenharmony_ci stream.append('\n') 2779e5c31af7Sopenharmony_ci stream.extend(makeFeatureDescDefinitions) 2780e5c31af7Sopenharmony_ci stream.append('\n') 2781e5c31af7Sopenharmony_ci stream.append('static const FeatureStructCreationData featureStructCreationArray[]\n{') 2782e5c31af7Sopenharmony_ci stream.extend(featureStructWrappers) 2783e5c31af7Sopenharmony_ci stream.append('};\n') 2784e5c31af7Sopenharmony_ci stream.append(blobChecker) 2785e5c31af7Sopenharmony_ci stream.append('} // vk\n') 2786e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 2787e5c31af7Sopenharmony_ci 2788e5c31af7Sopenharmony_cidef writeDeviceFeatureTest(api, filename): 2789e5c31af7Sopenharmony_ci 2790e5c31af7Sopenharmony_ci coreFeaturesPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Features[0-9]*$") 2791e5c31af7Sopenharmony_ci featureItems = [] 2792e5c31af7Sopenharmony_ci testFunctions = [] 2793e5c31af7Sopenharmony_ci # iterate over all feature structures 2794e5c31af7Sopenharmony_ci allFeaturesPattern = re.compile("^VkPhysicalDevice\w+Features[1-9]*") 2795e5c31af7Sopenharmony_ci for structureType in api.compositeTypes: 2796e5c31af7Sopenharmony_ci # skip structures that are not feature structures 2797e5c31af7Sopenharmony_ci if not allFeaturesPattern.match(structureType.name): 2798e5c31af7Sopenharmony_ci continue 2799e5c31af7Sopenharmony_ci # skip sType and pNext and just grab third and next attributes 2800e5c31af7Sopenharmony_ci structureMembers = structureType.members[2:] 2801e5c31af7Sopenharmony_ci 2802e5c31af7Sopenharmony_ci items = [] 2803e5c31af7Sopenharmony_ci for member in structureMembers: 2804e5c31af7Sopenharmony_ci items.append(" FEATURE_ITEM ({0}, {1}),".format(structureType.name, member.name)) 2805e5c31af7Sopenharmony_ci 2806e5c31af7Sopenharmony_ci testBlock = """ 2807e5c31af7Sopenharmony_citcu::TestStatus createDeviceWithUnsupportedFeaturesTest{4} (Context& context) 2808e5c31af7Sopenharmony_ci{{ 2809e5c31af7Sopenharmony_ci const PlatformInterface& vkp = context.getPlatformInterface(); 2810e5c31af7Sopenharmony_ci tcu::TestLog& log = context.getTestContext().getLog(); 2811e5c31af7Sopenharmony_ci tcu::ResultCollector resultCollector (log); 2812e5c31af7Sopenharmony_ci const CustomInstance instance (createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true)); 2813e5c31af7Sopenharmony_ci const InstanceDriver& instanceDriver (instance.getDriver()); 2814e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine()); 2815e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = 0; 2816e5c31af7Sopenharmony_ci const deUint32 queueCount = 1; 2817e5c31af7Sopenharmony_ci const float queuePriority = 1.0f; 2818e5c31af7Sopenharmony_ci const DeviceFeatures deviceFeaturesAll (context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE); 2819e5c31af7Sopenharmony_ci const VkPhysicalDeviceFeatures2 deviceFeatures2 = deviceFeaturesAll.getCoreFeatures2(); 2820e5c31af7Sopenharmony_ci int numErrors = 0; 2821e5c31af7Sopenharmony_ci bool isSubProcess = context.getTestContext().getCommandLine().isSubProcess(); 2822e5c31af7Sopenharmony_ci{6} 2823e5c31af7Sopenharmony_ci 2824e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures emptyDeviceFeatures; 2825e5c31af7Sopenharmony_ci deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures)); 2826e5c31af7Sopenharmony_ci 2827e5c31af7Sopenharmony_ci // Only non-core extensions will be used when creating the device. 2828e5c31af7Sopenharmony_ci const auto& extensionNames = context.getDeviceCreationExtensions(); 2829e5c31af7Sopenharmony_ci DE_UNREF(extensionNames); // In some cases this is not used. 2830e5c31af7Sopenharmony_ci 2831e5c31af7Sopenharmony_ci if (const void* featuresStruct = findStructureInChain(const_cast<const void*>(deviceFeatures2.pNext), getStructureType<{0}>())) 2832e5c31af7Sopenharmony_ci {{ 2833e5c31af7Sopenharmony_ci static const Feature features[] = 2834e5c31af7Sopenharmony_ci {{ 2835e5c31af7Sopenharmony_ci{1} 2836e5c31af7Sopenharmony_ci }}; 2837e5c31af7Sopenharmony_ci auto* supportedFeatures = reinterpret_cast<const {0}*>(featuresStruct); 2838e5c31af7Sopenharmony_ci checkFeatures(vkp, instance, instanceDriver, physicalDevice, {2}, features, supportedFeatures, queueFamilyIndex, queueCount, queuePriority, numErrors, resultCollector, {3}, emptyDeviceFeatures, {5}, context.getUsedApiVersion()); 2839e5c31af7Sopenharmony_ci }} 2840e5c31af7Sopenharmony_ci 2841e5c31af7Sopenharmony_ci if (numErrors > 0) 2842e5c31af7Sopenharmony_ci return tcu::TestStatus(resultCollector.getResult(), "Enabling unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT."); 2843e5c31af7Sopenharmony_ci else 2844e5c31af7Sopenharmony_ci return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage()); 2845e5c31af7Sopenharmony_ci}} 2846e5c31af7Sopenharmony_ci""" 2847e5c31af7Sopenharmony_ci additionalParams = ( 'memReservationStatMax, isSubProcess' if api.apiName == 'vulkansc' else 'isSubProcess' ) 2848e5c31af7Sopenharmony_ci additionalDefs = ( ' VkDeviceObjectReservationCreateInfo memReservationStatMax = context.getResourceInterface()->getStatMax();' if apiName == 'vulkansc' else '') 2849e5c31af7Sopenharmony_ci featureItems.append(testBlock.format(structureType.name, "\n".join(items), len(items), ("DE_NULL" if coreFeaturesPattern.match(structureType.name) else "&extensionNames"), structureType.name[len('VkPhysicalDevice'):], additionalParams, additionalDefs)) 2850e5c31af7Sopenharmony_ci 2851e5c31af7Sopenharmony_ci testFunctions.append("createDeviceWithUnsupportedFeaturesTest" + structureType.name[len('VkPhysicalDevice'):]) 2852e5c31af7Sopenharmony_ci 2853e5c31af7Sopenharmony_ci stream = [''] 2854e5c31af7Sopenharmony_ci stream.extend(featureItems) 2855e5c31af7Sopenharmony_ci stream.append(""" 2856e5c31af7Sopenharmony_civoid addSeparateUnsupportedFeatureTests (tcu::TestCaseGroup* testGroup) 2857e5c31af7Sopenharmony_ci{ 2858e5c31af7Sopenharmony_ci""") 2859e5c31af7Sopenharmony_ci for x in testFunctions: 2860e5c31af7Sopenharmony_ci stream.append('\taddFunctionCase(testGroup, "' + camelToSnake(x[len('createDeviceWithUnsupportedFeaturesTest'):]) + '", ' + x + ');') 2861e5c31af7Sopenharmony_ci stream.append('}\n') 2862e5c31af7Sopenharmony_ci 2863e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 2864e5c31af7Sopenharmony_ci 2865e5c31af7Sopenharmony_cidef writeDeviceProperties(api, dpDefs, filename): 2866e5c31af7Sopenharmony_ci # find VkPhysicalDeviceVulkan[1-9][0-9]Features blob structurs 2867e5c31af7Sopenharmony_ci # and construct dictionary with all of their attributes 2868e5c31af7Sopenharmony_ci blobMembers = {} 2869e5c31af7Sopenharmony_ci blobStructs = {} 2870e5c31af7Sopenharmony_ci blobPattern = re.compile("^VkPhysicalDeviceVulkan([1-9][0-9])Properties[0-9]*$") 2871e5c31af7Sopenharmony_ci for structureType in api.compositeTypes: 2872e5c31af7Sopenharmony_ci match = blobPattern.match(structureType.name) 2873e5c31af7Sopenharmony_ci if match: 2874e5c31af7Sopenharmony_ci allMembers = [member.name for member in structureType.members] 2875e5c31af7Sopenharmony_ci vkVersion = match.group(1) 2876e5c31af7Sopenharmony_ci blobMembers[vkVersion] = allMembers[2:] 2877e5c31af7Sopenharmony_ci blobStructs[vkVersion] = set() 2878e5c31af7Sopenharmony_ci initFromBlobDefinitions = [] 2879e5c31af7Sopenharmony_ci emptyInitDefinitions = [] 2880e5c31af7Sopenharmony_ci # iterate over all property structures 2881e5c31af7Sopenharmony_ci allPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*") 2882e5c31af7Sopenharmony_ci nonExtPropertiesPattern = re.compile("^VkPhysicalDevice\w+Properties[1-9]*$") 2883e5c31af7Sopenharmony_ci for structureType in api.compositeTypes: 2884e5c31af7Sopenharmony_ci # skip structures that are not property structures 2885e5c31af7Sopenharmony_ci if not allPropertiesPattern.match(structureType.name): 2886e5c31af7Sopenharmony_ci continue 2887e5c31af7Sopenharmony_ci # skip structures that were previously identified as blobs 2888e5c31af7Sopenharmony_ci if blobPattern.match(structureType.name): 2889e5c31af7Sopenharmony_ci continue 2890e5c31af7Sopenharmony_ci # skip sType and pNext and just grab third and next attributes 2891e5c31af7Sopenharmony_ci structureMembers = structureType.members[2:] 2892e5c31af7Sopenharmony_ci notPartOfBlob = True 2893e5c31af7Sopenharmony_ci if nonExtPropertiesPattern.match(structureType.name): 2894e5c31af7Sopenharmony_ci # check if this member is part of any of the blobs 2895e5c31af7Sopenharmony_ci for blobName, blobMemberList in blobMembers.items(): 2896e5c31af7Sopenharmony_ci # if just one member is not part of this blob go to the next blob 2897e5c31af7Sopenharmony_ci # (we asume that all members are part of blob - no need to check all) 2898e5c31af7Sopenharmony_ci if structureMembers[0].name not in blobMemberList: 2899e5c31af7Sopenharmony_ci continue 2900e5c31af7Sopenharmony_ci # add another property structure name to this blob 2901e5c31af7Sopenharmony_ci blobStructs[blobName].add(structureType) 2902e5c31af7Sopenharmony_ci # add specialization for this property structure 2903e5c31af7Sopenharmony_ci memberCopying = "" 2904e5c31af7Sopenharmony_ci for member in structureMembers: 2905e5c31af7Sopenharmony_ci if len(member.arraySizeList) == 0: 2906e5c31af7Sopenharmony_ci # handle special case 2907e5c31af7Sopenharmony_ci if structureType.name == "VkPhysicalDeviceSubgroupProperties" and "subgroup" not in member.name : 2908e5c31af7Sopenharmony_ci blobMemberName = "subgroup" + member.name[0].capitalize() + member.name[1:] 2909e5c31af7Sopenharmony_ci memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{2};\n".format(member.name, blobName, blobMemberName) 2910e5c31af7Sopenharmony_ci # end handling special case 2911e5c31af7Sopenharmony_ci else: 2912e5c31af7Sopenharmony_ci memberCopying += "\tpropertyType.{0} = allPropertiesBlobs.vk{1}.{0};\n".format(member.name, blobName) 2913e5c31af7Sopenharmony_ci else: 2914e5c31af7Sopenharmony_ci memberCopying += "\tmemcpy(propertyType.{0}, allPropertiesBlobs.vk{1}.{0}, sizeof({2}) * {3});\n".format(member.name, blobName, member.type, member.arraySizeList[0]) 2915e5c31af7Sopenharmony_ci wholeFunction = \ 2916e5c31af7Sopenharmony_ci "template<> void initPropertyFromBlob<{0}>({0}& propertyType, const AllPropertiesBlobs& allPropertiesBlobs)\n" \ 2917e5c31af7Sopenharmony_ci "{{\n" \ 2918e5c31af7Sopenharmony_ci "{1}" \ 2919e5c31af7Sopenharmony_ci "}}".format(structureType.name, memberCopying) 2920e5c31af7Sopenharmony_ci initFromBlobDefinitions.append(wholeFunction) 2921e5c31af7Sopenharmony_ci notPartOfBlob = False 2922e5c31af7Sopenharmony_ci # assuming that all members are part of blob, goto next 2923e5c31af7Sopenharmony_ci break 2924e5c31af7Sopenharmony_ci # add empty template definition as on Fedora there are issue with 2925e5c31af7Sopenharmony_ci # linking using just generic template - all specializations are needed 2926e5c31af7Sopenharmony_ci if notPartOfBlob: 2927e5c31af7Sopenharmony_ci emptyFunction = "template<> void initPropertyFromBlob<{0}>({0}&, const AllPropertiesBlobs&) {{}}" 2928e5c31af7Sopenharmony_ci emptyInitDefinitions.append(emptyFunction.format(structureType.name)) 2929e5c31af7Sopenharmony_ci extensionDefines = [] 2930e5c31af7Sopenharmony_ci makePropertyDescDefinitions = [] 2931e5c31af7Sopenharmony_ci propertyStructWrappers = [] 2932e5c31af7Sopenharmony_ci for idx, (sType, sVerSuffix, sExtSuffix, extStruct, extName, extNameDef, specVersionDef) in enumerate(dpDefs): 2933e5c31af7Sopenharmony_ci extensionNameDefinition = extNameDef 2934e5c31af7Sopenharmony_ci if not extensionNameDefinition: 2935e5c31af7Sopenharmony_ci extensionNameDefinition = 'DECL{0}_{1}_EXTENSION_NAME'.format((sExtSuffix if sExtSuffix else ''), sType) 2936e5c31af7Sopenharmony_ci extensionDefines.append(f'#define {extensionNameDefinition} "core_property"') 2937e5c31af7Sopenharmony_ci # construct makePropertyDesc template function definitions 2938e5c31af7Sopenharmony_ci sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sVerSuffix + sExtSuffix) 2939e5c31af7Sopenharmony_ci makePropertyDescDefinitions.append("template<> PropertyDesc makePropertyDesc<{0}>(void) " \ 2940e5c31af7Sopenharmony_ci "{{ return PropertyDesc{{{1}, {2}, {3}, {4}}}; }}".format(extStruct, sTypeName, extensionNameDefinition, specVersionDef, len(dpDefs)-idx)) 2941e5c31af7Sopenharmony_ci # construct CreateProperty struct wrapper block 2942e5c31af7Sopenharmony_ci propertyStructWrappers.append("\t{{ createPropertyStructWrapper<{0}>, {1}, {2} }},".format(extStruct, extensionNameDefinition, specVersionDef)) 2943e5c31af7Sopenharmony_ci # construct method that will check if structure sType is part of blob 2944e5c31af7Sopenharmony_ci blobChecker = "deUint32 getBlobPropertiesVersion (VkStructureType sType)\n{\n" \ 2945e5c31af7Sopenharmony_ci "\tconst std::map<VkStructureType, deUint32> sTypeBlobMap\n" \ 2946e5c31af7Sopenharmony_ci "\t{\n" 2947e5c31af7Sopenharmony_ci # iterate over blobs with list of structures 2948e5c31af7Sopenharmony_ci for blobName in sorted(blobStructs.keys()): 2949e5c31af7Sopenharmony_ci blobChecker += "\t\t// Vulkan{0}\n".format(blobName) 2950e5c31af7Sopenharmony_ci # iterate over all feature structures in current blob 2951e5c31af7Sopenharmony_ci structuresList = list(blobStructs[blobName]) 2952e5c31af7Sopenharmony_ci structuresList = sorted(structuresList, key=lambda s: s.name) 2953e5c31af7Sopenharmony_ci for structType in structuresList: 2954e5c31af7Sopenharmony_ci # find definition of this structure in dpDefs 2955e5c31af7Sopenharmony_ci structName = structType.name 2956e5c31af7Sopenharmony_ci structDef = None 2957e5c31af7Sopenharmony_ci foundDefs = [s for s in dpDefs if s[3] == structName] 2958e5c31af7Sopenharmony_ci if len(foundDefs) > 0: 2959e5c31af7Sopenharmony_ci structDef = foundDefs[0] 2960e5c31af7Sopenharmony_ci else: 2961e5c31af7Sopenharmony_ci for alias in structType.aliasList: 2962e5c31af7Sopenharmony_ci foundDefs = [s for s in dpDefs if s[3] == alias] 2963e5c31af7Sopenharmony_ci if len(foundDefs) > 0: 2964e5c31af7Sopenharmony_ci structDef = foundDefs[0] 2965e5c31af7Sopenharmony_ci break 2966e5c31af7Sopenharmony_ci sType = structDef[0] 2967e5c31af7Sopenharmony_ci sSuffix = structDef[1] + structDef[2] 2968e5c31af7Sopenharmony_ci sTypeName = "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_{0}_PROPERTIES{1}".format(sType, sSuffix) 2969e5c31af7Sopenharmony_ci tabs = "\t" * int((80 - len(sTypeName)) / 4) 2970e5c31af7Sopenharmony_ci blobChecker += "\t\t{{ {0},{1}VK_API_VERSION_{2}_{3} }},\n".format(sTypeName, tabs, blobName[0], blobName[1]) 2971e5c31af7Sopenharmony_ci blobChecker += "\t};\n\n" \ 2972e5c31af7Sopenharmony_ci "\tauto it = sTypeBlobMap.find(sType);\n" \ 2973e5c31af7Sopenharmony_ci "\tif(it == sTypeBlobMap.end())\n" \ 2974e5c31af7Sopenharmony_ci "\t\treturn 0;\n" \ 2975e5c31af7Sopenharmony_ci "\treturn it->second;\n" \ 2976e5c31af7Sopenharmony_ci "}\n" 2977e5c31af7Sopenharmony_ci # combine all definition lists 2978e5c31af7Sopenharmony_ci stream = [ 2979e5c31af7Sopenharmony_ci '#include "vkDeviceProperties.hpp"\n', 2980e5c31af7Sopenharmony_ci 'namespace vk\n{'] 2981e5c31af7Sopenharmony_ci stream.extend(extensionDefines) 2982e5c31af7Sopenharmony_ci stream.append('\n') 2983e5c31af7Sopenharmony_ci stream.extend(initFromBlobDefinitions) 2984e5c31af7Sopenharmony_ci stream.append('\n// generic template is not enough for some compilers') 2985e5c31af7Sopenharmony_ci stream.extend(emptyInitDefinitions) 2986e5c31af7Sopenharmony_ci stream.append('\n') 2987e5c31af7Sopenharmony_ci stream.extend(makePropertyDescDefinitions) 2988e5c31af7Sopenharmony_ci stream.append('\n') 2989e5c31af7Sopenharmony_ci stream.append('static const PropertyStructCreationData propertyStructCreationArray[] =\n{') 2990e5c31af7Sopenharmony_ci stream.extend(propertyStructWrappers) 2991e5c31af7Sopenharmony_ci stream.append('};\n') 2992e5c31af7Sopenharmony_ci stream.append(blobChecker) 2993e5c31af7Sopenharmony_ci stream.append('} // vk\n') 2994e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 2995e5c31af7Sopenharmony_ci 2996e5c31af7Sopenharmony_ciUNSUFFIXED_STRUCTURES = [ 2997e5c31af7Sopenharmony_ci "CornerSampledImage", 2998e5c31af7Sopenharmony_ci "ShaderSMBuiltins", 2999e5c31af7Sopenharmony_ci "ShadingRateImage", 3000e5c31af7Sopenharmony_ci "RayTracing", 3001e5c31af7Sopenharmony_ci "RepresentativeFragmentTest", 3002e5c31af7Sopenharmony_ci "ComputeShaderDerivatives", 3003e5c31af7Sopenharmony_ci "MeshShader", 3004e5c31af7Sopenharmony_ci "ShaderImageFootprint", 3005e5c31af7Sopenharmony_ci "ExclusiveScissor", 3006e5c31af7Sopenharmony_ci "DedicatedAllocationImageAliasing", 3007e5c31af7Sopenharmony_ci "CoverageReductionMode", 3008e5c31af7Sopenharmony_ci "DeviceGeneratedCommands", 3009e5c31af7Sopenharmony_ci "InheritedViewportScissor", 3010e5c31af7Sopenharmony_ci "PresentBarrier", 3011e5c31af7Sopenharmony_ci "DiagnosticsConfig", 3012e5c31af7Sopenharmony_ci "FragmentShadingRateEnums", 3013e5c31af7Sopenharmony_ci "RayTracingMotionBlur", 3014e5c31af7Sopenharmony_ci "ExternalMemoryRDMA", 3015e5c31af7Sopenharmony_ci "CopyMemoryIndirect", 3016e5c31af7Sopenharmony_ci "MemoryDecompression", 3017e5c31af7Sopenharmony_ci "LinearColorAttachment", 3018e5c31af7Sopenharmony_ci "OpticalFlow", 3019e5c31af7Sopenharmony_ci "RayTracingInvocationReorder", 3020e5c31af7Sopenharmony_ci "DisplacementMicromap"] 3021e5c31af7Sopenharmony_ci 3022e5c31af7Sopenharmony_cidef deviceFeaturesOrPropertiesGetter(name): 3023e5c31af7Sopenharmony_ci result = name[16:] # Remove VkPhysicalDevice prefix 3024e5c31af7Sopenharmony_ci if result[-3:] == "KHR": 3025e5c31af7Sopenharmony_ci result = result[0:-3] 3026e5c31af7Sopenharmony_ci elif result[-2:] == "NV": 3027e5c31af7Sopenharmony_ci suffix = result[-2:] 3028e5c31af7Sopenharmony_ci result = result[0:-2] 3029e5c31af7Sopenharmony_ci if result[-8:] == "Features": 3030e5c31af7Sopenharmony_ci infix = result[-8:] 3031e5c31af7Sopenharmony_ci result = result[0:-8] 3032e5c31af7Sopenharmony_ci elif result[-10:] == "Properties": 3033e5c31af7Sopenharmony_ci infix = result[-10:] 3034e5c31af7Sopenharmony_ci result = result[0:-10] 3035e5c31af7Sopenharmony_ci if (result in UNSUFFIXED_STRUCTURES): 3036e5c31af7Sopenharmony_ci suffix = "" 3037e5c31af7Sopenharmony_ci result = result + infix + suffix 3038e5c31af7Sopenharmony_ci return result 3039e5c31af7Sopenharmony_ci 3040e5c31af7Sopenharmony_cidef genericDeviceFeaturesWriter(dfDefs, pattern, filename): 3041e5c31af7Sopenharmony_ci stream = [] 3042e5c31af7Sopenharmony_ci for _, _, _, extStruct, _, _, _ in dfDefs: 3043e5c31af7Sopenharmony_ci nameSubStr = deviceFeaturesOrPropertiesGetter(extStruct) 3044e5c31af7Sopenharmony_ci stream.append(pattern.format(extStruct, nameSubStr)) 3045e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, indentLines(stream)) 3046e5c31af7Sopenharmony_ci 3047e5c31af7Sopenharmony_cidef writeDeviceFeaturesDefaultDeviceDefs(dfDefs, filename): 3048e5c31af7Sopenharmony_ci pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceFeatures.getFeatureType<{0}>();\t}}" 3049e5c31af7Sopenharmony_ci genericDeviceFeaturesWriter(dfDefs, pattern, filename) 3050e5c31af7Sopenharmony_ci 3051e5c31af7Sopenharmony_cidef writeDeviceFeaturesContextDecl(dfDefs, filename): 3052e5c31af7Sopenharmony_ci pattern = "const vk::{0}&\tget{1}\t(void) const;" 3053e5c31af7Sopenharmony_ci genericDeviceFeaturesWriter(dfDefs, pattern, filename) 3054e5c31af7Sopenharmony_ci 3055e5c31af7Sopenharmony_cidef writeDeviceFeaturesContextDefs(dfDefs, filename): 3056e5c31af7Sopenharmony_ci pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}" 3057e5c31af7Sopenharmony_ci genericDeviceFeaturesWriter(dfDefs, pattern, filename) 3058e5c31af7Sopenharmony_ci 3059e5c31af7Sopenharmony_cidef genericDevicePropertiesWriter(dfDefs, pattern, filename): 3060e5c31af7Sopenharmony_ci stream = [] 3061e5c31af7Sopenharmony_ci for _, _, _, extStruct, _, _, _ in dfDefs: 3062e5c31af7Sopenharmony_ci nameSubStr = deviceFeaturesOrPropertiesGetter(extStruct) 3063e5c31af7Sopenharmony_ci stream.append(pattern.format(extStruct, nameSubStr)) 3064e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, indentLines(stream)) 3065e5c31af7Sopenharmony_ci 3066e5c31af7Sopenharmony_cidef writeDevicePropertiesDefaultDeviceDefs(dfDefs, filename): 3067e5c31af7Sopenharmony_ci pattern = "const {0}&\tget{1}\t(void) const {{ return m_deviceProperties.getPropertyType<{0}>();\t}}" 3068e5c31af7Sopenharmony_ci genericDevicePropertiesWriter(dfDefs, pattern, filename) 3069e5c31af7Sopenharmony_ci 3070e5c31af7Sopenharmony_cidef writeDevicePropertiesContextDecl(dfDefs, filename): 3071e5c31af7Sopenharmony_ci pattern = "const vk::{0}&\tget{1}\t(void) const;" 3072e5c31af7Sopenharmony_ci genericDevicePropertiesWriter(dfDefs, pattern, filename) 3073e5c31af7Sopenharmony_ci 3074e5c31af7Sopenharmony_cidef writeDevicePropertiesContextDefs(dfDefs, filename): 3075e5c31af7Sopenharmony_ci pattern = "const vk::{0}&\tContext::get{1}\t(void) const {{ return m_device->get{1}();\t}}" 3076e5c31af7Sopenharmony_ci genericDevicePropertiesWriter(dfDefs, pattern, filename) 3077e5c31af7Sopenharmony_ci 3078e5c31af7Sopenharmony_cidef writeMandatoryFeatures(api, filename): 3079e5c31af7Sopenharmony_ci 3080e5c31af7Sopenharmony_ci def structInAPI(name): 3081e5c31af7Sopenharmony_ci for c in api.compositeTypes: 3082e5c31af7Sopenharmony_ci if c.name == name: 3083e5c31af7Sopenharmony_ci return True 3084e5c31af7Sopenharmony_ci for alias in c.aliasList: 3085e5c31af7Sopenharmony_ci if alias == name: 3086e5c31af7Sopenharmony_ci return True 3087e5c31af7Sopenharmony_ci return False 3088e5c31af7Sopenharmony_ci stream = [] 3089e5c31af7Sopenharmony_ci 3090e5c31af7Sopenharmony_ci dictStructs = {} 3091e5c31af7Sopenharmony_ci dictData = [] 3092e5c31af7Sopenharmony_ci extData = [] 3093e5c31af7Sopenharmony_ci usedFeatureStructs = {} 3094e5c31af7Sopenharmony_ci for _, data in api.additionalExtensionData: 3095e5c31af7Sopenharmony_ci if 'mandatory_features' in data.keys(): 3096e5c31af7Sopenharmony_ci # sort to have same results for py2 and py3 3097e5c31af7Sopenharmony_ci listStructFeatures = sorted(data['mandatory_features'].items(), key=lambda tup: tup[0]) 3098e5c31af7Sopenharmony_ci for structure, featuresList in listStructFeatures: 3099e5c31af7Sopenharmony_ci for featureData in featuresList: 3100e5c31af7Sopenharmony_ci # allow for featureless VKSC only extensions 3101e5c31af7Sopenharmony_ci if not 'features' in featureData.keys() or 'requirements' not in featureData.keys(): 3102e5c31af7Sopenharmony_ci continue 3103e5c31af7Sopenharmony_ci requirements = featureData['requirements'] 3104e5c31af7Sopenharmony_ci 3105e5c31af7Sopenharmony_ci mandatory_variant = '' 3106e5c31af7Sopenharmony_ci try: 3107e5c31af7Sopenharmony_ci mandatory_variant = featureData['mandatory_variant'] 3108e5c31af7Sopenharmony_ci except KeyError: 3109e5c31af7Sopenharmony_ci mandatory_variant = '' 3110e5c31af7Sopenharmony_ci 3111e5c31af7Sopenharmony_ci dictData.append( [ structure, featureData['features'], requirements, mandatory_variant] ) 3112e5c31af7Sopenharmony_ci 3113e5c31af7Sopenharmony_ci if structure == 'VkPhysicalDeviceFeatures': 3114e5c31af7Sopenharmony_ci continue 3115e5c31af7Sopenharmony_ci 3116e5c31af7Sopenharmony_ci # if structure is not in dict construct name of variable and add is as a first item 3117e5c31af7Sopenharmony_ci if (structure not in dictStructs): 3118e5c31af7Sopenharmony_ci dictStructs[structure] = ([structure[2:3].lower() + structure[3:]], mandatory_variant) 3119e5c31af7Sopenharmony_ci # add first requirement if it is unique 3120e5c31af7Sopenharmony_ci if requirements and (requirements[0] not in dictStructs[structure][0]): 3121e5c31af7Sopenharmony_ci dictStructs[structure][0].append(requirements[0]) 3122e5c31af7Sopenharmony_ci 3123e5c31af7Sopenharmony_ci usedFeatureStructs[structure] = [] 3124e5c31af7Sopenharmony_ci 3125e5c31af7Sopenharmony_ci if requirements: 3126e5c31af7Sopenharmony_ci for req in requirements: 3127e5c31af7Sopenharmony_ci if '.' in req: 3128e5c31af7Sopenharmony_ci req = req.split('.')[0] 3129e5c31af7Sopenharmony_ci reqStruct = 'Vk' + req[0].upper() + req[1:] 3130e5c31af7Sopenharmony_ci usedFeatureStructs[reqStruct] = [] 3131e5c31af7Sopenharmony_ci 3132e5c31af7Sopenharmony_ci if 'mandatory_extensions' in data: 3133e5c31af7Sopenharmony_ci mandatoryExtensions = [] 3134e5c31af7Sopenharmony_ci for mandatoryExt in data['mandatory_extensions']: 3135e5c31af7Sopenharmony_ci if 'extension' in mandatoryExt: 3136e5c31af7Sopenharmony_ci extName = mandatoryExt.pop('extension') 3137e5c31af7Sopenharmony_ci mandatoryExtensions.append((extName, mandatoryExt)) 3138e5c31af7Sopenharmony_ci 3139e5c31af7Sopenharmony_ci for extension, extensionData in mandatoryExtensions: 3140e5c31af7Sopenharmony_ci # requirements are actually mandatory. 3141e5c31af7Sopenharmony_ci if 'requirements' not in extensionData: 3142e5c31af7Sopenharmony_ci continue 3143e5c31af7Sopenharmony_ci 3144e5c31af7Sopenharmony_ci requirements = extensionData['requirements'] 3145e5c31af7Sopenharmony_ci mandatory_variant = '' if 'mandatory_variant' not in extensionData else extensionData['mandatory_variant'] 3146e5c31af7Sopenharmony_ci extData.append((extension, requirements, mandatory_variant)) 3147e5c31af7Sopenharmony_ci 3148e5c31af7Sopenharmony_ci for req in requirements: 3149e5c31af7Sopenharmony_ci if '.' in req: 3150e5c31af7Sopenharmony_ci req = req.split('.')[0] 3151e5c31af7Sopenharmony_ci reqStruct = 'Vk' + req[0].upper() + req[1:] 3152e5c31af7Sopenharmony_ci usedFeatureStructs[reqStruct] = [] 3153e5c31af7Sopenharmony_ci 3154e5c31af7Sopenharmony_ci stream.extend(['bool canUseFeaturesStruct (const vector<VkExtensionProperties>& deviceExtensions, uint32_t usedApiVersion, const char* extension)', 3155e5c31af7Sopenharmony_ci '{', 3156e5c31af7Sopenharmony_ci '\treturn (isExtensionStructSupported(deviceExtensions, RequiredExtension(extension))', 3157e5c31af7Sopenharmony_ci '\t\t\t|| isCoreDeviceExtension(usedApiVersion, extension));', 3158e5c31af7Sopenharmony_ci '}', 3159e5c31af7Sopenharmony_ci '', 3160e5c31af7Sopenharmony_ci 'bool checkMandatoryFeatures(const vkt::Context& context)\n{', 3161e5c31af7Sopenharmony_ci '\tif (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))', 3162e5c31af7Sopenharmony_ci '\t\tTCU_THROW(NotSupportedError, "Extension VK_KHR_get_physical_device_properties2 is not present");', 3163e5c31af7Sopenharmony_ci '', 3164e5c31af7Sopenharmony_ci '\tVkPhysicalDevice\t\t\t\t\tphysicalDevice\t\t= context.getPhysicalDevice();', 3165e5c31af7Sopenharmony_ci '\tconst InstanceInterface&\t\t\tvki\t\t\t\t\t= context.getInstanceInterface();', 3166e5c31af7Sopenharmony_ci '\tconst vector<VkExtensionProperties>\tdeviceExtensions\t= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);', 3167e5c31af7Sopenharmony_ci '\tconst uint32_t\t\t\t\t\t\tusedApiVersion\t\t= context.getUsedApiVersion();', 3168e5c31af7Sopenharmony_ci '', 3169e5c31af7Sopenharmony_ci '\ttcu::TestLog& log = context.getTestContext().getLog();', 3170e5c31af7Sopenharmony_ci '\tvk::VkPhysicalDeviceFeatures2 coreFeatures;', 3171e5c31af7Sopenharmony_ci '\tdeMemset(&coreFeatures, 0, sizeof(coreFeatures));', 3172e5c31af7Sopenharmony_ci '\tcoreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;', 3173e5c31af7Sopenharmony_ci '\tvoid** nextPtr = &coreFeatures.pNext;', 3174e5c31af7Sopenharmony_ci '']) 3175e5c31af7Sopenharmony_ci 3176e5c31af7Sopenharmony_ci # Find the extensions that added the required feature structs. 3177e5c31af7Sopenharmony_ci class StructFoundContinue(Exception): 3178e5c31af7Sopenharmony_ci pass 3179e5c31af7Sopenharmony_ci 3180e5c31af7Sopenharmony_ci for usedStruct in usedFeatureStructs: 3181e5c31af7Sopenharmony_ci for compType in api.compositeTypes: 3182e5c31af7Sopenharmony_ci nameList = [compType.name] + compType.aliasList 3183e5c31af7Sopenharmony_ci if usedStruct in nameList: 3184e5c31af7Sopenharmony_ci # Found the official name list for the struct. 3185e5c31af7Sopenharmony_ci for extension in api.extensions: 3186e5c31af7Sopenharmony_ci try: 3187e5c31af7Sopenharmony_ci for requirement in extension.requirementsList: 3188e5c31af7Sopenharmony_ci for extensionStructure in requirement.newTypes: 3189e5c31af7Sopenharmony_ci if extensionStructure.name in nameList: 3190e5c31af7Sopenharmony_ci # Found extension for the struct. 3191e5c31af7Sopenharmony_ci usedFeatureStructs[usedStruct].append(extension.name) 3192e5c31af7Sopenharmony_ci raise StructFoundContinue 3193e5c31af7Sopenharmony_ci except StructFoundContinue: 3194e5c31af7Sopenharmony_ci pass 3195e5c31af7Sopenharmony_ci 3196e5c31af7Sopenharmony_ci structList = sorted(usedFeatureStructs.items(), key=lambda tup: tup[0]) # sort to have same results for py2 and py3 3197e5c31af7Sopenharmony_ci apiStructs = list( filter(lambda x : structInAPI(x[0]), structList)) # remove items not defined in current API 3198e5c31af7Sopenharmony_ci 3199e5c31af7Sopenharmony_ci for structName, extensions in apiStructs: 3200e5c31af7Sopenharmony_ci metaCondition = '' 3201e5c31af7Sopenharmony_ci if structName in dictStructs: 3202e5c31af7Sopenharmony_ci mandatoryVariantList = dictStructs[structName][1] 3203e5c31af7Sopenharmony_ci if len(mandatoryVariantList) > 0: 3204e5c31af7Sopenharmony_ci mandatoryVariant = mandatoryVariantList[0] 3205e5c31af7Sopenharmony_ci metaCondition = 'defined(CTS_USES_' + mandatoryVariant.upper() + ')' 3206e5c31af7Sopenharmony_ci stream.append('#if ' + metaCondition) 3207e5c31af7Sopenharmony_ci 3208e5c31af7Sopenharmony_ci # The variable name will be the structure name without the Vk prefix and starting in lowercase. 3209e5c31af7Sopenharmony_ci newVar = structName[2].lower() + structName[3:] 3210e5c31af7Sopenharmony_ci 3211e5c31af7Sopenharmony_ci stream.extend(['\tvk::' + structName + ' ' + newVar + ';', 3212e5c31af7Sopenharmony_ci '\tdeMemset(&' + newVar + ', 0, sizeof(' + newVar + '));', 3213e5c31af7Sopenharmony_ci '']) 3214e5c31af7Sopenharmony_ci 3215e5c31af7Sopenharmony_ci if len(extensions) > 0: 3216e5c31af7Sopenharmony_ci canUseCond = '\tif (' 3217e5c31af7Sopenharmony_ci for (i, extName) in enumerate(extensions): 3218e5c31af7Sopenharmony_ci canUseCond += ' ' if i == 0 else ' || ' 3219e5c31af7Sopenharmony_ci canUseCond += 'canUseFeaturesStruct(deviceExtensions, usedApiVersion, "' + extName + '")' 3220e5c31af7Sopenharmony_ci canUseCond += ' )' 3221e5c31af7Sopenharmony_ci stream.append(canUseCond) 3222e5c31af7Sopenharmony_ci elif api.apiName == "vulkan" and structName in dictStructs: 3223e5c31af7Sopenharmony_ci #reqs = v[0][1:] 3224e5c31af7Sopenharmony_ci reqs = dictStructs[structName][0][1:] 3225e5c31af7Sopenharmony_ci cond = 'if ( ' 3226e5c31af7Sopenharmony_ci for i, req in enumerate(reqs): 3227e5c31af7Sopenharmony_ci if i > 0: 3228e5c31af7Sopenharmony_ci cond = cond + ' || ' 3229e5c31af7Sopenharmony_ci if (req.startswith("ApiVersion")): 3230e5c31af7Sopenharmony_ci cond = cond + 'context.contextSupports(vk::' + req + ')' 3231e5c31af7Sopenharmony_ci cond = cond + ' )' 3232e5c31af7Sopenharmony_ci stream.append('\t' + cond) 3233e5c31af7Sopenharmony_ci 3234e5c31af7Sopenharmony_ci stream.extend(['\t{', 3235e5c31af7Sopenharmony_ci '\t\t' + newVar + '.sType = getStructureType<' + structName + '>();', 3236e5c31af7Sopenharmony_ci '\t\t*nextPtr = &' + newVar + ';', 3237e5c31af7Sopenharmony_ci '\t\tnextPtr = &' + newVar + '.pNext;', 3238e5c31af7Sopenharmony_ci '\t}']) 3239e5c31af7Sopenharmony_ci 3240e5c31af7Sopenharmony_ci if len(metaCondition) > 0: 3241e5c31af7Sopenharmony_ci stream.append('#endif // ' + metaCondition) 3242e5c31af7Sopenharmony_ci 3243e5c31af7Sopenharmony_ci stream.append('') 3244e5c31af7Sopenharmony_ci 3245e5c31af7Sopenharmony_ci stream.extend(['\tcontext.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &coreFeatures);', 3246e5c31af7Sopenharmony_ci '\tbool result = true;', 3247e5c31af7Sopenharmony_ci '']) 3248e5c31af7Sopenharmony_ci 3249e5c31af7Sopenharmony_ci for v in dictData: 3250e5c31af7Sopenharmony_ci if not structInAPI(v[0]): # remove items not defined in current API ( important for Vulkan SC ) 3251e5c31af7Sopenharmony_ci continue 3252e5c31af7Sopenharmony_ci structType = v[0]; 3253e5c31af7Sopenharmony_ci structName = 'coreFeatures.features'; 3254e5c31af7Sopenharmony_ci metaCondition = '' 3255e5c31af7Sopenharmony_ci if len(v) == 4 and v[3] != '': 3256e5c31af7Sopenharmony_ci # for x in v[3].split('_'): 3257e5c31af7Sopenharmony_ci metaCondition = metaCondition + ' || defined(CTS_USES_' + v[3][0].upper() + ')' 3258e5c31af7Sopenharmony_ci stream.extend(['#if ' + metaCondition[4:]]) 3259e5c31af7Sopenharmony_ci if v[0] != 'VkPhysicalDeviceFeatures' : 3260e5c31af7Sopenharmony_ci structName = dictStructs[v[0]][0][0] 3261e5c31af7Sopenharmony_ci if len(v[2]) > 0 : 3262e5c31af7Sopenharmony_ci condition = 'if ( ' 3263e5c31af7Sopenharmony_ci for i, req in enumerate(v[2]) : 3264e5c31af7Sopenharmony_ci if (req.startswith("ApiVersion")): 3265e5c31af7Sopenharmony_ci condition = condition + 'context.contextSupports(vk::' + req + ')' 3266e5c31af7Sopenharmony_ci elif '.' in req: 3267e5c31af7Sopenharmony_ci condition = condition + req 3268e5c31af7Sopenharmony_ci else: 3269e5c31af7Sopenharmony_ci condition = condition + 'isExtensionStructSupported(deviceExtensions, RequiredExtension("' + req + '"))' 3270e5c31af7Sopenharmony_ci if i+1 < len(v[2]) : 3271e5c31af7Sopenharmony_ci condition = condition + ' && ' 3272e5c31af7Sopenharmony_ci condition = condition + ' )' 3273e5c31af7Sopenharmony_ci stream.append('\t' + condition) 3274e5c31af7Sopenharmony_ci stream.append('\t{') 3275e5c31af7Sopenharmony_ci # Don't need to support an AND case since that would just be another line in the .txt 3276e5c31af7Sopenharmony_ci if len(v[1]) == 1: 3277e5c31af7Sopenharmony_ci stream.append('\t\tif ( ' + structName + '.' + v[1][0] + ' == VK_FALSE )') 3278e5c31af7Sopenharmony_ci else: 3279e5c31af7Sopenharmony_ci condition = 'if ( ' 3280e5c31af7Sopenharmony_ci for i, feature in enumerate(v[1]): 3281e5c31af7Sopenharmony_ci if i != 0: 3282e5c31af7Sopenharmony_ci condition = condition + ' && ' 3283e5c31af7Sopenharmony_ci condition = condition + '( ' + structName + '.' + feature + ' == VK_FALSE )' 3284e5c31af7Sopenharmony_ci condition = condition + ' )' 3285e5c31af7Sopenharmony_ci stream.append('\t\t' + condition) 3286e5c31af7Sopenharmony_ci featureSet = " or ".join(v[1]) 3287e5c31af7Sopenharmony_ci stream.extend(['\t\t{', 3288e5c31af7Sopenharmony_ci '\t\t\tlog << tcu::TestLog::Message << "Mandatory feature ' + featureSet + ' not supported" << tcu::TestLog::EndMessage;', 3289e5c31af7Sopenharmony_ci '\t\t\tresult = false;', 3290e5c31af7Sopenharmony_ci '\t\t}', 3291e5c31af7Sopenharmony_ci '\t}']) 3292e5c31af7Sopenharmony_ci if metaCondition != '': 3293e5c31af7Sopenharmony_ci stream.extend(['#endif // ' + metaCondition[4:], 3294e5c31af7Sopenharmony_ci '']) 3295e5c31af7Sopenharmony_ci else: 3296e5c31af7Sopenharmony_ci stream.extend(['']) 3297e5c31af7Sopenharmony_ci 3298e5c31af7Sopenharmony_ci for extension, requirements, mandatory_variant in extData: 3299e5c31af7Sopenharmony_ci metaCondition = '' 3300e5c31af7Sopenharmony_ci if mandatory_variant != '': 3301e5c31af7Sopenharmony_ci metaCondition = metaCondition + ' || defined(CTS_USES_' + mandatory_variant[0].upper() + ')' 3302e5c31af7Sopenharmony_ci stream.extend(['#if ' + metaCondition[4:]]) 3303e5c31af7Sopenharmony_ci if len(requirements) > 0 : 3304e5c31af7Sopenharmony_ci condition = 'if ( ' 3305e5c31af7Sopenharmony_ci for i, req in enumerate(requirements) : 3306e5c31af7Sopenharmony_ci if (req.startswith("ApiVersion")): 3307e5c31af7Sopenharmony_ci condition = condition + 'context.contextSupports(vk::' + req + ')' 3308e5c31af7Sopenharmony_ci elif '.' in req: 3309e5c31af7Sopenharmony_ci condition = condition + req 3310e5c31af7Sopenharmony_ci else: 3311e5c31af7Sopenharmony_ci condition = condition + 'isExtensionStructSupported(deviceExtensions, RequiredExtension("' + req + '"))' 3312e5c31af7Sopenharmony_ci if i+1 < len(requirements) : 3313e5c31af7Sopenharmony_ci condition = condition + ' && ' 3314e5c31af7Sopenharmony_ci condition = condition + ' )' 3315e5c31af7Sopenharmony_ci stream.append('\t' + condition) 3316e5c31af7Sopenharmony_ci stream.append('\t{') 3317e5c31af7Sopenharmony_ci stream.extend(['\t\tif (!(isExtensionStructSupported(deviceExtensions, RequiredExtension("' + extension + '")) || isCoreDeviceExtension(usedApiVersion, "' + extension + '")))', 3318e5c31af7Sopenharmony_ci '\t\t{', 3319e5c31af7Sopenharmony_ci '\t\t\tlog << tcu::TestLog::Message << "Mandatory extension ' + extension + ' not supported" << tcu::TestLog::EndMessage;', 3320e5c31af7Sopenharmony_ci '\t\t\tresult = false;', 3321e5c31af7Sopenharmony_ci '\t\t}', 3322e5c31af7Sopenharmony_ci '\t}']) 3323e5c31af7Sopenharmony_ci if metaCondition != '': 3324e5c31af7Sopenharmony_ci stream.extend(['#endif // ' + metaCondition[4:], 3325e5c31af7Sopenharmony_ci '']) 3326e5c31af7Sopenharmony_ci else: 3327e5c31af7Sopenharmony_ci stream.append('') 3328e5c31af7Sopenharmony_ci 3329e5c31af7Sopenharmony_ci stream.append('\treturn result;') 3330e5c31af7Sopenharmony_ci stream.append('}\n') 3331e5c31af7Sopenharmony_ci 3332e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 3333e5c31af7Sopenharmony_ci 3334e5c31af7Sopenharmony_cidef writeExtensionList(api, filename, extensionType): 3335e5c31af7Sopenharmony_ci extensionList = [] 3336e5c31af7Sopenharmony_ci for extensionName, data in api.additionalExtensionData: 3337e5c31af7Sopenharmony_ci # make sure extension name starts with VK_KHR 3338e5c31af7Sopenharmony_ci if not extensionName.startswith('VK_KHR'): 3339e5c31af7Sopenharmony_ci continue 3340e5c31af7Sopenharmony_ci # make sure that this extension was registered 3341e5c31af7Sopenharmony_ci if 'register_extension' not in data.keys(): 3342e5c31af7Sopenharmony_ci continue 3343e5c31af7Sopenharmony_ci # make sure extension is intended for the vulkan variant 3344e5c31af7Sopenharmony_ci is_sc_only = False 3345e5c31af7Sopenharmony_ci 3346e5c31af7Sopenharmony_ci if api.apiName != 'vulkansc': 3347e5c31af7Sopenharmony_ci if 'mandatory_features' in data.keys(): 3348e5c31af7Sopenharmony_ci for structure, listStruct in data['mandatory_features'].items(): 3349e5c31af7Sopenharmony_ci for featureData in listStruct: 3350e5c31af7Sopenharmony_ci mandatory_variant = '' 3351e5c31af7Sopenharmony_ci try: 3352e5c31af7Sopenharmony_ci mandatory_variant = featureData['mandatory_variant'] 3353e5c31af7Sopenharmony_ci except KeyError: 3354e5c31af7Sopenharmony_ci mandatory_variant = '' 3355e5c31af7Sopenharmony_ci # VKSC only 3356e5c31af7Sopenharmony_ci if 'vulkansc' in mandatory_variant: 3357e5c31af7Sopenharmony_ci is_sc_only = True 3358e5c31af7Sopenharmony_ci if is_sc_only: 3359e5c31af7Sopenharmony_ci continue 3360e5c31af7Sopenharmony_ci 3361e5c31af7Sopenharmony_ci # make sure extension has proper type 3362e5c31af7Sopenharmony_ci if extensionType == data['register_extension']['type']: 3363e5c31af7Sopenharmony_ci extensionList.append(extensionName) 3364e5c31af7Sopenharmony_ci extensionList.sort() 3365e5c31af7Sopenharmony_ci # write list of all found extensions 3366e5c31af7Sopenharmony_ci stream = [] 3367e5c31af7Sopenharmony_ci stream.append('static const char* s_allowed{0}KhrExtensions[] =\n{{'.format(extensionType.title())) 3368e5c31af7Sopenharmony_ci for n in extensionList: 3369e5c31af7Sopenharmony_ci stream.append('\t"' + n + '",') 3370e5c31af7Sopenharmony_ci stream.append('};\n') 3371e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 3372e5c31af7Sopenharmony_ci 3373e5c31af7Sopenharmony_cidef writeApiExtensionDependencyInfo(api, filename): 3374e5c31af7Sopenharmony_ci 3375e5c31af7Sopenharmony_ci def genHelperFunctions(): 3376e5c31af7Sopenharmony_ci yield 'using namespace tcu;' 3377e5c31af7Sopenharmony_ci yield 'using ExtPropVect = std::vector<vk::VkExtensionProperties>;' 3378e5c31af7Sopenharmony_ci yield 'using IsSupportedFun = bool (*)(const tcu::UVec2&, const ExtPropVect&, const ExtPropVect&);' 3379e5c31af7Sopenharmony_ci yield 'using DependencyCheckVect = std::vector<std::pair<const char*, IsSupportedFun> >;\n' 3380e5c31af7Sopenharmony_ci yield 'bool isCompatibile(deUint32 major, deUint32 minor, const tcu::UVec2& testedApiVersion)' 3381e5c31af7Sopenharmony_ci yield '{' 3382e5c31af7Sopenharmony_ci yield '\t// return true when tested api version is greater' 3383e5c31af7Sopenharmony_ci yield '\t// or equal to version represented by two uints' 3384e5c31af7Sopenharmony_ci yield '\tif (major == testedApiVersion.x())' 3385e5c31af7Sopenharmony_ci yield '\t\treturn minor <= testedApiVersion.y();' 3386e5c31af7Sopenharmony_ci yield '\treturn major < testedApiVersion.x();' 3387e5c31af7Sopenharmony_ci yield '}\n' 3388e5c31af7Sopenharmony_ci yield 'bool isSupported(const ExtPropVect& extensions, const char* ext)' 3389e5c31af7Sopenharmony_ci yield '{' 3390e5c31af7Sopenharmony_ci yield '\treturn isExtensionStructSupported(extensions, vk::RequiredExtension(ext));' 3391e5c31af7Sopenharmony_ci yield '}\n' 3392e5c31af7Sopenharmony_ci 3393e5c31af7Sopenharmony_ci def genExtDepArray(extType): 3394e5c31af7Sopenharmony_ci extensionList = [] 3395e5c31af7Sopenharmony_ci maxExtLength = 0 3396e5c31af7Sopenharmony_ci extVector = 'vIEP' 3397e5c31af7Sopenharmony_ci othVector = 'vDEP' 3398e5c31af7Sopenharmony_ci if extType == 'device': 3399e5c31af7Sopenharmony_ci extVector, othVector = othVector, extVector # swap 3400e5c31af7Sopenharmony_ci # iterate over all extension that are of specified type and that have requirements 3401e5c31af7Sopenharmony_ci for ext in api.extensions: 3402e5c31af7Sopenharmony_ci if ext.type != extType: 3403e5c31af7Sopenharmony_ci continue 3404e5c31af7Sopenharmony_ci if ext.depends is None: 3405e5c31af7Sopenharmony_ci continue 3406e5c31af7Sopenharmony_ci # memorize extension name and dependencies for future vector generation 3407e5c31af7Sopenharmony_ci extensionList.append(ext.name) 3408e5c31af7Sopenharmony_ci # memorize max extension name and dependency length 3409e5c31af7Sopenharmony_ci maxExtLength = max(maxExtLength, len(ext.name)) 3410e5c31af7Sopenharmony_ci # generate check function for this extension 3411e5c31af7Sopenharmony_ci yield f'bool check_{ext.name}(const tcu::UVec2& v, const ExtPropVect& vIEP, const ExtPropVect& vDEP)' 3412e5c31af7Sopenharmony_ci yield '{' 3413e5c31af7Sopenharmony_ci # check if extension was promoted; for SC we need to check vulkan version as sc10 is based on vk12 3414e5c31af7Sopenharmony_ci if ext.promotedto is not None and 'VK_VERSION' in ext.promotedto: 3415e5c31af7Sopenharmony_ci p = ext.promotedto 3416e5c31af7Sopenharmony_ci yield f'\tif (isCompatibile({p[-3]}, {p[-1]}, v))' 3417e5c31af7Sopenharmony_ci yield '\t\treturn true;\n' 3418e5c31af7Sopenharmony_ci else: 3419e5c31af7Sopenharmony_ci yield '\tDE_UNREF(v);' 3420e5c31af7Sopenharmony_ci # there is a high chance that other vector won't be used 3421e5c31af7Sopenharmony_ci yield f'\tDE_UNREF({othVector});' 3422e5c31af7Sopenharmony_ci # check if extension is supported 3423e5c31af7Sopenharmony_ci yield f'\n\tif (!isSupported({extVector}, "{ext.name}"))' 3424e5c31af7Sopenharmony_ci yield '\t\treturn true;\n' 3425e5c31af7Sopenharmony_ci # replace dependent extensions/versions with proper conditions 3426e5c31af7Sopenharmony_ci depList = re.split(r'(\W+)', ext.depends) 3427e5c31af7Sopenharmony_ci for idx, depPart in enumerate(depList): 3428e5c31af7Sopenharmony_ci if ',' in depPart: 3429e5c31af7Sopenharmony_ci depList[idx] = depList[idx].replace(',', ' || ') 3430e5c31af7Sopenharmony_ci elif '+' in depPart: 3431e5c31af7Sopenharmony_ci depList[idx] = depList[idx].replace('+', ' && ') 3432e5c31af7Sopenharmony_ci elif 'VK_' in depPart: 3433e5c31af7Sopenharmony_ci if 'VK_VERSION' in depPart: 3434e5c31af7Sopenharmony_ci if idx > 0 and ' || ' in depList[idx-1]: 3435e5c31af7Sopenharmony_ci # some vk.xml entries include "promoted to" version preceded by logical OR operator in the extension "depends" attribute 3436e5c31af7Sopenharmony_ci # script don't rely on this optional information and will find "promoted to" versions for all dependencies of all extensions in the below code 3437e5c31af7Sopenharmony_ci # accordingly the one from vk.xml is ignored to avoid redundant isCompatibile() checks 3438e5c31af7Sopenharmony_ci depList[idx-1] = depList[idx-1].replace(' || ', '') 3439e5c31af7Sopenharmony_ci depList[idx] = '' 3440e5c31af7Sopenharmony_ci continue 3441e5c31af7Sopenharmony_ci # when dependency is vulkan version then replace it with proper condition 3442e5c31af7Sopenharmony_ci depList[idx] = f'isCompatibile({depPart[-3]}, {depPart[-1]}, v)' 3443e5c31af7Sopenharmony_ci else: 3444e5c31af7Sopenharmony_ci # when dependency is extension check if it was promoted 3445e5c31af7Sopenharmony_ci extNotFound = True 3446e5c31af7Sopenharmony_ci for dExt in api.extensions: 3447e5c31af7Sopenharmony_ci if depPart == dExt.name: 3448e5c31af7Sopenharmony_ci depExtVector = 'vDEP' if dExt.type == 'device' else 'vIEP' 3449e5c31af7Sopenharmony_ci isSupportedCheck = f'isSupported({depExtVector}, "{depPart}")' 3450e5c31af7Sopenharmony_ci if dExt.promotedto is not None: 3451e5c31af7Sopenharmony_ci p = dExt.promotedto 3452e5c31af7Sopenharmony_ci # check if dependency was promoted to vulkan version or other extension 3453e5c31af7Sopenharmony_ci if 'VK_VERSION' in p: 3454e5c31af7Sopenharmony_ci depList[idx] = f'(isCompatibile({p[-3]}, {p[-1]}, v) || {isSupportedCheck})' 3455e5c31af7Sopenharmony_ci else: 3456e5c31af7Sopenharmony_ci depList[idx] = f'(isSupported({depExtVector}, "{p}") || {isSupportedCheck})' 3457e5c31af7Sopenharmony_ci else: 3458e5c31af7Sopenharmony_ci depList[idx] = isSupportedCheck 3459e5c31af7Sopenharmony_ci extNotFound = False 3460e5c31af7Sopenharmony_ci break 3461e5c31af7Sopenharmony_ci # for SC when extension was not found try checking also not supported 3462e5c31af7Sopenharmony_ci # extensions and see if this extension is part of core 3463e5c31af7Sopenharmony_ci if extNotFound and api.apiName == "vulkansc": 3464e5c31af7Sopenharmony_ci for dExt in api.notSupportedExtensions: 3465e5c31af7Sopenharmony_ci if depPart == dExt.name: 3466e5c31af7Sopenharmony_ci p = dExt.promotedto 3467e5c31af7Sopenharmony_ci if p is None: 3468e5c31af7Sopenharmony_ci break 3469e5c31af7Sopenharmony_ci if int(p[-1]) > 2: 3470e5c31af7Sopenharmony_ci break 3471e5c31af7Sopenharmony_ci extNotFound = False 3472e5c31af7Sopenharmony_ci depList[idx] = "true" 3473e5c31af7Sopenharmony_ci if extNotFound: 3474e5c31af7Sopenharmony_ci assert False, f"{depPart} from dependencies not found" 3475e5c31af7Sopenharmony_ci yield f'\t// depends attribute in xml: {ext.depends}' 3476e5c31af7Sopenharmony_ci finalConditon = ''.join(depList) 3477e5c31af7Sopenharmony_ci yield f'\treturn {finalConditon};' 3478e5c31af7Sopenharmony_ci yield '}\n' 3479e5c31af7Sopenharmony_ci # save list of all device/instance extensions 3480e5c31af7Sopenharmony_ci yield 'static const DependencyCheckVect {}ExtensionDependencies'.format(extType) 3481e5c31af7Sopenharmony_ci yield '{' 3482e5c31af7Sopenharmony_ci for ext in extensionList: 3483e5c31af7Sopenharmony_ci extTabCount = (maxExtLength - len(ext)) / 4 3484e5c31af7Sopenharmony_ci eTabs = '\t'*int(round(extTabCount+1.49)) 3485e5c31af7Sopenharmony_ci yield f'\tstd::make_pair("{ext}",{eTabs}&check_{ext}),' 3486e5c31af7Sopenharmony_ci yield '};\n' 3487e5c31af7Sopenharmony_ci 3488e5c31af7Sopenharmony_ci def genApiVersions(): 3489e5c31af7Sopenharmony_ci yield 'static const std::tuple<deUint32, deUint32, deUint32, deUint32>\treleasedApiVersions[]\t=' 3490e5c31af7Sopenharmony_ci yield '{' 3491e5c31af7Sopenharmony_ci for f in reversed(api.features): 3492e5c31af7Sopenharmony_ci apiVariant = '0' if f.api == 'vulkan' else '1' 3493e5c31af7Sopenharmony_ci major, minor = f.number.split('.') 3494e5c31af7Sopenharmony_ci version = (int(apiVariant) << 29) | (int(major) << 22) | (int(minor) << 12) 3495e5c31af7Sopenharmony_ci yield '\tstd::make_tuple({}, {}, {}, {}),'.format(version, apiVariant, major, minor) 3496e5c31af7Sopenharmony_ci yield '};' 3497e5c31af7Sopenharmony_ci 3498e5c31af7Sopenharmony_ci def parseExtensionDependencies(extDeps, ext): 3499e5c31af7Sopenharmony_ci major, minor = 1, 0 3500e5c31af7Sopenharmony_ci requiredVerFound = False; 3501e5c31af7Sopenharmony_ci # return in case nothing more left to be processed 3502e5c31af7Sopenharmony_ci if extDeps is None or extDeps == "": 3503e5c31af7Sopenharmony_ci return major, minor, requiredVerFound 3504e5c31af7Sopenharmony_ci ungrpPartLen = 0 3505e5c31af7Sopenharmony_ci versionPattern = "[A-Z]+_VERSION_([0-9]+)_([0-9]+)" 3506e5c31af7Sopenharmony_ci ungroupedPattern = r"^.*?\(+|^.*?$" 3507e5c31af7Sopenharmony_ci # look for non-grouped part, it may include the required vulkan version 3508e5c31af7Sopenharmony_ci ungroupPart = re.search(ungroupedPattern, extDeps) 3509e5c31af7Sopenharmony_ci if ungroupPart is not None and ungroupPart[0].replace(r"(", "") != "": 3510e5c31af7Sopenharmony_ci ungrpPartLen = len(ungroupPart[0].replace(r"(", "")) 3511e5c31af7Sopenharmony_ci # is specific version explicitly requested? 3512e5c31af7Sopenharmony_ci match = re.search(versionPattern, ungroupPart[0]) 3513e5c31af7Sopenharmony_ci if match is not None: 3514e5c31af7Sopenharmony_ci if len(match[0]) != len(extDeps): 3515e5c31af7Sopenharmony_ci # there is more than just a version; check if it's accompanied by AND operator(s) 3516e5c31af7Sopenharmony_ci ext_pattern = ".*\+*"+versionPattern+"\++.*|.*\++"+versionPattern+"\+*.*" 3517e5c31af7Sopenharmony_ci match = re.search(ext_pattern, ungroupPart[0]) 3518e5c31af7Sopenharmony_ci if match is not None: 3519e5c31af7Sopenharmony_ci # specific version is explicitly requested 3520e5c31af7Sopenharmony_ci major, minor = int(match[1]), int(match[2]) 3521e5c31af7Sopenharmony_ci return major, minor, True 3522e5c31af7Sopenharmony_ci # no explicit version is requested, continue parsing the remaining part 3523e5c31af7Sopenharmony_ci extDeps = extDeps[ungrpPartLen:] 3524e5c31af7Sopenharmony_ci groupedPattern = r"(.*)\+|(.*)$" 3525e5c31af7Sopenharmony_ci match = re.search(groupedPattern, extDeps) 3526e5c31af7Sopenharmony_ci if match is not None and match[0] != "": 3527e5c31af7Sopenharmony_ci # groups may include the dependency "promoted to" versions accompanied by OR operator 3528e5c31af7Sopenharmony_ci # but they don't include the extension explicit required version; continue parsing the remaining part 3529e5c31af7Sopenharmony_ci groupLength = len(match[0]) 3530e5c31af7Sopenharmony_ci major, minor, requiredVerFound = parseExtensionDependencies(extDeps[groupLength:], ext) 3531e5c31af7Sopenharmony_ci return major, minor, requiredVerFound 3532e5c31af7Sopenharmony_ci 3533e5c31af7Sopenharmony_ci def genRequiredCoreVersions(): 3534e5c31af7Sopenharmony_ci yield 'static const std::tuple<deUint32, deUint32, const char*>\textensionRequiredCoreVersion[]\t =' 3535e5c31af7Sopenharmony_ci yield '{' 3536e5c31af7Sopenharmony_ci versionPattern = "[A-Z]+_VERSION_([0-9]+)_([0-9]+)" 3537e5c31af7Sopenharmony_ci for ext in api.extensions: 3538e5c31af7Sopenharmony_ci # skip video extensions 3539e5c31af7Sopenharmony_ci if 'vulkan_video_' in ext.name: 3540e5c31af7Sopenharmony_ci continue 3541e5c31af7Sopenharmony_ci major, minor = 1, 0 3542e5c31af7Sopenharmony_ci if ext.depends is not None: 3543e5c31af7Sopenharmony_ci major, minor, requiredVerFound = parseExtensionDependencies(ext.depends, ext) 3544e5c31af7Sopenharmony_ci if not requiredVerFound: 3545e5c31af7Sopenharmony_ci # find all extensions that are dependencies of this one 3546e5c31af7Sopenharmony_ci matches = re.findall("VK_\w+", ext.depends, re.M) 3547e5c31af7Sopenharmony_ci for m in matches: 3548e5c31af7Sopenharmony_ci for de in api.extensions: 3549e5c31af7Sopenharmony_ci if de.name == m: 3550e5c31af7Sopenharmony_ci if de.depends is not None: 3551e5c31af7Sopenharmony_ci # check if the dependency states explicitly the required vulkan version and pick the higher one 3552e5c31af7Sopenharmony_ci newMajor, newMinor, requiredVerFound = parseExtensionDependencies(de.depends, de) 3553e5c31af7Sopenharmony_ci if requiredVerFound: 3554e5c31af7Sopenharmony_ci if newMajor > major: 3555e5c31af7Sopenharmony_ci major, minor = newMajor, newMinor 3556e5c31af7Sopenharmony_ci elif newMajor == major and newMinor > minor: 3557e5c31af7Sopenharmony_ci minor = newMinor 3558e5c31af7Sopenharmony_ci break 3559e5c31af7Sopenharmony_ci yield '\tstd::make_tuple({}, {}, "{}"),'.format(major, minor, ext.name) 3560e5c31af7Sopenharmony_ci yield '};' 3561e5c31af7Sopenharmony_ci 3562e5c31af7Sopenharmony_ci stream = [] 3563e5c31af7Sopenharmony_ci stream.extend(genHelperFunctions()) 3564e5c31af7Sopenharmony_ci stream.extend(genExtDepArray('instance')) 3565e5c31af7Sopenharmony_ci stream.extend(genExtDepArray('device')) 3566e5c31af7Sopenharmony_ci stream.extend(genApiVersions()) 3567e5c31af7Sopenharmony_ci stream.extend(genRequiredCoreVersions()) 3568e5c31af7Sopenharmony_ci 3569e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 3570e5c31af7Sopenharmony_ci 3571e5c31af7Sopenharmony_cidef writeEntryPointValidation(api, filename): 3572e5c31af7Sopenharmony_ci # keys are instance extension names and value is list of device-level functions 3573e5c31af7Sopenharmony_ci instExtDeviceFunDict = {} 3574e5c31af7Sopenharmony_ci # iterate over all extensions and find instance extensions 3575e5c31af7Sopenharmony_ci for ext in api.extensions: 3576e5c31af7Sopenharmony_ci if ext.type == "instance": 3577e5c31af7Sopenharmony_ci # iterate over all functions instance extension adds 3578e5c31af7Sopenharmony_ci for requirement in ext.requirementsList: 3579e5c31af7Sopenharmony_ci for extCommand in requirement.newCommands: 3580e5c31af7Sopenharmony_ci # to get a type of command we need to find this command definition in list of all functions 3581e5c31af7Sopenharmony_ci for command in api.functions: 3582e5c31af7Sopenharmony_ci if extCommand.name == command.name or extCommand.name in command.aliasList: 3583e5c31af7Sopenharmony_ci # check if this is device-level entry-point 3584e5c31af7Sopenharmony_ci if command.getType() == Function.TYPE_DEVICE: 3585e5c31af7Sopenharmony_ci if ext.name not in instExtDeviceFunDict: 3586e5c31af7Sopenharmony_ci instExtDeviceFunDict[ext.name] = [] 3587e5c31af7Sopenharmony_ci instExtDeviceFunDict[ext.name].append(extCommand.name) 3588e5c31af7Sopenharmony_ci stream = ['std::map<std::string, std::vector<std::string> > instExtDeviceFun', '{'] 3589e5c31af7Sopenharmony_ci for extName in instExtDeviceFunDict: 3590e5c31af7Sopenharmony_ci stream.append(f'\t{{ "{extName}",\n\t\t{{') 3591e5c31af7Sopenharmony_ci for fun in instExtDeviceFunDict[extName]: 3592e5c31af7Sopenharmony_ci stream.append(f'\t\t\t"{fun}",') 3593e5c31af7Sopenharmony_ci stream.append('\t\t}\n\t},') 3594e5c31af7Sopenharmony_ci stream.append('};') 3595e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 3596e5c31af7Sopenharmony_ci 3597e5c31af7Sopenharmony_cidef writeGetDeviceProcAddr(api, filename): 3598e5c31af7Sopenharmony_ci testBlockStart = '''tcu::TestStatus testGetDeviceProcAddr (Context& context) 3599e5c31af7Sopenharmony_ci{ 3600e5c31af7Sopenharmony_ci tcu::TestLog& log (context.getTestContext().getLog()); 3601e5c31af7Sopenharmony_ci const PlatformInterface& platformInterface = context.getPlatformInterface(); 3602e5c31af7Sopenharmony_ci const auto validationEnabled = context.getTestContext().getCommandLine().isValidationEnabled(); 3603e5c31af7Sopenharmony_ci const CustomInstance instance (createCustomInstanceFromContext(context)); 3604e5c31af7Sopenharmony_ci const InstanceDriver& instanceDriver = instance.getDriver(); 3605e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine()); 3606e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = 0; 3607e5c31af7Sopenharmony_ci const deUint32 queueCount = 1; 3608e5c31af7Sopenharmony_ci const float queuePriority = 1.0f; 3609e5c31af7Sopenharmony_ci const std::vector<VkQueueFamilyProperties> queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice); 3610e5c31af7Sopenharmony_ci 3611e5c31af7Sopenharmony_ci const VkDeviceQueueCreateInfo deviceQueueCreateInfo = 3612e5c31af7Sopenharmony_ci { 3613e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType; 3614e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3615e5c31af7Sopenharmony_ci (VkDeviceQueueCreateFlags)0u, // VkDeviceQueueCreateFlags flags; 3616e5c31af7Sopenharmony_ci queueFamilyIndex, // deUint32 queueFamilyIndex; 3617e5c31af7Sopenharmony_ci queueCount, // deUint32 queueCount; 3618e5c31af7Sopenharmony_ci &queuePriority, // const float* pQueuePriorities; 3619e5c31af7Sopenharmony_ci }; 3620e5c31af7Sopenharmony_ci 3621e5c31af7Sopenharmony_ci const VkDeviceCreateInfo deviceCreateInfo = 3622e5c31af7Sopenharmony_ci { 3623e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType; 3624e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3625e5c31af7Sopenharmony_ci (VkDeviceCreateFlags)0u, // VkDeviceCreateFlags flags; 3626e5c31af7Sopenharmony_ci 1u, // deUint32 queueCreateInfoCount; 3627e5c31af7Sopenharmony_ci &deviceQueueCreateInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos; 3628e5c31af7Sopenharmony_ci 0u, // deUint32 enabledLayerCount; 3629e5c31af7Sopenharmony_ci DE_NULL, // const char* const* ppEnabledLayerNames; 3630e5c31af7Sopenharmony_ci 0u, // deUint32 enabledExtensionCount; 3631e5c31af7Sopenharmony_ci DE_NULL, // const char* const* ppEnabledExtensionNames; 3632e5c31af7Sopenharmony_ci DE_NULL, // const VkPhysicalDeviceFeatures* pEnabledFeatures; 3633e5c31af7Sopenharmony_ci }; 3634e5c31af7Sopenharmony_ci const Unique<VkDevice> device (createCustomDevice(validationEnabled, platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo)); 3635e5c31af7Sopenharmony_ci const DeviceDriver deviceDriver (platformInterface, instance, device.get(), context.getUsedApiVersion()); 3636e5c31af7Sopenharmony_ci 3637e5c31af7Sopenharmony_ci const std::vector<std::string> loaderExceptions{ 3638e5c31af7Sopenharmony_ci "vkSetDebugUtilsObjectNameEXT", 3639e5c31af7Sopenharmony_ci "vkSetDebugUtilsObjectTagEXT", 3640e5c31af7Sopenharmony_ci "vkQueueBeginDebugUtilsLabelEXT", 3641e5c31af7Sopenharmony_ci "vkQueueEndDebugUtilsLabelEXT", 3642e5c31af7Sopenharmony_ci "vkQueueInsertDebugUtilsLabelEXT", 3643e5c31af7Sopenharmony_ci "vkCmdBeginDebugUtilsLabelEXT", 3644e5c31af7Sopenharmony_ci "vkCmdEndDebugUtilsLabelEXT", 3645e5c31af7Sopenharmony_ci "vkCmdInsertDebugUtilsLabelEXT", 3646e5c31af7Sopenharmony_ci }; 3647e5c31af7Sopenharmony_ci 3648e5c31af7Sopenharmony_ci const std::vector<std::string> functions{''' 3649e5c31af7Sopenharmony_ci testBlockEnd = ''' }; 3650e5c31af7Sopenharmony_ci 3651e5c31af7Sopenharmony_ci bool fail = false; 3652e5c31af7Sopenharmony_ci for (const auto& function : functions) 3653e5c31af7Sopenharmony_ci { 3654e5c31af7Sopenharmony_ci if (std::find(loaderExceptions.begin(), loaderExceptions.end(), function) != loaderExceptions.end()) 3655e5c31af7Sopenharmony_ci { 3656e5c31af7Sopenharmony_ci continue; 3657e5c31af7Sopenharmony_ci } 3658e5c31af7Sopenharmony_ci if (deviceDriver.getDeviceProcAddr(device.get(), function.c_str()) != DE_NULL) 3659e5c31af7Sopenharmony_ci { 3660e5c31af7Sopenharmony_ci fail = true; 3661e5c31af7Sopenharmony_ci log << tcu::TestLog::Message << "Function " << function << " is not NULL" << tcu::TestLog::EndMessage; 3662e5c31af7Sopenharmony_ci } 3663e5c31af7Sopenharmony_ci } 3664e5c31af7Sopenharmony_ci if (fail) 3665e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Fail"); 3666e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("All functions are NULL"); 3667e5c31af7Sopenharmony_ci} 3668e5c31af7Sopenharmony_ci''' 3669e5c31af7Sopenharmony_ci 3670e5c31af7Sopenharmony_ci def functions(functionType): 3671e5c31af7Sopenharmony_ci for ext in api.extensions: 3672e5c31af7Sopenharmony_ci for requirement in ext.requirementsList: 3673e5c31af7Sopenharmony_ci for requiredCommand in requirement.newCommands: 3674e5c31af7Sopenharmony_ci yield '\t\t"' + requiredCommand.name + '",' 3675e5c31af7Sopenharmony_ci stream = [] 3676e5c31af7Sopenharmony_ci stream.append('#include "tcuCommandLine.hpp"') 3677e5c31af7Sopenharmony_ci stream.append('#include "vktTestCase.hpp"') 3678e5c31af7Sopenharmony_ci stream.append('#include "vkPlatform.hpp"') 3679e5c31af7Sopenharmony_ci stream.append('#include "vkDeviceUtil.hpp"') 3680e5c31af7Sopenharmony_ci stream.append('#include "vkQueryUtil.hpp"') 3681e5c31af7Sopenharmony_ci stream.append('#include "vktCustomInstancesDevices.hpp"') 3682e5c31af7Sopenharmony_ci stream.append('#include "vktTestCase.hpp"') 3683e5c31af7Sopenharmony_ci stream.append('#include "vktTestCaseUtil.hpp"') 3684e5c31af7Sopenharmony_ci stream.append('\nnamespace vkt\n{\n') 3685e5c31af7Sopenharmony_ci stream.append('using namespace vk;\n') 3686e5c31af7Sopenharmony_ci stream.append(testBlockStart) 3687e5c31af7Sopenharmony_ci stream.extend(functions(api)) 3688e5c31af7Sopenharmony_ci stream.append(testBlockEnd) 3689e5c31af7Sopenharmony_ci 3690e5c31af7Sopenharmony_ci # function to create tests 3691e5c31af7Sopenharmony_ci stream.append("void addGetDeviceProcAddrTests (tcu::TestCaseGroup* testGroup)\n{") 3692e5c31af7Sopenharmony_ci stream.append('\taddFunctionCase(testGroup, "non_enabled", testGetDeviceProcAddr);') 3693e5c31af7Sopenharmony_ci stream.append('}\n') 3694e5c31af7Sopenharmony_ci stream.append('}\n') 3695e5c31af7Sopenharmony_ci 3696e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 3697e5c31af7Sopenharmony_ci 3698e5c31af7Sopenharmony_cidef writeConformanceVersions(filename): 3699e5c31af7Sopenharmony_ci # get list of all vulkan/vulkansc tags from git 3700e5c31af7Sopenharmony_ci listOfTags = os.popen("git ls-remote -t").read() 3701e5c31af7Sopenharmony_ci vkMatches = re.findall("vulkan-cts-(\d).(\d).(\d).(\d)", listOfTags, re.M) 3702e5c31af7Sopenharmony_ci scMatches = re.findall("vulkansc-cts-(\d).(\d).(\d).(\d)", listOfTags, re.M) 3703e5c31af7Sopenharmony_ci if len(vkMatches) == 0 or len(scMatches) == 0: 3704e5c31af7Sopenharmony_ci return 3705e5c31af7Sopenharmony_ci # read all text files in doc folder and find withdrawn cts versions (branches) 3706e5c31af7Sopenharmony_ci withdrawnVkBranches = set() 3707e5c31af7Sopenharmony_ci withdrawnScBranches = set() 3708e5c31af7Sopenharmony_ci today = datetime.date.today() 3709e5c31af7Sopenharmony_ci for fileName in glob.glob(os.path.join(os.path.dirname(__file__), "..", "doc", "*.txt")): 3710e5c31af7Sopenharmony_ci if "withdrawal" not in fileName: 3711e5c31af7Sopenharmony_ci continue 3712e5c31af7Sopenharmony_ci fileContent = readFile(fileName) 3713e5c31af7Sopenharmony_ci # get date when releases are withdrawn 3714e5c31af7Sopenharmony_ci match = re.search(r"(20\d\d)-(\d\d)-(\d\d).+ withdrawn", fileContent, re.IGNORECASE) 3715e5c31af7Sopenharmony_ci if match is not None: 3716e5c31af7Sopenharmony_ci # check if announcement refers to date in the past 3717e5c31af7Sopenharmony_ci if today > datetime.date(int(match[1]), int(match[2]), int(match[3])): 3718e5c31af7Sopenharmony_ci # get names of withdrawn branches 3719e5c31af7Sopenharmony_ci vkBranchMatches = re.findall("vulkan(\w\w)?-cts-(\d).(\d).(\d).(\d)", fileContent, re.M) 3720e5c31af7Sopenharmony_ci for v in vkBranchMatches: 3721e5c31af7Sopenharmony_ci selectedSet = withdrawnScBranches if v[0] == "sc" else withdrawnVkBranches 3722e5c31af7Sopenharmony_ci selectedSet.add((v[1], v[2], v[3], v[4])) 3723e5c31af7Sopenharmony_ci if len(withdrawnVkBranches) == 0: 3724e5c31af7Sopenharmony_ci print(f"Warning: unable to read content of doc folder, skipping generation of {os.path.basename(filename)}") 3725e5c31af7Sopenharmony_ci return 3726e5c31af7Sopenharmony_ci # define helper function that will be used to add entries for both vk and sc 3727e5c31af7Sopenharmony_ci def appendToStream(stream, versionsToAdd, maxWithdrawnVersion): 3728e5c31af7Sopenharmony_ci addedVersions = set() 3729e5c31af7Sopenharmony_ci for v in reversed(versionsToAdd): 3730e5c31af7Sopenharmony_ci # add only unique versions; ignore duplicates (e.g. with "-rc1", "-rc2" postfix); 3731e5c31af7Sopenharmony_ci # also add versions that are greater then maximal withdrawn version 3732e5c31af7Sopenharmony_ci if v in addedVersions or v <= maxWithdrawnVersion: 3733e5c31af7Sopenharmony_ci continue 3734e5c31af7Sopenharmony_ci addedVersions.add(v) 3735e5c31af7Sopenharmony_ci stream.append(f'\tmakeConformanceVersion({v[0]}, {v[1]}, {v[2]}, {v[3]}),') 3736e5c31af7Sopenharmony_ci # save array with versions 3737e5c31af7Sopenharmony_ci stream = ['static const VkConformanceVersion knownConformanceVersions[]',\ 3738e5c31af7Sopenharmony_ci '{',\ 3739e5c31af7Sopenharmony_ci '#ifndef CTS_USES_VULKANSC'] 3740e5c31af7Sopenharmony_ci appendToStream(stream, vkMatches, max(withdrawnVkBranches)) 3741e5c31af7Sopenharmony_ci stream.append('#else') 3742e5c31af7Sopenharmony_ci appendToStream(stream, scMatches, tuple('0'*4) if len(withdrawnScBranches) == 0 else max(withdrawnScBranches)) 3743e5c31af7Sopenharmony_ci stream.append('#endif // CTS_USES_VULKANSC') 3744e5c31af7Sopenharmony_ci stream.append('};') 3745e5c31af7Sopenharmony_ci writeInlFile(filename, INL_HEADER, stream) 3746e5c31af7Sopenharmony_ci 3747e5c31af7Sopenharmony_cidef parseCmdLineArgs(): 3748e5c31af7Sopenharmony_ci parser = argparse.ArgumentParser(description = "Generate Vulkan INL files", 3749e5c31af7Sopenharmony_ci formatter_class=argparse.ArgumentDefaultsHelpFormatter) 3750e5c31af7Sopenharmony_ci parser.add_argument("-a", 3751e5c31af7Sopenharmony_ci "--api", 3752e5c31af7Sopenharmony_ci dest="api", 3753e5c31af7Sopenharmony_ci default="", 3754e5c31af7Sopenharmony_ci help="Choose between Vulkan and Vulkan SC") 3755e5c31af7Sopenharmony_ci parser.add_argument("-o", 3756e5c31af7Sopenharmony_ci "--outdir", 3757e5c31af7Sopenharmony_ci dest="outdir", 3758e5c31af7Sopenharmony_ci default="", 3759e5c31af7Sopenharmony_ci help="Choose output directory") 3760e5c31af7Sopenharmony_ci return parser.parse_args() 3761e5c31af7Sopenharmony_ci 3762e5c31af7Sopenharmony_ciif __name__ == "__main__": 3763e5c31af7Sopenharmony_ci args = parseCmdLineArgs() 3764e5c31af7Sopenharmony_ci 3765e5c31af7Sopenharmony_ci # if argument was specified it is interpreted as a path to which .inl files will be written 3766e5c31af7Sopenharmony_ci outputPath = DEFAULT_OUTPUT_DIR[args.api] if args.outdir == '' else args.outdir 3767e5c31af7Sopenharmony_ci 3768e5c31af7Sopenharmony_ci vkTree = etree.parse(os.path.join(VULKAN_XML_DIR, "vk.xml")) 3769e5c31af7Sopenharmony_ci apiName = "vulkansc" if args.api == 'SC' else "vulkan" 3770e5c31af7Sopenharmony_ci stripNonmatchingAPIs(vkTree.getroot(), apiName, actuallyDelete = True) 3771e5c31af7Sopenharmony_ci 3772e5c31af7Sopenharmony_ci # Read vk.xml and generate vulkan headers from it 3773e5c31af7Sopenharmony_ci api = API(apiName) 3774e5c31af7Sopenharmony_ci api.build(vkTree) 3775e5c31af7Sopenharmony_ci api.postProcess() 3776e5c31af7Sopenharmony_ci 3777e5c31af7Sopenharmony_ci # Read video.xml 3778e5c31af7Sopenharmony_ci if args.api != 'SC': 3779e5c31af7Sopenharmony_ci api.build( etree.parse(os.path.join(VULKAN_XML_DIR, "video.xml")) ) 3780e5c31af7Sopenharmony_ci 3781e5c31af7Sopenharmony_ci platformFuncs = [Function.TYPE_PLATFORM] 3782e5c31af7Sopenharmony_ci instanceFuncs = [Function.TYPE_INSTANCE] 3783e5c31af7Sopenharmony_ci deviceFuncs = [Function.TYPE_DEVICE] 3784e5c31af7Sopenharmony_ci 3785e5c31af7Sopenharmony_ci dfd = generateDeviceFeaturesOrPropertiesDefs(api, 'Features') 3786e5c31af7Sopenharmony_ci writeDeviceFeatures (api, dfd, os.path.join(outputPath, "vkDeviceFeatures.inl")) 3787e5c31af7Sopenharmony_ci writeDeviceFeaturesDefaultDeviceDefs (dfd, os.path.join(outputPath, "vkDeviceFeaturesForDefaultDeviceDefs.inl")) 3788e5c31af7Sopenharmony_ci writeDeviceFeaturesContextDecl (dfd, os.path.join(outputPath, "vkDeviceFeaturesForContextDecl.inl")) 3789e5c31af7Sopenharmony_ci writeDeviceFeaturesContextDefs (dfd, os.path.join(outputPath, "vkDeviceFeaturesForContextDefs.inl")) 3790e5c31af7Sopenharmony_ci writeDeviceFeatureTest (api, os.path.join(outputPath, "vkDeviceFeatureTest.inl")) 3791e5c31af7Sopenharmony_ci 3792e5c31af7Sopenharmony_ci dpd = generateDeviceFeaturesOrPropertiesDefs(api, 'Properties') 3793e5c31af7Sopenharmony_ci writeDeviceProperties (api, dpd, os.path.join(outputPath, "vkDeviceProperties.inl")) 3794e5c31af7Sopenharmony_ci writeDevicePropertiesDefaultDeviceDefs (dpd, os.path.join(outputPath, "vkDevicePropertiesForDefaultDeviceDefs.inl")) 3795e5c31af7Sopenharmony_ci writeDevicePropertiesContextDecl (dpd, os.path.join(outputPath, "vkDevicePropertiesForContextDecl.inl")) 3796e5c31af7Sopenharmony_ci writeDevicePropertiesContextDefs (dpd, os.path.join(outputPath, "vkDevicePropertiesForContextDefs.inl")) 3797e5c31af7Sopenharmony_ci 3798e5c31af7Sopenharmony_ci writeHandleType (api, os.path.join(outputPath, "vkHandleType.inl")) 3799e5c31af7Sopenharmony_ci writeBasicTypes (api, os.path.join(outputPath, "vkBasicTypes.inl")) 3800e5c31af7Sopenharmony_ci writeCompositeTypes (api, os.path.join(outputPath, "vkStructTypes.inl")) 3801e5c31af7Sopenharmony_ci writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualPlatformInterface.inl"), platformFuncs, False) 3802e5c31af7Sopenharmony_ci writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualInstanceInterface.inl"), instanceFuncs, False) 3803e5c31af7Sopenharmony_ci writeInterfaceDecl (api, os.path.join(outputPath, "vkVirtualDeviceInterface.inl"), deviceFuncs, False) 3804e5c31af7Sopenharmony_ci writeInterfaceDecl (api, os.path.join(outputPath, "vkConcretePlatformInterface.inl"), platformFuncs, True) 3805e5c31af7Sopenharmony_ci writeInterfaceDecl (api, os.path.join(outputPath, "vkConcreteInstanceInterface.inl"), instanceFuncs, True) 3806e5c31af7Sopenharmony_ci writeInterfaceDecl (api, os.path.join(outputPath, "vkConcreteDeviceInterface.inl"), deviceFuncs, True) 3807e5c31af7Sopenharmony_ci writeFunctionPtrTypes (api, os.path.join(outputPath, "vkFunctionPointerTypes.inl")) 3808e5c31af7Sopenharmony_ci writeFunctionPointers (api, os.path.join(outputPath, "vkPlatformFunctionPointers.inl"), platformFuncs) 3809e5c31af7Sopenharmony_ci writeFunctionPointers (api, os.path.join(outputPath, "vkInstanceFunctionPointers.inl"), instanceFuncs) 3810e5c31af7Sopenharmony_ci writeFunctionPointers (api, os.path.join(outputPath, "vkDeviceFunctionPointers.inl"), deviceFuncs) 3811e5c31af7Sopenharmony_ci writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitPlatformFunctionPointers.inl"), platformFuncs, lambda f: f.name != "vkGetInstanceProcAddr") 3812e5c31af7Sopenharmony_ci writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitInstanceFunctionPointers.inl"), instanceFuncs) 3813e5c31af7Sopenharmony_ci writeInitFunctionPointers (api, os.path.join(outputPath, "vkInitDeviceFunctionPointers.inl"), deviceFuncs) 3814e5c31af7Sopenharmony_ci writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkPlatformDriverImpl.inl"), platformFuncs, "PlatformDriver") 3815e5c31af7Sopenharmony_ci writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkInstanceDriverImpl.inl"), instanceFuncs, "InstanceDriver") 3816e5c31af7Sopenharmony_ci writeFuncPtrInterfaceImpl (api, os.path.join(outputPath, "vkDeviceDriverImpl.inl"), deviceFuncs, "DeviceDriver") 3817e5c31af7Sopenharmony_ci if args.api=='SC': 3818e5c31af7Sopenharmony_ci writeFuncPtrInterfaceSCImpl (api, os.path.join(outputPath, "vkDeviceDriverSCImpl.inl"), deviceFuncs, "DeviceDriverSC") 3819e5c31af7Sopenharmony_ci writeStrUtilProto (api, os.path.join(outputPath, "vkStrUtil.inl")) 3820e5c31af7Sopenharmony_ci writeStrUtilImpl (api, os.path.join(outputPath, "vkStrUtilImpl.inl")) 3821e5c31af7Sopenharmony_ci writeRefUtilProto (api, os.path.join(outputPath, "vkRefUtil.inl")) 3822e5c31af7Sopenharmony_ci writeRefUtilImpl (api, os.path.join(outputPath, "vkRefUtilImpl.inl")) 3823e5c31af7Sopenharmony_ci writeStructTraitsImpl (api, os.path.join(outputPath, "vkGetStructureTypeImpl.inl")) 3824e5c31af7Sopenharmony_ci writeNullDriverImpl (api, os.path.join(outputPath, "vkNullDriverImpl.inl")) 3825e5c31af7Sopenharmony_ci writeTypeUtil (api, os.path.join(outputPath, "vkTypeUtil.inl")) 3826e5c31af7Sopenharmony_ci writeSupportedExtensions (api, os.path.join(outputPath, "vkSupportedExtensions.inl")) 3827e5c31af7Sopenharmony_ci writeCoreFunctionalities (api, os.path.join(outputPath, "vkCoreFunctionalities.inl")) 3828e5c31af7Sopenharmony_ci writeExtensionFunctions (api, os.path.join(outputPath, "vkExtensionFunctions.inl")) 3829e5c31af7Sopenharmony_ci writeDeviceFeatures2 (api, os.path.join(outputPath, "vkDeviceFeatures2.inl")) 3830e5c31af7Sopenharmony_ci writeMandatoryFeatures (api, os.path.join(outputPath, "vkMandatoryFeatures.inl")) 3831e5c31af7Sopenharmony_ci writeExtensionList (api, os.path.join(outputPath, "vkInstanceExtensions.inl"), 'instance') 3832e5c31af7Sopenharmony_ci writeExtensionList (api, os.path.join(outputPath, "vkDeviceExtensions.inl"), 'device') 3833e5c31af7Sopenharmony_ci writeDriverIds (api, os.path.join(outputPath, "vkKnownDriverIds.inl")) 3834e5c31af7Sopenharmony_ci writeObjTypeImpl (api, os.path.join(outputPath, "vkObjTypeImpl.inl")) 3835e5c31af7Sopenharmony_ci writeApiExtensionDependencyInfo (api, os.path.join(outputPath, "vkApiExtensionDependencyInfo.inl")) 3836e5c31af7Sopenharmony_ci writeEntryPointValidation (api, os.path.join(outputPath, "vkEntryPointValidation.inl")) 3837e5c31af7Sopenharmony_ci writeGetDeviceProcAddr (api, os.path.join(outputPath, "vkGetDeviceProcAddr.inl")) 3838e5c31af7Sopenharmony_ci writeConformanceVersions ( os.path.join(outputPath, "vkKnownConformanceVersions.inl")) 3839e5c31af7Sopenharmony_ci 3840e5c31af7Sopenharmony_ci # NOTE: when new files are generated then they should also be added to the 3841e5c31af7Sopenharmony_ci # vk-gl-cts\external\vulkancts\framework\vulkan\CMakeLists.txt outputs list 3842