111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#!/usr/bin/env python3 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# VK 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Copyright (c) 2015-2016 The Khronos Group Inc. 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Copyright (c) 2015-2016 Valve Corporation 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Copyright (c) 2015-2016 LunarG, Inc. 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Copyright (c) 2015-2016 Google Inc. 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Licensed under the Apache License, Version 2.0 (the "License"); 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# you may not use this file except in compliance with the License. 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# You may obtain a copy of the License at 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# http://www.apache.org/licenses/LICENSE-2.0 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Unless required by applicable law or agreed to in writing, software 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# distributed under the License is distributed on an "AS IS" BASIS, 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# See the License for the specific language governing permissions and 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# limitations under the License. 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Author: Tobin Ehlis <tobine@google.com> 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Author: Courtney Goeltzenleuchter <courtneygo@google.com> 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Author: Jon Ashburn <jon@lunarg.com> 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Author: Mark Lobodzinski <mark@lunarg.com> 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Author: Mike Stroyan <stroyan@google.com> 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Author: Tony Barbour <tony@LunarG.com> 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Author: Chia-I Wu <olv@google.com> 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Author: Gwan-gyeong Mun <kk.moon@samsung.com> 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertimport sys 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertimport os 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertimport re 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertimport vulkan 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertimport vk_helper 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertfrom source_line_info import sourcelineinfo 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertfrom collections import defaultdict 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef proto_is_global(proto): 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert global_function_names = [ 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateInstance", 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "EnumerateInstanceLayerProperties", 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "EnumerateInstanceExtensionProperties", 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "EnumerateDeviceLayerProperties", 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "EnumerateDeviceExtensionProperties", 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateXcbSurfaceKHR", 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetPhysicalDeviceXcbPresentationSupportKHR", 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateXlibSurfaceKHR", 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetPhysicalDeviceXlibPresentationSupportKHR", 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateWaylandSurfaceKHR", 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetPhysicalDeviceWaylandPresentationSupportKHR", 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateMirSurfaceKHR", 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetPhysicalDeviceMirPresentationSupportKHR", 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateAndroidSurfaceKHR", 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateWin32SurfaceKHR", 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetPhysicalDeviceWin32PresentationSupportKHR" 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ] 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice" or proto.name in global_function_names: 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return True 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return False 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef wsi_name(ext_name): 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = "" 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'Xcb' in ext_name: 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = 'XCB' 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'Xlib' in ext_name: 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = 'XLIB' 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'Win32' in ext_name: 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = 'WIN32' 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'Mir' in ext_name: 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = 'MIR' 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'Wayland' in ext_name: 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = 'WAYLAND' 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'Android' in ext_name: 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = 'ANDROID' 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = '' 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return wsi_prefix 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef wsi_ifdef(ext_name): 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = wsi_name(ext_name) 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if not wsi_prefix: 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return '' 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "#ifdef VK_USE_PLATFORM_%s_KHR" % wsi_prefix 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef wsi_endif(ext_name): 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi_prefix = wsi_name(ext_name) 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if not wsi_prefix: 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return '' 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "#endif // VK_USE_PLATFORM_%s_KHR" % wsi_prefix 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef generate_get_proc_addr_check(name): 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return " if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \ 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return NULL;" % ((name,) * 3) 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef ucc_to_U_C_C(CamelCase): 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', CamelCase) 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).upper() 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Parse complete struct chain and add any new ndo_uses to the dict 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef gather_object_uses_in_struct(obj_list, struct_type): 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_uses = {} 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_helper.typedef_rev_dict[struct_type] in vk_helper.struct_dict: 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_type = vk_helper.typedef_rev_dict[struct_type] 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Parse elements of this struct param to identify objects and/or arrays of objects 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for m in sorted(vk_helper.struct_dict[struct_type]): 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array_len = "%s" % (str(vk_helper.struct_dict[struct_type][m]['array_size'])) 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert base_type = vk_helper.struct_dict[struct_type][m]['type'] 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert mem_name = vk_helper.struct_dict[struct_type][m]['name'] 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array_len != '0': 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert mem_name = "%s[%s]" % (mem_name, array_len) 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if base_type in obj_list: 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert #if array_len not in ndo_uses: 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # struct_uses[array_len] = [] 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert #struct_uses[array_len].append("%s%s,%s" % (name_prefix, struct_name, base_type)) 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_uses[mem_name] = base_type 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif vk_helper.is_type(base_type, 'struct'): 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert sub_uses = gather_object_uses_in_struct(obj_list, base_type) 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if len(sub_uses) > 0: 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_uses[mem_name] = sub_uses 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return struct_uses 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# For the given list of object types, Parse the given list of params 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# and return dict of params that use one of the obj_list types 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# Format of the dict is that terminal elements have <name>,<type> 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# non-terminal elements will have <name>[<array_size>] 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# TODO : This analysis could be done up-front at vk_helper time 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef get_object_uses(obj_list, params): 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_uses = {} 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_decls = {} 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param_count = 'NONE' # track params that give array sizes 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for p in params: 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert base_type = p.ty.replace('const ', '').strip('*') 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array_len = '' 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert is_ptr = False 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'count' in p.name.lower(): 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param_count = p.name 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptr_txt = '' 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '*' in p.ty: 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert is_ptr = True 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptr_txt = '*' 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if base_type in obj_list: 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if is_ptr and 'const' in p.ty and param_count != 'NONE': 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array_len = "[%s]" % param_count 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Non-arrays we can overwrite in place, but need local decl for arrays 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_decls[p.name] = '%s%s' % (base_type, ptr_txt) 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert #if array_len not in obj_uses: 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # obj_uses[array_len] = {} 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # obj_uses[array_len][p.name] = base_type 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_uses["%s%s" % (p.name, array_len)] = base_type 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif vk_helper.is_type(base_type, 'struct'): 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_name = p.name 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'NONE' != param_count: 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_name = "%s[%s]" % (struct_name, param_count) 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_uses = gather_object_uses_in_struct(obj_list, base_type) 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if len(struct_uses) > 0: 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_uses[struct_name] = struct_uses 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # This is a top-level struct w/ uses below it, so need local decl 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_decls['%s' % (p.name)] = '%s%s' % (base_type, ptr_txt) 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return (obj_uses, local_decls) 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass Subcommand(object): 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def __init__(self, outfile): 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.outfile = outfile 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.headers = vulkan.headers 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.protos = vulkan.protos 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.no_addr = False 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.layer_name = "" 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.lineinfo = sourcelineinfo() 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.wsi = sys.argv[1] 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def run(self): 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.outfile: 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert with open(self.outfile, "w") as outfile: 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert outfile.write(self.generate()) 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert print(self.generate()) 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate(self): 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert copyright = self.generate_copyright() 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header = self.generate_header() 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body = self.generate_body() 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert footer = self.generate_footer() 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert contents = [] 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if copyright: 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert contents.append(copyright) 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if header: 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert contents.append(header) 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if body: 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert contents.append(body) 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if footer: 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert contents.append(footer) 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n\n".join(contents) 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_copyright(self): 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return """/* THIS FILE IS GENERATED. DO NOT EDIT. */ 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 The Khronos Group Inc. 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 Valve Corporation 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 LunarG, Inc. 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 Google, Inc. 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Licensed under the Apache License, Version 2.0 (the "License"); 21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * you may not use this file except in compliance with the License. 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * You may obtain a copy of the License at 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * http://www.apache.org/licenses/LICENSE-2.0 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Unless required by applicable law or agreed to in writing, software 21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * distributed under the License is distributed on an "AS IS" BASIS, 21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * See the License for the specific language governing permissions and 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * limitations under the License. 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Tobin Ehlis <tobine@google.com> 22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Courtney Goeltzenleuchter <courtneygo@google.com> 22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Jon Ashburn <jon@lunarg.com> 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Mark Lobodzinski <mark@lunarg.com> 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Mike Stroyan <stroyan@google.com> 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Tony Barbour <tony@LunarG.com> 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */""" 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_header(self): 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(["#include <" + h + ">" for h in self.headers]) 23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_body(self): 23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pass 23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_footer(self): 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pass 23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Return set of printf '%' qualifier and input to that qualifier 24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _get_printf_params(self, vk_type, name, output_param, cpp=False): 24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # TODO : Need ENUM and STRUCT checks here 24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_helper.is_type(vk_type, 'enum'):#"_TYPE" in vk_type: # TODO : This should be generic ENUM check 24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%s", "string_%s(%s)" % (vk_type.replace('const ', '').strip('*'), name)) 24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if "char*" == vk_type: 24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%s", name) 24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if "uint64" in vk_type: 24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '*' in vk_type: 24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%lu", "*%s" % name) 24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%lu", name) 25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_type.strip('*') in vulkan.object_non_dispatch_list: 25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '*' in vk_type: 25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%lu", "%s" % name) 25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%lu", "%s" % name) 25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if "size" in vk_type: 25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '*' in vk_type: 25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%lu", "(unsigned long)*%s" % name) 25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%lu", "(unsigned long)%s" % name) 25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if "float" in vk_type: 25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '[' in vk_type: # handle array, current hard-coded to 4 (TODO: Make this dynamic) 26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if cpp: 26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("[%i, %i, %i, %i]", '"[" << %s[0] << "," << %s[1] << "," << %s[2] << "," << %s[3] << "]"' % (name, name, name, name)) 26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("[%f, %f, %f, %f]", "%s[0], %s[1], %s[2], %s[3]" % (name, name, name, name)) 26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%f", name) 26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if "bool" in vk_type.lower() or 'xcb_randr_crtc_t' in vk_type: 26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%u", name) 26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if True in [t in vk_type.lower() for t in ["int", "flags", "mask", "xcb_window_t"]]: 26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '[' in vk_type: # handle array, current hard-coded to 4 (TODO: Make this dynamic) 26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if cpp: 26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("[%i, %i, %i, %i]", "%s[0] << %s[1] << %s[2] << %s[3]" % (name, name, name, name)) 27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("[%i, %i, %i, %i]", "%s[0], %s[1], %s[2], %s[3]" % (name, name, name, name)) 27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '*' in vk_type: 27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'pUserData' == name: 27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%i", "((pUserData == 0) ? 0 : *(pUserData))") 27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'const' in vk_type.lower(): 27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("0x%p", "(void*)(%s)" % name) 27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%i", "*(%s)" % name) 27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("%i", name) 27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # TODO : This is special-cased as there's only one "format" param currently and it's nice to expand it 27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if "VkFormat" == vk_type: 28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if cpp: 28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("0x%p", "&%s" % name) 28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("{%s.channelFormat = %%s, %s.numericFormat = %%s}" % (name, name), "string_VK_COLOR_COMPONENT_FORMAT(%s.channelFormat), string_VK_FORMAT_RANGE_SIZE(%s.numericFormat)" % (name, name)) 28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if output_param: 28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("0x%p", "(void*)*%s" % name) 28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_helper.is_type(vk_type, 'struct') and '*' not in vk_type: 28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("0x%p", "(void*)(&%s)" % name) 28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return ("0x%p", "(void*)(%s)" % name) 28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _gen_create_msg_callback(self): 29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body = [] 29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('%s' % self.lineinfo.get()) 29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(') 29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkInstance instance,') 29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,') 29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' const VkAllocationCallbacks* pAllocator,') 29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkDebugReportCallbackEXT* pCallback)') 29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('{') 29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Switch to this code section for the new per-instance storage and debug callbacks 29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.layer_name in ['object_tracker', 'unique_objects']: 30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name ) 30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkResult result = pInstanceTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);') 30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' if (VK_SUCCESS == result) {') 30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);') 30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' result = layer_create_msg_callback(my_data->report_data,') 30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' pCreateInfo,') 30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' pAllocator,') 30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' pCallback);') 30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' }') 30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' return result;') 31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkResult result = instance_dispatch_table(instance)->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);') 31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' if (VK_SUCCESS == result) {') 31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);') 31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pCallback);') 31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' }') 31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' return result;') 31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('}') 31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(r_body) 31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _gen_destroy_msg_callback(self): 32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body = [] 32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('%s' % self.lineinfo.get()) 32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, const VkAllocationCallbacks *pAllocator)') 32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('{') 32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Switch to this code section for the new per-instance storage and debug callbacks 32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.layer_name in ['object_tracker', 'unique_objects']: 32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name ) 32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);') 33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' pInstanceTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);') 33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);') 33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);') 33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('}') 33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(r_body) 33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _gen_debug_report_msg(self): 33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body = [] 33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('%s' % self.lineinfo.get()) 33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg)') 34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('{') 34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Switch to this code section for the new per-instance storage and debug callbacks 34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.layer_name == 'object_tracker': 34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name ) 34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);') 34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append(' pInstanceTable->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);') 34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert r_body.append('}') 34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(r_body) 34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _gen_layer_logging_workaround(self): 35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body = [] 35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('%s' % self.lineinfo.get()) 35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('// vk_layer_logging.h expects these to be defined') 35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('VKAPI_ATTR VkResult VKAPI_CALL') 35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,') 35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {') 35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return %s::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);' % self.layer_name) 35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('}') 36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,') 36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' VkDebugReportCallbackEXT msgCallback,') 36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' const VkAllocationCallbacks *pAllocator) {') 36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' %s::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);' % self.layer_name) 36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('}') 36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('VKAPI_ATTR void VKAPI_CALL') 36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,') 36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {') 37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' %s::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);' % self.layer_name) 37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('}') 37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(body) 37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _gen_layer_interface_v0_functions(self): 37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body = [] 37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('%s' % self.lineinfo.get()) 37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('// loader-layer interface v0') 37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.layer_name == 'object_tracker': 38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('static const VkExtensionProperties instance_extensions[] = {') 38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' {') 38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' VK_EXT_DEBUG_REPORT_EXTENSION_NAME,') 38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' VK_EXT_DEBUG_REPORT_SPEC_VERSION') 38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' }') 38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('};') 38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('static const VkLayerProperties globalLayerProps = {') 39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' "VK_LAYER_LUNARG_%s",' % self.layer_name) 39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' VK_LAYER_API_VERSION, // specVersion') 39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' 1, // implementationVersion') 39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' "LunarG Validation Layer"') 39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('};') 39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('static const VkLayerProperties globalLayerProps = {') 39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' "VK_LAYER_GOOGLE_%s",' % self.layer_name) 40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' VK_LAYER_API_VERSION, // specVersion') 40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' 1, // implementationVersion') 40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' "Google Validation Layer"') 40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('};') 40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties* pProperties)') 40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('{') 40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.layer_name == 'object_tracker': 40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);') 41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return util_GetExtensionProperties(0, NULL, pCount, pProperties);') 41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('}') 41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties* pProperties)') 41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('{') 41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);') 41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('}') 41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties* pProperties)') 42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('{') 42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);') 42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('}') 42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName)') 42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('{') 42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return %s::GetDeviceProcAddr(dev, funcName);' % self.layer_name) 42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('}') 42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName)') 43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('{') 43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))') 43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties);') 43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))') 43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties);') 43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))') 43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties);') 43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' if (!strcmp(funcName, "vkGetInstanceProcAddr"))') 43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr);') 43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('') 44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(' return %s::GetInstanceProcAddr(instance, funcName);' % self.layer_name) 44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('}') 44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(body) 44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _generate_dispatch_entrypoints(self, qual=""): 44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if qual: 44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert qual += " " 44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs = [] 45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert intercepted = [] 45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for proto in self.protos: 45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.name in ["EnumerateInstanceExtensionProperties", 45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "EnumerateInstanceLayerProperties", 45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "EnumerateDeviceLayerProperties"]: 45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # the layer do not need to define these 45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert continue 45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif proto.name in ["GetDeviceProcAddr", 45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetInstanceProcAddr"]: 45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append(proto.c_func(attr="VKAPI") + ';') 46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert intercepted.append(proto) 46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert intercept = self.generate_intercept(proto, qual) 46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if intercept is None: 46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # fill in default intercept for certain entrypoints 46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'CreateDebugReportCallbackEXT' == proto.name: 46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert intercept = self._gen_layer_dbg_create_msg_callback() 46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'DestroyDebugReportCallbackEXT' == proto.name: 46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert intercept = self._gen_layer_dbg_destroy_msg_callback() 46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'DebugReportMessageEXT' == proto.name: 47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert intercept = self._gen_debug_report_msg() 47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'CreateDevice' == proto.name: 47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('/* CreateDevice HERE */') 47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if intercept is not None: 47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append(intercept) 47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if not "KHR" in proto.name: 47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert intercepted.append(proto) 47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_lookups = [] 48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert device_lookups = [] 48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for proto in intercepted: 48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto_is_global(proto): 48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_lookups.append("if (!strcmp(name, \"%s\"))" % proto.name) 48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_lookups.append(" return (PFN_vkVoidFunction) %s;" % (proto.name)) 48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert device_lookups.append("if (!strcmp(name, \"%s\"))" % proto.name) 48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert device_lookups.append(" return (PFN_vkVoidFunction) %s;" % (proto.name)) 48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # add customized intercept_core_device_command 49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body = [] 49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append('%s' % self.lineinfo.get()) 49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("static inline PFN_vkVoidFunction intercept_core_device_command(const char *name)") 49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("{") 49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(generate_get_proc_addr_check("name")) 49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("") 49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" name += 2;") 49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" %s" % "\n ".join(device_lookups)) 49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("") 49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" return NULL;") 50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("}") 50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # add intercept_core_instance_command 50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("static inline PFN_vkVoidFunction intercept_core_instance_command(const char *name)") 50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("{") 50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(generate_get_proc_addr_check("name")) 50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("") 50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" // we should never be queried for these commands") 50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" assert(strcmp(name, \"vkEnumerateInstanceLayerProperties\") &&") 50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" strcmp(name, \"vkEnumerateInstanceExtensionProperties\") &&") 50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" strcmp(name, \"vkEnumerateDeviceLayerProperties\"));") 51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("") 51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" name += 2;") 51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" %s" % "\n ".join(instance_lookups)) 51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("") 51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append(" return NULL;") 51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body.append("}") 51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append("\n".join(body)) 51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n\n".join(funcs) 51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _generate_extensions(self): 52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert exts = [] 52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert exts.append('%s' % self.lineinfo.get()) 52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert exts.append(self._gen_create_msg_callback()) 52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert exts.append(self._gen_destroy_msg_callback()) 52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert exts.append(self._gen_debug_report_msg()) 52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(exts) 52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _generate_layer_gpa_function(self, extensions=[], instance_extensions=[]): 52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body = [] 53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# 53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# New style of GPA Functions for the new layer_data/layer_logging changes 53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# 53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.layer_name in ['object_tracker', 'unique_objects']: 53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_enable, ext_list in extensions: 53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % self.lineinfo.get()) 53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('static inline PFN_vkVoidFunction intercept_%s_command(const char *name, VkDevice dev)' % ext_enable) 53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('{') 53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (dev) {') 53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);') 54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (!my_data->%s)' % ext_enable) 54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' return nullptr;') 54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' }\n') 54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_name in ext_list: 54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (!strcmp("%s", name))\n' 54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (ext_name, ext_name[2:])) 54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('\n return nullptr;') 54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('}\n') 54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append("VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName)\n" 55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "{\n" 55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " PFN_vkVoidFunction addr;\n" 55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " addr = intercept_core_device_command(funcName);\n" 55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " if (addr)\n" 55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return addr;\n" 55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " assert(device);\n") 55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_enable, _ in extensions: 55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' addr = intercept_%s_command(funcName, device);' % ext_enable) 55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (addr)\n' 56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' return addr;') 56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append("\n if (get_dispatch_table(%s_device_table_map, device)->GetDeviceProcAddr == NULL)\n" 56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return NULL;\n" 56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return get_dispatch_table(%s_device_table_map, device)->GetDeviceProcAddr(device, funcName);\n" 56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "}\n" % (self.layer_name, self.layer_name)) 56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_enable, ext_list in instance_extensions: 56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % self.lineinfo.get()) 56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('static inline PFN_vkVoidFunction intercept_%s_command(const char *name, VkInstance instance)' % ext_enable) 56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('{') 57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ext_enable == 'msg_callback_get_proc_addr': 57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);\n" 57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return debug_report_get_instance_proc_addr(my_data->report_data, name);") 57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" VkLayerInstanceDispatchTable* pTable = get_dispatch_table(%s_instance_table_map, instance);" % self.layer_name) 57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (instanceExtMap.size() == 0 || !instanceExtMap[pTable].%s)' % ext_enable) 57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' return nullptr;\n') 57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_name in ext_list: 57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if wsi_name(ext_name): 58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % wsi_ifdef(ext_name)) 58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (!strcmp("%s", name))\n' 58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (ext_name, ext_name[2:])) 58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if wsi_name(ext_name): 58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % wsi_endif(ext_name)) 58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('\n return nullptr;') 58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('}\n') 58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append("VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName)\n" 59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "{\n" 59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " PFN_vkVoidFunction addr;\n" 59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " addr = intercept_core_instance_command(funcName);\n" 59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " if (!addr) {\n" 59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " addr = intercept_core_device_command(funcName);\n" 59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " }") 59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_enable, _ in extensions: 59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" if (!addr) {\n" 59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " addr = intercept_%s_command(funcName, VkDevice(VK_NULL_HANDLE));\n" 60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " }" % ext_enable) 60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" if (addr) {\n" 60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return addr;\n" 60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " }\n" 60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " assert(instance);\n" 60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ) 60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_enable, _ in instance_extensions: 60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' addr = intercept_%s_command(funcName, instance);' % ext_enable) 61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (addr)\n' 61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' return addr;\n') 61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" if (get_dispatch_table(%s_instance_table_map, instance)->GetInstanceProcAddr == NULL) {\n" 61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return NULL;\n" 61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " }\n" 61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return get_dispatch_table(%s_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);\n" 61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "}\n" % (self.layer_name, self.layer_name)) 61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(func_body) 61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % self.lineinfo.get()) 62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append("VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName)\n" 62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "{\n" 62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " PFN_vkVoidFunction addr;\n") 62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append("\n" 62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " loader_platform_thread_once(&initOnce, init%s);\n\n" 62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " addr = intercept_core_device_command(funcName);\n" 62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " if (addr)\n" 62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return addr;" % self.layer_name) 62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" assert(device);\n") 63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('') 63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' VkLayerDispatchTable *pDisp = device_dispatch_table(device);') 63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 0 != len(extensions): 63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert extra_space = "" 63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (ext_enable, ext_list) in extensions: 63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 0 != len(ext_enable): 63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (deviceExtMap.size() != 0 && deviceExtMap[pDisp].%s)' % ext_enable) 63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' {') 63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert extra_space = " " 63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_name in ext_list: 64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' %sif (!strcmp("%s", funcName))\n' 64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (extra_space, ext_name, ext_name)) 64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 0 != len(ext_enable): 64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' }') 64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % self.lineinfo.get()) 64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" {\n" 64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " if (pDisp->GetDeviceProcAddr == NULL)\n" 64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return NULL;\n" 64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return pDisp->GetDeviceProcAddr(device, funcName);\n" 64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " }\n" 65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "}\n") 65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % self.lineinfo.get()) 65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append("VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName)\n" 65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "{\n" 65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " PFN_vkVoidFunction addr;\n" 65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ) 65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append( 65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " loader_platform_thread_once(&initOnce, init%s);\n\n" 65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " addr = intercept_core_instance_command(funcName);\n" 65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " if (addr)\n" 66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return addr;" % self.layer_name) 66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" assert(instance);\n") 66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append("") 66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);\n") 66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 0 != len(instance_extensions): 66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert extra_space = "" 66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (ext_enable, ext_list) in instance_extensions: 66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 0 != len(ext_enable): 66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ext_enable == 'msg_callback_get_proc_addr': 66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);\n" 67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);\n" 67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " if (addr) {\n" 67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return addr;\n" 67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " }\n") 67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' if (instanceExtMap.size() != 0 && instanceExtMap[pTable].%s)' % ext_enable) 67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' {') 67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert extra_space = " " 67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ext_name in ext_list: 67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if wsi_name(ext_name): 68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % wsi_ifdef(ext_name)) 68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' %sif (!strcmp("%s", funcName))\n' 68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (extra_space, ext_name, ext_name)) 68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if wsi_name(ext_name): 68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % wsi_endif(ext_name)) 68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 0 != len(ext_enable): 68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' }\n') 68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" if (pTable->GetInstanceProcAddr == NULL)\n" 68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return NULL;\n" 69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " return pTable->GetInstanceProcAddr(instance, funcName);\n" 69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "}\n") 69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(func_body) 69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _generate_layer_initialization(self, init_opts=False, prefix='vk', lockname=None, condname=None): 69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body = ["#include \"vk_dispatch_table_helper.h\""] 69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % self.lineinfo.get()) 69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('static void init_%s(layer_data *my_data, const VkAllocationCallbacks *pAllocator)\n' 69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '{\n' % self.layer_name) 70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if init_opts: 70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % self.lineinfo.get()) 70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('') 70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(' layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_%s");' % self.layer_name) 70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('') 70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if lockname is not None: 70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('%s' % self.lineinfo.get()) 70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" if (!%sLockInitialized)" % lockname) 70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" {") 70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" // TODO/TBD: Need to delete this mutex sometime. How???") 71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" loader_platform_thread_create_mutex(&%sLock);" % lockname) 71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if condname is not None: 71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" loader_platform_thread_init_cond(&%sCond);" % condname) 71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" %sLockInitialized = 1;" % lockname) 71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append(" }") 71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append("}\n") 71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert func_body.append('') 71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(func_body) 71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass ObjectTrackerSubcommand(Subcommand): 72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_header(self): 72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt = [] 72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('%s' % self.lineinfo.get()) 72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "vk_loader_platform.h"') 72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "vulkan/vulkan.h"') 72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('') 72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include <stdio.h>') 72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include <stdlib.h>') 72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include <string.h>') 72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include <cinttypes>') 73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('') 73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include <unordered_map>') 73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('') 73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "vulkan/vk_layer.h"') 73411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "vk_layer_config.h"') 73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "vk_layer_table.h"') 73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "vk_layer_data.h"') 73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "vk_layer_logging.h"') 73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('') 73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# NOTE: The non-autoGenerated code is in the object_tracker.h header file 74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "object_tracker.h"') 74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('') 74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(header_txt) 74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_maps(self): 74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert maps_txt = [] 74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for o in vulkan.object_type_list: 74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert maps_txt.append('std::unordered_map<uint64_t, OBJTRACK_NODE*> %sMap;' % (o)) 74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(maps_txt) 74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _gather_object_uses(self, obj_list, struct_type, obj_set): 75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # for each member of struct_type 75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # add objs in obj_list to obj_set 75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # call self for structs 75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for m in sorted(vk_helper.struct_dict[struct_type]): 75511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_helper.struct_dict[struct_type][m]['type'] in obj_list: 75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_set.add(vk_helper.struct_dict[struct_type][m]['type']) 75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif vk_helper.is_type(vk_helper.struct_dict[struct_type][m]['type'], 'struct'): 75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_set = obj_set.union(self._gather_object_uses(obj_list, vk_helper.struct_dict[struct_type][m]['type'], obj_set)) 75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return obj_set 76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_procs(self): 76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt = [] 76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # First parse through funcs and gather dict of all objects seen by each call 76411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_use_dict = {} 76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert proto_list = vulkan.core.protos + vulkan.ext_khr_surface.protos + vulkan.ext_khr_surface.protos + vulkan.ext_khr_win32_surface.protos + vulkan.ext_khr_device_swapchain.protos 76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for proto in proto_list: 76711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert disp_obj = proto.params[0].ty.strip('*').replace('const ', '') 76811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if disp_obj in vulkan.object_dispatch_list: 76911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if disp_obj not in obj_use_dict: 77011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_use_dict[disp_obj] = set() 77111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for p in proto.params[1:]: 77211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert base_type = p.ty.strip('*').replace('const ', '') 77311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if base_type in vulkan.object_type_list: 77411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_use_dict[disp_obj].add(base_type) 77511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_helper.is_type(base_type, 'struct'): 77611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_use_dict[disp_obj] = self._gather_object_uses(vulkan.object_type_list, base_type, obj_use_dict[disp_obj]) 77711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert #for do in obj_use_dict: 77811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # print "Disp obj %s has uses for objs: %s" % (do, ', '.join(obj_use_dict[do])) 77911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 78011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for o in vulkan.object_type_list:# vulkan.core.objects: 78111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('%s' % self.lineinfo.get()) 78211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', o) 78311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:] 78411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if o in vulkan.object_dispatch_list: 78511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('static void create_%s(%s dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o, o)) 78611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 78711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('static void create_%s(VkDevice dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o)) 78811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('{') 78911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType,(uint64_t)(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",') 79011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeEXT(objType),') 79111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' (uint64_t)(vkObj));') 79211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('') 79311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;') 79411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' pNewObjNode->belongsTo = (uint64_t)dispatchable_object;') 79511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' pNewObjNode->objType = objType;') 79611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' pNewObjNode->status = OBJSTATUS_NONE;') 79711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' pNewObjNode->vkObj = (uint64_t)(vkObj);') 79811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' %sMap[(uint64_t)vkObj] = pNewObjNode;' % (o)) 79911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' uint32_t objIndex = objTypeToIndex(objType);') 80011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' numObjs[objIndex]++;') 80111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' numTotalObjs++;') 80211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('}') 80311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('') 80411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('%s' % self.lineinfo.get()) 80511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if o in vulkan.object_dispatch_list: 80611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('static void destroy_%s(%s dispatchable_object, %s object)' % (name, o, o)) 80711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 80811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('static void destroy_%s(VkDevice dispatchable_object, %s object)' % (name, o)) 80911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('{') 81011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' uint64_t object_handle = (uint64_t)(object);') 81111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' auto it = %sMap.find(object_handle);' % o) 81211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' if (it != %sMap.end()) {' % o) 81311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' OBJTRACK_NODE* pNode = it->second;') 81411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' uint32_t objIndex = objTypeToIndex(pNode->objType);') 81511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' assert(numTotalObjs > 0);') 81611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' numTotalObjs--;') 81711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' assert(numObjs[objIndex] > 0);') 81811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' numObjs[objIndex]--;') 81911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_NONE, "OBJTRACK",') 82011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",') 82111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' string_VkDebugReportObjectTypeEXT(pNode->objType), (uint64_t)(object), numTotalObjs, numObjs[objIndex],') 82211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' string_VkDebugReportObjectTypeEXT(pNode->objType));') 82311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' delete pNode;') 82411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' %sMap.erase(it);' % (o)) 82511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' } else {') 82611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0,') 82711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' object_handle, __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",') 82811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",') 82911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' object_handle);') 83011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' }') 83111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('}') 83211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('') 83311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Generate the permutations of validate_* functions where for each 83411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # dispatchable object type, we have a corresponding validate_* function 83511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # for that object and all non-dispatchable objects that are used in API 83611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # calls with that dispatchable object. 83711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('//%s' % str(sorted(obj_use_dict))) 83811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for do in sorted(obj_use_dict): 83911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', do) 84011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:] 84111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # First create validate_* func for disp obj 84211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('%s' % self.lineinfo.get()) 84311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('static bool validate_%s(%s dispatchable_object, %s object, VkDebugReportObjectTypeEXT objType, bool null_allowed)' % (name, do, do)) 84411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('{') 84511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' if (null_allowed && (object == VK_NULL_HANDLE))') 84611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' return false;') 84711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' if (%sMap.find((uint64_t)object) == %sMap.end()) {' % (do, do)) 84811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, objType, (uint64_t)(object), __LINE__, OBJTRACK_INVALID_OBJECT, "OBJTRACK",') 84911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' "Invalid %s Object 0x%%" PRIx64 ,(uint64_t)(object));' % do) 85011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' }') 85111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' return false;') 85211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('}') 85311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('') 85411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for o in sorted(obj_use_dict[do]): 85511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if o == do: # We already generated this case above so skip here 85611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert continue 85711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', o) 85811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:] 85911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('%s' % self.lineinfo.get()) 86011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('static bool validate_%s(%s dispatchable_object, %s object, VkDebugReportObjectTypeEXT objType, bool null_allowed)' % (name, do, o)) 86111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('{') 86211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' if (null_allowed && (object == VK_NULL_HANDLE))') 86311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' return false;') 86411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if o == "VkImage": 86511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' // We need to validate normal image objects and those from the swapchain') 86611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' if ((%sMap.find((uint64_t)object) == %sMap.end()) &&' % (o, o)) 86711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' (swapchainImageMap.find((uint64_t)object) == swapchainImageMap.end())) {') 86811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 86911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' if (%sMap.find((uint64_t)object) == %sMap.end()) {' % (o, o)) 87011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, objType, (uint64_t)(object), __LINE__, OBJTRACK_INVALID_OBJECT, "OBJTRACK",') 87111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' "Invalid %s Object 0x%%" PRIx64, (uint64_t)(object));' % o) 87211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' }') 87311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append(' return false;') 87411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('}') 87511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('') 87611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert procs_txt.append('') 87711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(procs_txt) 87811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 87911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_destroy_instance(self): 88011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt = [] 88111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('%s' % self.lineinfo.get()) 88211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('VKAPI_ATTR void VKAPI_CALL DestroyInstance(') 88311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('VkInstance instance,') 88411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('const VkAllocationCallbacks* pAllocator)') 88511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('{') 88611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' std::unique_lock<std::mutex> lock(global_lock);') 88711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 88811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' dispatch_key key = get_dispatch_key(instance);') 88911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' layer_data *my_data = get_my_data_ptr(key, layer_data_map);') 89011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 89111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' // Enable the temporary callback(s) here to catch cleanup issues:') 89211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' bool callback_setup = false;') 89311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' if (my_data->num_tmp_callbacks > 0) {') 89411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' if (!layer_enable_tmp_callbacks(my_data->report_data,') 89511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' my_data->num_tmp_callbacks,') 89611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' my_data->tmp_dbg_create_infos,') 89711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' my_data->tmp_callbacks)) {') 89811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' callback_setup = true;') 89911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 90011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 90111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 90211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' validate_instance(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);') 90311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 90411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' destroy_instance(instance, instance);') 90511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' // Report any remaining objects in LL') 90611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 90711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' for (auto iit = VkDeviceMap.begin(); iit != VkDeviceMap.end();) {') 90811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' OBJTRACK_NODE* pNode = iit->second;') 90911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' if (pNode->belongsTo == (uint64_t)instance) {') 91011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' log_msg(mid(instance), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",') 91111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),') 91211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' pNode->vkObj);') 91311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for o in vulkan.core.objects: 91411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue', 'VkDevice']: 91511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert continue 91611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' for (auto idt = %sMap.begin(); idt != %sMap.end();) {' % (o, o)) 91711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' OBJTRACK_NODE* pNode = idt->second;') 91811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' if (pNode->belongsTo == iit->first) {') 91911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' log_msg(mid(instance), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",') 92011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),') 92111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' pNode->vkObj);') 92211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' %sMap.erase(idt++);' % o ) 92311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' } else {') 92411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' ++idt;') 92511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 92611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 92711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' VkDeviceMap.erase(iit++);') 92811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' } else {') 92911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' ++iit;') 93011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 93111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 93211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 93311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, instance);') 93411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' pInstanceTable->DestroyInstance(instance, pAllocator);') 93511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 93611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' // Disable and cleanup the temporary callback(s):') 93711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' if (callback_setup) {') 93811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' layer_disable_tmp_callbacks(my_data->report_data,') 93911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' my_data->num_tmp_callbacks,') 94011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' my_data->tmp_callbacks);') 94111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 94211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' if (my_data->num_tmp_callbacks > 0) {') 94311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos,') 94411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' my_data->tmp_callbacks);') 94511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' my_data->num_tmp_callbacks = 0;') 94611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 94711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 94811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' // Clean up logging callback, if any') 94911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' while (my_data->logging_callback.size() > 0) {') 95011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' VkDebugReportCallbackEXT callback = my_data->logging_callback.back();') 95111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);') 95211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' my_data->logging_callback.pop_back();') 95311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' }') 95411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 95511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' layer_debug_report_destroy_instance(mid(instance));') 95611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' layer_data_map.erase(key);') 95711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 95811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' instanceExtMap.erase(pInstanceTable);') 95911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' lock.unlock();') 96011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # The loader holds a mutex that protects this from other threads 96111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append(' object_tracker_instance_table_map.erase(key);') 96211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('}') 96311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedi_txt.append('') 96411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(gedi_txt) 96511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 96611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_destroy_device(self): 96711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt = [] 96811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('%s' % self.lineinfo.get()) 96911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('VKAPI_ATTR void VKAPI_CALL DestroyDevice(') 97011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('VkDevice device,') 97111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('const VkAllocationCallbacks* pAllocator)') 97211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('{') 97311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' std::unique_lock<std::mutex> lock(global_lock);') 97411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);') 97511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('') 97611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' destroy_device(device, device);') 97711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' // Report any remaining objects associated with this VkDevice object in LL') 97811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for o in vulkan.core.objects: 97911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # DescriptorSets and Command Buffers are destroyed through their pools, not explicitly 98011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue', 'VkDevice', 'VkDescriptorSet', 'VkCommandBuffer']: 98111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert continue 98211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' for (auto it = %sMap.begin(); it != %sMap.end();) {' % (o, o)) 98311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' OBJTRACK_NODE* pNode = it->second;') 98411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' if (pNode->belongsTo == (uint64_t)device) {') 98511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",') 98611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),') 98711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' pNode->vkObj);') 98811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' %sMap.erase(it++);' % o ) 98911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' } else {') 99011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' ++it;') 99111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' }') 99211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' }') 99311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('') 99411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(" // Clean up Queue's MemRef Linked Lists") 99511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' destroyQueueMemRefLists();') 99611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('') 99711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' lock.unlock();') 99811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('') 99911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' dispatch_key key = get_dispatch_key(device);') 100011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' VkLayerDispatchTable *pDisp = get_dispatch_table(object_tracker_device_table_map, device);') 100111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' pDisp->DestroyDevice(device, pAllocator);') 100211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append(' object_tracker_device_table_map.erase(key);') 100311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('') 100411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('}') 100511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert gedd_txt.append('') 100611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(gedd_txt) 100711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 100811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Special-case validating some objects -- they may be non-NULL but should 100911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # only be validated upon meeting some condition specified below. 101011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _dereference_conditionally(self, indent, prefix, type_name, name): 101111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code = '' 101211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if type_name == 'pBufferInfo': 101311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%sif ((%sdescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||\n' % (indent, prefix) 101411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%s (%sdescriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||\n' % (indent, prefix) 101511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%s (%sdescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||\n' % (indent, prefix) 101611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%s (%sdescriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) ) {\n' % (indent, prefix) 101711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif type_name == 'pImageInfo': 101811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%sif ((%sdescriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||\n' % (indent, prefix) 101911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%s (%sdescriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||\n' % (indent, prefix) 102011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%s (%sdescriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ||\n' % (indent, prefix) 102111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%s (%sdescriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||\n' % (indent, prefix) 102211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%s (%sdescriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ) {\n' % (indent, prefix) 102311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif type_name == 'pTexelBufferView': 102411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%sif ((%sdescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||\n' % (indent, prefix) 102511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%s (%sdescriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) ) {\n' % (indent, prefix) 102611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif name == 'pBeginInfo->pInheritanceInfo': 102711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%sOBJTRACK_NODE* pNode = VkCommandBufferMap[(uint64_t)commandBuffer];\n' % (indent) 102811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%sif ((%s) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY)) {\n' % (indent, name) 102911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 103011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert s_code += '%sif (%s) {\n' % (indent, name) 103111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return s_code 103211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 103311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _gen_obj_validate_code(self, struct_uses, obj_type_mapping, func_name, valid_null_dict, param0_name, indent, prefix, array_index): 103411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code = '' 103511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for obj in sorted(struct_uses): 103611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = obj 103711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array = '' 103811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert type_name = '' 103911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '[' in obj: 104011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (name, array) = obj.split('[') 104111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert type_name = name 104211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array = array.strip(']') 104311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if isinstance(struct_uses[obj], dict): 104411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_prefix = '' 104511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = '%s%s' % (prefix, name) 104611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptr_type = False 104711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'p' == obj[0]: 104811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptr_type = True 104911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert tmp_pre = self._dereference_conditionally(indent, prefix, type_name, name) 105011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += tmp_pre 105111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 105211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '': 105311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert idx = 'idx%s' % str(array_index) 105411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array_index += 1 105511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s\n' % self.lineinfo.get() 105611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx) 105711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 105811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_prefix = '%s[%s].' % (name, idx) 105911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif ptr_type: 106011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_prefix = '%s->' % (name) 106111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 106211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_prefix = '%s.' % (name) 106311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert tmp_pre = self._gen_obj_validate_code(struct_uses[obj], obj_type_mapping, func_name, valid_null_dict, param0_name, indent, local_prefix, array_index) 106411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += tmp_pre 106511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '': 106611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 106711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s}\n' % (indent) 106811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ptr_type: 106911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 107011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s}\n' % (indent) 107111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 107211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptype = struct_uses[obj] 107311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dbg_obj_type = obj_type_mapping[ptype] 107411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fname = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', ptype) 107511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fname = re.sub('([a-z0-9])([A-Z])', r'\1_\2', fname).lower()[3:] 107611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert full_name = '%s%s' % (prefix, name) 107711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert null_obj_ok = 'false' 107811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # If a valid null param is defined for this func and we have a match, allow NULL 107911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if func_name in valid_null_dict and True in [name in pn for pn in sorted(valid_null_dict[func_name])]: 108011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert null_obj_ok = 'true' 108111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (array_index > 0) or '' != array: 108211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert tmp_pre = self._dereference_conditionally(indent, prefix, type_name, full_name) 108311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += tmp_pre 108411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 108511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '': 108611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert idx = 'idx%s' % str(array_index) 108711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array_index += 1 108811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx) 108911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 109011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert full_name = '%s[%s]' % (full_name, idx) 109111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s\n' % self.lineinfo.get() 109211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sskipCall |= validate_%s(%s, %s, %s, %s);\n' %(indent, fname, param0_name, full_name, dbg_obj_type, null_obj_ok) 109311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '': 109411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 109511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s}\n' % (indent) 109611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 109711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s}\n' % (indent) 109811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 109911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s\n' % self.lineinfo.get() 110011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sskipCall |= validate_%s(%s, %s, %s, %s);\n' %(indent, fname, param0_name, full_name, dbg_obj_type, null_obj_ok) 110111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pre_code 110211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 110311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_intercept(self, proto, qual): 110411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.name in [ 'CreateDebugReportCallbackEXT', 'EnumerateInstanceLayerProperties', 'EnumerateInstanceExtensionProperties','EnumerateDeviceLayerProperties', 'EnumerateDeviceExtensionProperties' ]: 110511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # use default version 110611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return None 110711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 110811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Create map of object names to object type enums of the form VkName : VkObjectTypeName 110911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_type_mapping = {base_t : base_t.replace("Vk", "VkDebugReportObjectType") for base_t in vulkan.object_type_list} 111011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Convert object type enum names from UpperCamelCase to UPPER_CASE_WITH_UNDERSCORES 111111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for objectName, objectTypeEnum in obj_type_mapping.items(): 111211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_type_mapping[objectName] = ucc_to_U_C_C(objectTypeEnum) + '_EXT'; 111311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Command Buffer Object doesn't follow the rule. 111411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_type_mapping['VkCommandBuffer'] = "VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT" 111511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_type_mapping['VkShaderModule'] = "VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT" 111611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 111711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit_object_tracker_functions = [ 111811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateInstance", 111911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "EnumeratePhysicalDevices", 112011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetPhysicalDeviceQueueFamilyProperties", 112111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateDevice", 112211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetDeviceQueue", 112311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "QueueBindSparse", 112411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "AllocateDescriptorSets", 112511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "FreeDescriptorSets", 112611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateGraphicsPipelines", 112711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "CreateComputePipelines", 112811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "AllocateCommandBuffers", 112911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "FreeCommandBuffers", 113011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "DestroyDescriptorPool", 113111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "DestroyCommandPool", 113211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "MapMemory", 113311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "UnmapMemory", 113411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "FreeMemory", 113511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "DestroySwapchainKHR", 113611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "GetSwapchainImagesKHR" 113711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ] 113811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decl = proto.c_func(attr="VKAPI") 113911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param0_name = proto.params[0].name 114011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line = '' 114111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_line = '' 114211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line = '' 114311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Dict below tracks params that are vk objects. Dict is "loop count"->["params w/ that loop count"] where '0' is params that aren't in an array 114411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # TODO : Should integrate slightly better code for this purpose from unique_objects layer 114511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_params = defaultdict(list) # Dict uses loop count as key to make final code generation cleaner so params shared in single loop where needed 114611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_types = defaultdict(list) 114711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # TODO : For now skipping objs that can be NULL. Really should check these and have special case that allows them to be NULL 114811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # or better yet, these should be encoded into an API json definition and we generate checks from there 114911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Until then, this is a dict where each func name is a list of object params that can be null (so don't need to be validated) 115011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # param names may be directly passed to the function, or may be a field in a struct param 115111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert valid_null_object_names = {'CreateGraphicsPipelines' : ['basePipelineHandle'], 115211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateComputePipelines' : ['basePipelineHandle'], 115311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'BeginCommandBuffer' : ['renderPass', 'framebuffer'], 115411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'QueueSubmit' : ['fence'], 115511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'AcquireNextImageKHR' : ['fence', 'semaphore' ], 115611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'UpdateDescriptorSets' : ['pTexelBufferView'], 115711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateSwapchainKHR' : ['oldSwapchain'], 115811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 115911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param_count = 'NONE' # keep track of arrays passed directly into API functions 116011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for p in proto.params: 116111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert base_type = p.ty.replace('const ', '').strip('*') 116211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'count' in p.name.lower(): 116311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param_count = p.name 116411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if base_type in vulkan.core.objects: 116511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # This is an object to potentially check for validity. First see if it's an array 116611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '*' in p.ty and 'const' in p.ty and param_count != 'NONE': 116711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_params[param_count].append(p.name) 116811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_types[param_count].append(str(p.ty[6:-1])) 116911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Not an array, check for just a base Object that's not in exceptions 117011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif '*' not in p.ty and (proto.name not in valid_null_object_names or p.name not in valid_null_object_names[proto.name]): 117111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_params[0].append(p.name) 117211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_types[0].append(str(p.ty)) 117311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif vk_helper.is_type(base_type, 'struct'): 117411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_type = base_type 117511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_helper.typedef_rev_dict[struct_type] in vk_helper.struct_dict: 117611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct_type = vk_helper.typedef_rev_dict[struct_type] 117711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Parse elements of this struct param to identify objects and/or arrays of objects 117811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for m in sorted(vk_helper.struct_dict[struct_type]): 117911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_helper.struct_dict[struct_type][m]['type'] in vulkan.core.objects and vk_helper.struct_dict[struct_type][m]['type'] not in ['VkPhysicalDevice', 'VkQueue', 'VkFence', 'VkImage', 'VkDeviceMemory']: 118011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.name not in valid_null_object_names or vk_helper.struct_dict[struct_type][m]['name'] not in valid_null_object_names[proto.name]: 118111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # This is not great, but gets the job done for now, but If we have a count and this param is a ptr w/ 118211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # last letter 's' OR non-'count' string of count is in the param name, then this is a dynamically sized array param 118311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param_array = False 118411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if param_count != 'NONE': 118511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '*' in p.ty: 118611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 's' == p.name[-1] or param_count.lower().replace('count', '') in p.name.lower(): 118711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param_array = True 118811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if param_array: 118911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param_name = '%s[i].%s' % (p.name, vk_helper.struct_dict[struct_type][m]['name']) 119011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 119111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert param_name = '%s->%s' % (p.name, vk_helper.struct_dict[struct_type][m]['name']) 119211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if vk_helper.struct_dict[struct_type][m]['dyn_array']: 119311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if param_count != 'NONE': # this will be a double-embedded loop, use comma delineated 'count,name' for param_name 119411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_count = '%s[i].%s' % (p.name, vk_helper.struct_dict[struct_type][m]['array_size']) 119511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_params[param_count].append('%s,%s' % (loop_count, param_name)) 119611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_types[param_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type'])) 119711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 119811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_count = '%s->%s' % (p.name, vk_helper.struct_dict[struct_type][m]['array_size']) 119911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_params[loop_count].append(param_name) 120011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_types[loop_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type'])) 120111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 120211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '[' in param_name: # dynamic array param, set size 120311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_params[param_count].append(param_name) 120411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_types[param_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type'])) 120511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 120611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_params[0].append(param_name) 120711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert loop_types[0].append('%s' % (vk_helper.struct_dict[struct_type][m]['type'])) 120811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert last_param_index = None 120911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_func = False 121011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if True in [create_txt in proto.name for create_txt in ['Create', 'Allocate']]: 121111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_func = True 121211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert last_param_index = -1 # For create funcs don't validate last object 121311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (struct_uses, local_decls) = get_object_uses(vulkan.object_type_list, proto.params[:last_param_index]) 121411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs = [] 121511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert mutex_unlock = False 121611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s\n' % self.lineinfo.get()) 121711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.name in explicit_object_tracker_functions: 121811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s%s\n' 121911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '{\n' 122011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' return explicit_%s;\n' 122111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '}' % (qual, decl, proto.c_call())) 122211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "".join(funcs) 122311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Temporarily prevent DestroySurface call from being generated until WSI layer support is fleshed out 122411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif 'DestroyInstance' in proto.name or 'DestroyDevice' in proto.name: 122511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "" 122611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 122711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if create_func: 122811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typ = proto.params[-1].ty.strip('*').replace('const ', ''); 122911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ) 123011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:] 123111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_line = ' {\n' 123211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_line += ' std::lock_guard<std::mutex> lock(global_lock);\n' 123311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_line += ' if (result == VK_SUCCESS) {\n' 123411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_line += ' create_%s(%s, *%s, %s);\n' % (name, param0_name, proto.params[-1].name, obj_type_mapping[typ]) 123511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_line += ' }\n' 123611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_line += ' }\n' 123711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'FreeCommandBuffers' in proto.name: 123811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typ = proto.params[-1].ty.strip('*').replace('const ', ''); 123911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ) 124011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:] 124111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s\n' % self.lineinfo.get()) 124211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n' 124311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line += ' for (uint32_t i = 0; i < commandBufferCount; i++) {\n' 124411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line += ' destroy_%s(%s[i], %s[i]);\n' % (name, proto.params[-1].name, proto.params[-1].name) 124511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line += ' }\n' 124611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n' 124711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'Destroy' in proto.name: 124811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typ = proto.params[-2].ty.strip('*').replace('const ', ''); 124911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ) 125011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:] 125111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s\n' % self.lineinfo.get()) 125211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line = ' {\n' 125311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line += ' std::lock_guard<std::mutex> lock(global_lock);\n' 125411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line += ' destroy_%s(%s, %s);\n' % (name, param0_name, proto.params[-2].name) 125511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_line += ' }\n' 125611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = ' ' 125711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if len(struct_uses) > 0: 125811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += '%sbool skipCall = false;\n' % (indent) 125911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if not mutex_unlock: 126011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += '%s{\n' % (indent) 126111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 126211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += '%sstd::lock_guard<std::mutex> lock(global_lock);\n' % (indent) 126311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert mutex_unlock = True 126411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += '// objects to validate: %s\n' % str(sorted(struct_uses)) 126511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += self._gen_obj_validate_code(struct_uses, obj_type_mapping, proto.name, valid_null_object_names, param0_name, indent, '', 0) 126611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if mutex_unlock: 126711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 126811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += '%s}\n' % (indent) 126911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if len(struct_uses) > 0: 127011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += ' if (skipCall)\n' 127111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.ret == "bool": 127211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += ' return false;\n' 127311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif proto.ret == "VkBool32": 127411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += ' return VK_FALSE;\n' 127511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif proto.ret != "void": 127611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += ' return VK_ERROR_VALIDATION_FAILED_EXT;\n' 127711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 127811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using_line += ' return;\n' 127911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_val = '' 128011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert stmt = '' 128111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.ret != "void": 128211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_val = "%s result = " % proto.ret 128311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert stmt = " return result;\n" 128411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 128511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_param = proto.params[0].name 128611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'CreateInstance' in proto.name: 128711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_param = '*' + proto.params[1].name 128811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 128911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Must use 'instance' table for these APIs, 'device' table otherwise 129011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert table_type = "" 129111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto_is_global(proto): 129211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert table_type = "instance" 129311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 129411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert table_type = "device" 129511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if wsi_name(proto.name): 129611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s' % wsi_ifdef(proto.name)) 129711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s%s\n' 129811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '{\n' 129911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s' 130011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s' 130111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' %sget_dispatch_table(object_tracker_%s_table_map, %s)->%s;\n' 130211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s' 130311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s' 130411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '}' % (qual, decl, using_line, destroy_line, ret_val, table_type, dispatch_param, proto.c_call(), create_line, stmt)) 130511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if wsi_name(proto.name): 130611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s' % wsi_endif(proto.name)) 130711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n\n".join(funcs) 130811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 130911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_body(self): 131011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.layer_name = "object_tracker" 131111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert extensions=[('wsi_enabled', 131211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ['vkCreateSwapchainKHR', 131311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR', 131411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])] 131511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.wsi == 'Win32': 131611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions=[('msg_callback_get_proc_addr', []), 131711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ('wsi_enabled', 131811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ['vkDestroySurfaceKHR', 131911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceSupportKHR', 132011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR', 132111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceFormatsKHR', 132211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfacePresentModesKHR', 132311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateWin32SurfaceKHR', 132411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceWin32PresentationSupportKHR'])] 132511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif self.wsi == 'Android': 132611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions=[('msg_callback_get_proc_addr', []), 132711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ('wsi_enabled', 132811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ['vkDestroySurfaceKHR', 132911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceSupportKHR', 133011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR', 133111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceFormatsKHR', 133211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfacePresentModesKHR', 133311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateAndroidSurfaceKHR'])] 133411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif self.wsi == 'Xcb' or self.wsi == 'Xlib' or self.wsi == 'Wayland' or self.wsi == 'Mir': 133511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions=[('msg_callback_get_proc_addr', []), 133611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ('wsi_enabled', 133711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ['vkDestroySurfaceKHR', 133811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceSupportKHR', 133911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR', 134011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceFormatsKHR', 134111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfacePresentModesKHR', 134211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateXcbSurfaceKHR', 134311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceXcbPresentationSupportKHR', 134411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateXlibSurfaceKHR', 134511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceXlibPresentationSupportKHR', 134611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateWaylandSurfaceKHR', 134711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceWaylandPresentationSupportKHR', 134811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateMirSurfaceKHR', 134911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceMirPresentationSupportKHR'])] 135011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 135111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert print('Error: Undefined DisplayServer') 135211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions=[] 135311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 135411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body = ["namespace %s {" % self.layer_name, 135511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.generate_maps(), 135611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.generate_procs(), 135711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.generate_destroy_instance(), 135811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.generate_destroy_device(), 135911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self._generate_dispatch_entrypoints(), 136011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self._generate_extensions(), 136111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self._generate_layer_gpa_function(extensions, 136211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions), 136311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "} // namespace %s" % self.layer_name, 136411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self._gen_layer_logging_workaround(), 136511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self._gen_layer_interface_v0_functions()] 136611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n\n".join(body) 136711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 136811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass UniqueObjectsSubcommand(Subcommand): 136911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_header(self): 137011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt = [] 137111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('%s' % self.lineinfo.get()) 137211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert header_txt.append('#include "unique_objects.h"') 137311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n".join(header_txt) 137411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 137511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Generate UniqueObjects code for given struct_uses dict of objects that need to be unwrapped 137611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # vector_name_set is used to make sure we don't replicate vector names 137711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # first_level_param indicates if elements are passed directly into the function else they're below a ptr/struct 137811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # TODO : Comment this code 137911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def _gen_obj_code(self, struct_uses, param_type, indent, prefix, array_index, vector_name_set, first_level_param): 138011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decls = '' 138111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code = '' 138211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_code = '' 138311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for obj in sorted(struct_uses): 138411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = obj 138511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array = '' 138611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '[' in obj: 138711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (name, array) = obj.split('[') 138811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array = array.strip(']') 138911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptr_type = False 139011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'p' == obj[0] and obj[1] != obj[1].lower(): # TODO : Not ideal way to determine ptr 139111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptr_type = True 139211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if isinstance(struct_uses[obj], dict): 139311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_prefix = '' 139411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = '%s%s' % (prefix, name) 139511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ptr_type: 139611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if first_level_param and name in param_type: 139711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sif (%s) {\n' % (indent, name) 139811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: # shadow ptr will have been initialized at this point so check it vs. source ptr 139911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sif (local_%s) {\n' % (indent, name) 140011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 140111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '': 140211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert idx = 'idx%s' % str(array_index) 140311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array_index += 1 140411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if first_level_param and name in param_type: 140511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%slocal_%s = new safe_%s[%s];\n' % (indent, name, param_type[name].strip('*'), array) 140611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_code += ' if (local_%s)\n' % (name) 140711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_code += ' delete[] local_%s;\n' % (name) 140811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx) 140911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 141011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if first_level_param: 141111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%slocal_%s[%s].initialize(&%s[%s]);\n' % (indent, name, idx, name, idx) 141211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_prefix = '%s[%s].' % (name, idx) 141311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif ptr_type: 141411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if first_level_param and name in param_type: 141511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%slocal_%s = new safe_%s(%s);\n' % (indent, name, param_type[name].strip('*'), name) 141611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_code += ' if (local_%s)\n' % (name) 141711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_code += ' delete local_%s;\n' % (name) 141811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_prefix = '%s->' % (name) 141911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 142011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_prefix = '%s.' % (name) 142111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert isinstance(decls, object) 142211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (tmp_decl, tmp_pre, tmp_post) = self._gen_obj_code(struct_uses[obj], param_type, indent, local_prefix, array_index, vector_name_set, False) 142311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decls += tmp_decl 142411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += tmp_pre 142511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_code += tmp_post 142611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '': 142711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 142811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s}\n' % (indent) 142911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ptr_type: 143011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 143111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s}\n' % (indent) 143211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 143311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (array_index > 0) or array != '': # TODO : This is not ideal, really want to know if we're anywhere under an array 143411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if first_level_param: 143511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decls += '%s%s* local_%s = NULL;\n' % (indent, struct_uses[obj], name) 143611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '' and not first_level_param: # ptrs under structs will have been initialized so use local_* 143711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sif (local_%s%s) {\n' %(indent, prefix, name) 143811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 143911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sif (%s%s) {\n' %(indent, prefix, name) 144011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 144111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '': 144211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert idx = 'idx%s' % str(array_index) 144311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert array_index += 1 144411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if first_level_param: 144511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%slocal_%s = new %s[%s];\n' % (indent, name, struct_uses[obj], array) 144611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_code += ' if (local_%s)\n' % (name) 144711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_code += ' delete[] local_%s;\n' % (name) 144811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx) 144911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 145011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert name = '%s[%s]' % (name, idx) 145111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pName = 'p%s' % (struct_uses[obj][2:]) 145211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if name not in vector_name_set: 145311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vector_name_set.add(name) 145411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%slocal_%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s%s)];\n' % (indent, prefix, name, struct_uses[obj], prefix, name) 145511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if array != '': 145611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 145711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s}\n' % (indent) 145811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 145911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s}\n' % (indent) 146011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 146111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s\n' % (self.lineinfo.get()) 146211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert deref_txt = '&' 146311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ptr_type: 146411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert deref_txt = '' 146511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '->' in prefix: # need to update local struct 146611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%slocal_%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s%s)];\n' % (indent, prefix, name, struct_uses[obj], prefix, name) 146711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 146811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code += '%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t &>(%s)];\n' % (indent, name, struct_uses[obj], name) 146911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return decls, pre_code, post_code 147011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 147111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_intercept(self, proto, qual): 147211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_func = False 147311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_func = False 147411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert last_param_index = None #typcially we look at all params for ndos 147511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt = '' # code prior to calling down chain such as unwrap uses of ndos 147611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt = '' # code following call down chain such to wrap newly created ndos, or destroy local wrap struct 147711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs = [] 147811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = ' ' # indent level for generated code 147911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert decl = proto.c_func(attr="VKAPI") 148011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # A few API cases that are manual code 148111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # TODO : Special case Create*Pipelines funcs to handle creating multiple unique objects 148211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit_object_tracker_functions = ['GetSwapchainImagesKHR', 148311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateSwapchainKHR', 148411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateInstance', 148511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'DestroyInstance', 148611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateDevice', 148711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'DestroyDevice', 148811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateComputePipelines', 148911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateGraphicsPipelines' 149011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ] 149111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # TODO : This is hacky, need to make this a more general-purpose solution for all layers 149211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ifdef_dict = {'CreateXcbSurfaceKHR': 'VK_USE_PLATFORM_XCB_KHR', 149311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateAndroidSurfaceKHR': 'VK_USE_PLATFORM_ANDROID_KHR', 149411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateWin32SurfaceKHR': 'VK_USE_PLATFORM_WIN32_KHR', 149511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateXlibSurfaceKHR': 'VK_USE_PLATFORM_XLIB_KHR', 149611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateWaylandSurfaceKHR': 'VK_USE_PLATFORM_WAYLAND_KHR', 149711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'CreateMirSurfaceKHR': 'VK_USE_PLATFORM_MIR_KHR'} 149811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Give special treatment to create functions that return multiple new objects 149911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # This dict stores array name and size of array 150011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert custom_create_dict = {'pDescriptorSets' : 'pAllocateInfo->descriptorSetCount'} 150111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '%s\n' % (self.lineinfo.get()) 150211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.name in explicit_object_tracker_functions: 150311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s%s\n' 150411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '{\n' 150511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' return explicit_%s;\n' 150611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '}' % (qual, decl, proto.c_call())) 150711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "".join(funcs) 150811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if True in [create_txt in proto.name for create_txt in ['Create', 'Allocate']]: 150911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert create_func = True 151011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert last_param_index = -1 # For create funcs don't care if last param is ndo 151111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if True in [destroy_txt in proto.name for destroy_txt in ['Destroy', 'Free']]: 151211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_obj_type = proto.params[-2].ty 151311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if destroy_obj_type in vulkan.object_non_dispatch_list: 151411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert destroy_func = True 151511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 151611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # First thing we need to do is gather uses of non-dispatchable-objects (ndos) 151711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (struct_uses, local_decls) = get_object_uses(vulkan.object_non_dispatch_list, proto.params[1:last_param_index]) 151811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 151911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_param = proto.params[0].name 152011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'CreateInstance' in proto.name: 152111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_param = '*' + proto.params[1].name 152211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '%slayer_data *my_map_data = get_my_data_ptr(get_dispatch_key(%s), layer_data_map);\n' % (indent, dispatch_param) 152311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if len(struct_uses) > 0: 152411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '// STRUCT USES:%s\n' % sorted(struct_uses) 152511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if len(local_decls) > 0: 152611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '//LOCAL DECLS:%s\n' % sorted(local_decls) 152711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if destroy_func: # only one object 152811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '%sstd::unique_lock<std::mutex> lock(global_lock);\n' % (indent) 152911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for del_obj in sorted(struct_uses): 153011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '%suint64_t local_%s = reinterpret_cast<uint64_t &>(%s);\n' % (indent, del_obj, del_obj) 153111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '%s%s = (%s)my_map_data->unique_id_mapping[local_%s];\n' % (indent, del_obj, struct_uses[del_obj], del_obj) 153211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '%slock.unlock();\n' % (indent) 153311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pre_decl, pre_code, post_code) = ('', '', '') 153411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 153511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pre_decl, pre_code, post_code) = self._gen_obj_code(struct_uses, local_decls, ' ', '', 0, set(), True) 153611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # This is a bit hacky but works for now. Need to decl local versions of top-level structs 153711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ld in sorted(local_decls): 153811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert init_null_txt = 'NULL'; 153911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if '*' not in local_decls[ld]: 154011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert init_null_txt = '{}'; 154111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if local_decls[ld].strip('*') not in vulkan.object_non_dispatch_list: 154211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_decl += ' safe_%s local_%s = %s;\n' % (local_decls[ld], ld, init_null_txt) 154311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if pre_code != '': # lock around map uses 154411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_code = '%s{\n%sstd::lock_guard<std::mutex> lock(global_lock);\n%s%s}\n' % (indent, indent, pre_code, indent) 154511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '%s%s' % (pre_decl, pre_code) 154611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s' % (post_code) 154711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif create_func: 154811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert base_type = proto.params[-1].ty.replace('const ', '').strip('*') 154911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if base_type not in vulkan.object_non_dispatch_list: 155011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return None 155111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 155211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return None 155311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 155411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_val = '' 155511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_stmt = '' 155611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.ret != "void": 155711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_val = "%s result = " % proto.ret 155811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ret_stmt = " return result;\n" 155911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if create_func: 156011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_type = proto.params[-1].ty.strip('*') 156111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert obj_name = proto.params[-1].name 156211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if obj_type in vulkan.object_non_dispatch_list: 156311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_name = "unique%s" % obj_type[2:] 156411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%sif (VK_SUCCESS == result) {\n' % (indent) 156511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 156611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%sstd::lock_guard<std::mutex> lock(global_lock);\n' % (indent) 156711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if obj_name in custom_create_dict: 156811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s\n' % (self.lineinfo.get()) 156911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert local_name = '%ss' % (local_name) # add 's' to end for vector of many 157011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%sfor (uint32_t i=0; i<%s; ++i) {\n' % (indent, custom_create_dict[obj_name]) 157111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 157211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%suint64_t unique_id = global_unique_id++;\n' % (indent) 157311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%smy_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(%s[i]);\n' % (indent, obj_name) 157411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s%s[i] = reinterpret_cast<%s&>(unique_id);\n' % (indent, obj_name, obj_type) 157511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 157611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s}\n' % (indent) 157711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 157811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s\n' % (self.lineinfo.get()) 157911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%suint64_t unique_id = global_unique_id++;\n' % (indent) 158011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%smy_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*%s);\n' % (indent, obj_name) 158111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s*%s = reinterpret_cast<%s&>(unique_id);\n' % (indent, obj_name, obj_type) 158211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 158311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s}\n' % (indent) 158411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif destroy_func: 158511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert del_obj = proto.params[-2].name 158611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if 'count' in del_obj.lower(): 158711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s\n' % (self.lineinfo.get()) 158811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%sfor (uint32_t i=0; i<%s; ++i) {\n' % (indent, del_obj) 158911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert del_obj = proto.params[-1].name 159011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent += ' ' 159111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%sdelete (VkUniqueObject*)%s[i];\n' % (indent, del_obj) 159211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert indent = indent[4:] 159311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s}\n' % (indent) 159411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 159511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%s\n' % (self.lineinfo.get()) 159611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%slock.lock();\n' % (indent) 159711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert post_call_txt += '%smy_map_data->unique_id_mapping.erase(local_%s);\n' % (indent, proto.params[-2].name) 159811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 159911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert call_sig = proto.c_call() 160011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert # Replace default params with any custom local params 160111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for ld in local_decls: 160211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert call_sig = call_sig.replace(ld, '(const %s)local_%s' % (local_decls[ld], ld)) 160311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto_is_global(proto): 160411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert table_type = "instance" 160511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 160611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert table_type = "device" 160711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pre_call_txt += '%s\n' % (self.lineinfo.get()) 160811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert open_ifdef = '' 160911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert close_ifdef = '' 161011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if proto.name in ifdef_dict: 161111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert open_ifdef = '#ifdef %s\n' % (ifdef_dict[proto.name]) 161211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert close_ifdef = '#endif\n' 161311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert funcs.append('%s' 161411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s%s\n' 161511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '{\n' 161611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s' 161711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ' %sget_dispatch_table(unique_objects_%s_table_map, %s)->%s;\n' 161811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s' 161911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s' 162011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '}\n' 162111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert '%s' % (open_ifdef, qual, decl, pre_call_txt, ret_val, table_type, dispatch_param, call_sig, post_call_txt, ret_stmt, close_ifdef)) 162211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n\n".join(funcs) 162311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 162411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert def generate_body(self): 162511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self.layer_name = "unique_objects" 162611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert extensions=[('wsi_enabled', 162711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ['vkCreateSwapchainKHR', 162811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR', 162911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])] 163011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if self.wsi == 'Win32': 163111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions=[('wsi_enabled', 163211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ['vkDestroySurfaceKHR', 163311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceSupportKHR', 163411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR', 163511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceFormatsKHR', 163611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfacePresentModesKHR', 163711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateWin32SurfaceKHR' 163811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ])] 163911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif self.wsi == 'Android': 164011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions=[('wsi_enabled', 164111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ['vkDestroySurfaceKHR', 164211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceSupportKHR', 164311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR', 164411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceFormatsKHR', 164511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfacePresentModesKHR', 164611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateAndroidSurfaceKHR'])] 164711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert elif self.wsi == 'Xcb' or self.wsi == 'Xlib' or self.wsi == 'Wayland' or self.wsi == 'Mir': 164811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions=[('wsi_enabled', 164911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ['vkDestroySurfaceKHR', 165011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceSupportKHR', 165111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR', 165211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfaceFormatsKHR', 165311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkGetPhysicalDeviceSurfacePresentModesKHR', 165411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateXcbSurfaceKHR', 165511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateXlibSurfaceKHR', 165611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateWaylandSurfaceKHR', 165711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 'vkCreateMirSurfaceKHR' 165811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ])] 165911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else: 166011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert print('Error: Undefined DisplayServer') 166111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions=[] 166211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 166311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert body = ["namespace %s {" % self.layer_name, 166411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self._generate_dispatch_entrypoints(), 166511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self._generate_layer_gpa_function(extensions, 166611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert instance_extensions), 166711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "} // namespace %s" % self.layer_name, 166811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert self._gen_layer_interface_v0_functions()] 166911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return "\n\n".join(body) 167011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 167111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertdef main(): 167211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert wsi = { 167311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Win32", 167411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Android", 167511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Xcb", 167611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Xlib", 167711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Wayland", 167811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Mir", 167911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 168011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 168111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert subcommands = { 168211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "object_tracker" : ObjectTrackerSubcommand, 168311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "unique_objects" : UniqueObjectsSubcommand, 168411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 168511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 168611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if len(sys.argv) < 4 or sys.argv[1] not in wsi or sys.argv[2] not in subcommands or not os.path.exists(sys.argv[3]): 168711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert print("Usage: %s <wsi> <subcommand> <input_header> [outdir]" % sys.argv[0]) 168811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert print 168911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert print("Available subcommands are: %s" % " ".join(subcommands)) 169011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert exit(1) 169111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 169211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert hfp = vk_helper.HeaderFileParser(sys.argv[3]) 169311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert hfp.parse() 169411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vk_helper.enum_val_dict = hfp.get_enum_val_dict() 169511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vk_helper.enum_type_dict = hfp.get_enum_type_dict() 169611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vk_helper.struct_dict = hfp.get_struct_dict() 169711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vk_helper.typedef_fwd_dict = hfp.get_typedef_fwd_dict() 169811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vk_helper.typedef_rev_dict = hfp.get_typedef_rev_dict() 169911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert vk_helper.types_dict = hfp.get_types_dict() 170011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 170111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert outfile = None 170211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if len(sys.argv) >= 5: 170311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert outfile = sys.argv[4] 170411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 170511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert subcmd = subcommands[sys.argv[2]](outfile) 170611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert subcmd.run() 170711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 170811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertif __name__ == "__main__": 170911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert main() 1710