blob: f05dbd2a7ff8f5116601ce61f6b718581127f984 [file] [log] [blame]
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001#!/usr/bin/env python3
2#
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003# VK
Tobin Ehlis12076fc2014-10-22 09:06:33 -06004#
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -06005# Copyright (C) 2015 Valve Corporation
Michael Lentine64e2ebd2015-12-03 14:33:09 -08006# Copyright (C) 2015 Google Inc.
Tobin Ehlis12076fc2014-10-22 09:06:33 -06007#
8# Permission is hereby granted, free of charge, to any person obtaining a
9# copy of this software and associated documentation files (the "Software"),
10# to deal in the Software without restriction, including without limitation
11# the rights to use, copy, modify, merge, publish, distribute, sublicense,
12# and/or sell copies of the Software, and to permit persons to whom the
13# Software is furnished to do so, subject to the following conditions:
14#
15# The above copyright notice and this permission notice shall be included
16# in all copies or substantial portions of the Software.
17#
18# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24# DEALINGS IN THE SOFTWARE.
25#
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060026# Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
27# Author: Jon Ashburn <jon@lunarg.com>
28# Author: Mark Lobodzinski <mark@lunarg.com>
29# Author: Mike Stroyan <mike@LunarG.com>
30# Author: Tony Barbour <tony@LunarG.com>
Jon Ashburnf2bad722015-11-03 11:57:00 -070031# Author: Chia-I Wu <olv@lunarg.com>
Tobin Ehlis12076fc2014-10-22 09:06:33 -060032
33import sys
Tobin Ehlis14ff0852014-12-17 17:44:50 -070034import os
Mark Lobodzinski7c75b852015-05-05 15:01:37 -050035import re
Tobin Ehlis12076fc2014-10-22 09:06:33 -060036
Courtney Goeltzenleuchterf53c3cb2015-04-14 14:55:44 -060037import vulkan
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060038import vk_helper
Tobin Ehlis08fafd02015-06-12 12:49:01 -060039from source_line_info import sourcelineinfo
Tobin Ehlis154e0462015-08-26 11:22:09 -060040from collections import defaultdict
Tobin Ehlis12076fc2014-10-22 09:06:33 -060041
Jon Ashburn95a77ba2015-05-15 15:09:35 -060042def proto_is_global(proto):
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -070043 global_function_names = [
44 "CreateInstance",
45 "EnumerateInstanceLayerProperties",
46 "EnumerateInstanceExtensionProperties",
47 "EnumerateDeviceLayerProperties",
48 "EnumerateDeviceExtensionProperties",
49 "CreateXcbSurfaceKHR",
50 "vkGetPhysicalDeviceXcbPresentationSupportKHR",
51 "CreateXlibSurfaceKHR",
52 "vkGetPhysicalDeviceXlibPresentationSupportKHR",
53 "CreateWaylandSurfaceKHR",
54 "vkGetPhysicalDeviceWaylandPresentationSupportKHR",
55 "CreateMirSurfaceKHR",
56 "vkGetPhysicalDeviceMirPresentationSupportKHR",
57 "CreateAndroidSurfaceKHR",
58 "CreateWin32SurfaceKHR",
59 "vkGetPhysicalDeviceWin32PresentationSupportKHR"
60 ]
61 if proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice" or proto.name in global_function_names:
Jon Ashburn95a77ba2015-05-15 15:09:35 -060062 return True
63 else:
64 return False
65
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -070066def wsi_name(ext_name):
67 wsi_prefix = ""
68 if 'Xcb' in ext_name:
69 wsi_prefix = 'XCB'
70 elif 'Xlib' in ext_name:
71 wsi_prefix = 'XLIB'
72 elif 'Win32' in ext_name:
73 wsi_prefix = 'WIN32'
74 elif 'Mir' in ext_name:
75 wsi_prefix = 'MIR'
76 elif 'Wayland' in ext_name:
77 wsi_prefix = 'WAYLAND'
78 elif 'Android' in ext_name:
79 wsi_prefix = 'ANDROID'
80 else:
81 wsi_prefix = ''
82 return wsi_prefix
83
84def wsi_ifdef(ext_name):
85 wsi_prefix = wsi_name(ext_name)
86 if not wsi_prefix:
87 return ''
88 else:
89 return "#ifdef VK_USE_PLATFORM_%s_KHR" % wsi_prefix
90
91def wsi_endif(ext_name):
92 wsi_prefix = wsi_name(ext_name)
93 if not wsi_prefix:
94 return ''
95 else:
96 return "#endif // VK_USE_PLATFORM_%s_KHR" % wsi_prefix
97
Mike Stroyan938c2532015-04-03 13:58:35 -060098def generate_get_proc_addr_check(name):
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060099 return " if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \
100 " return NULL;" % ((name,) * 3)
Mike Stroyan938c2532015-04-03 13:58:35 -0600101
Mark Lobodzinski7c75b852015-05-05 15:01:37 -0500102def ucc_to_U_C_C(CamelCase):
103 temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', CamelCase)
104 return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).upper()
105
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600106class Subcommand(object):
107 def __init__(self, argv):
108 self.argv = argv
Courtney Goeltzenleuchterf53c3cb2015-04-14 14:55:44 -0600109 self.headers = vulkan.headers
110 self.protos = vulkan.protos
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -0600111 self.no_addr = False
112 self.layer_name = ""
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600113 self.lineinfo = sourcelineinfo()
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600114
115 def run(self):
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600116 print(self.generate())
117
118 def generate(self):
119 copyright = self.generate_copyright()
120 header = self.generate_header()
121 body = self.generate_body()
122 footer = self.generate_footer()
123
124 contents = []
125 if copyright:
126 contents.append(copyright)
127 if header:
128 contents.append(header)
129 if body:
130 contents.append(body)
131 if footer:
132 contents.append(footer)
133
134 return "\n\n".join(contents)
135
136 def generate_copyright(self):
137 return """/* THIS FILE IS GENERATED. DO NOT EDIT. */
138
139/*
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600140 *
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -0600141 * Copyright (C) 2015 Valve Corporation
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600142 *
143 * Permission is hereby granted, free of charge, to any person obtaining a
144 * copy of this software and associated documentation files (the "Software"),
145 * to deal in the Software without restriction, including without limitation
146 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
147 * and/or sell copies of the Software, and to permit persons to whom the
148 * Software is furnished to do so, subject to the following conditions:
149 *
150 * The above copyright notice and this permission notice shall be included
151 * in all copies or substantial portions of the Software.
152 *
153 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
155 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
156 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
157 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
158 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
159 * DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -0600160 *
161 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
162 * Author: Jon Ashburn <jon@lunarg.com>
163 * Author: Mark Lobodzinski <mark@lunarg.com>
164 * Author: Mike Stroyan <mike@LunarG.com>
165 * Author: Tony Barbour <tony@LunarG.com>
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600166 */"""
167
168 def generate_header(self):
169 return "\n".join(["#include <" + h + ">" for h in self.headers])
170
171 def generate_body(self):
172 pass
173
174 def generate_footer(self):
175 pass
176
177 # Return set of printf '%' qualifier and input to that qualifier
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600178 def _get_printf_params(self, vk_type, name, output_param, cpp=False):
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600179 # TODO : Need ENUM and STRUCT checks here
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600180 if vk_helper.is_type(vk_type, 'enum'):#"_TYPE" in vk_type: # TODO : This should be generic ENUM check
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -0600181 return ("%s", "string_%s(%s)" % (vk_type.replace('const ', '').strip('*'), name))
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600182 if "char*" == vk_type:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600183 return ("%s", name)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600184 if "uint64" in vk_type:
185 if '*' in vk_type:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600186 return ("%lu", "*%s" % name)
187 return ("%lu", name)
Tobin Ehlisa30e7e52015-07-06 14:02:36 -0600188 if vk_type.strip('*') in vulkan.object_non_dispatch_list:
189 if '*' in vk_type:
Chia-I Wue2fc5522015-10-26 20:04:44 +0800190 return ("%lu", "%s" % name)
191 return ("%lu", "%s" % name)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600192 if "size" in vk_type:
193 if '*' in vk_type:
Mark Lobodzinskia1456492015-10-06 09:57:52 -0600194 return ("%lu", "(unsigned long)*%s" % name)
195 return ("%lu", "(unsigned long)%s" % name)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600196 if "float" in vk_type:
197 if '[' in vk_type: # handle array, current hard-coded to 4 (TODO: Make this dynamic)
Tobin Ehlis99f88672015-01-10 12:42:41 -0700198 if cpp:
199 return ("[%i, %i, %i, %i]", '"[" << %s[0] << "," << %s[1] << "," << %s[2] << "," << %s[3] << "]"' % (name, name, name, name))
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600200 return ("[%f, %f, %f, %f]", "%s[0], %s[1], %s[2], %s[3]" % (name, name, name, name))
201 return ("%f", name)
Courtney Goeltzenleuchtercd2a0992015-07-09 11:44:38 -0600202 if "bool" in vk_type.lower() or 'xcb_randr_crtc_t' in vk_type:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600203 return ("%u", name)
Tobin Ehlisb870cbb2015-04-15 07:46:12 -0600204 if True in [t in vk_type.lower() for t in ["int", "flags", "mask", "xcb_window_t"]]:
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600205 if '[' in vk_type: # handle array, current hard-coded to 4 (TODO: Make this dynamic)
Tobin Ehlis99f88672015-01-10 12:42:41 -0700206 if cpp:
207 return ("[%i, %i, %i, %i]", "%s[0] << %s[1] << %s[2] << %s[3]" % (name, name, name, name))
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600208 return ("[%i, %i, %i, %i]", "%s[0], %s[1], %s[2], %s[3]" % (name, name, name, name))
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600209 if '*' in vk_type:
Tobin Ehlisd2b88e82015-02-04 15:15:11 -0700210 if 'pUserData' == name:
211 return ("%i", "((pUserData == 0) ? 0 : *(pUserData))")
Tobin Ehlisc62cb892015-04-17 13:26:33 -0600212 if 'const' in vk_type.lower():
213 return ("%p", "(void*)(%s)" % name)
Jon Ashburn52f79b52014-12-12 16:10:45 -0700214 return ("%i", "*(%s)" % name)
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600215 return ("%i", name)
Tobin Ehlis3a1cc8d2014-11-11 17:28:22 -0700216 # TODO : This is special-cased as there's only one "format" param currently and it's nice to expand it
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600217 if "VkFormat" == vk_type:
Tobin Ehlis99f88672015-01-10 12:42:41 -0700218 if cpp:
219 return ("%p", "&%s" % name)
Chia-I Wu1b99bb22015-10-27 19:25:11 +0800220 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))
Tobin Ehlise7271572014-11-19 15:52:46 -0700221 if output_param:
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600222 return ("%p", "(void*)*%s" % name)
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600223 if vk_helper.is_type(vk_type, 'struct') and '*' not in vk_type:
Courtney Goeltzenleuchterd462fba2015-04-03 16:35:32 -0600224 return ("%p", "(void*)(&%s)" % name)
Jon Ashburn52f79b52014-12-12 16:10:45 -0700225 return ("%p", "(void*)(%s)" % name)
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600226
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600227 def _gen_create_msg_callback(self):
Tobin Ehlise8185062014-12-17 08:01:59 -0700228 r_body = []
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600229 r_body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700230 r_body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(')
231 r_body.append(' VkInstance instance,')
232 r_body.append(' const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,')
233 r_body.append(' const VkAllocationCallbacks* pAllocator,')
234 r_body.append(' VkDebugReportCallbackEXT* pCallback)')
Tobin Ehlise8185062014-12-17 08:01:59 -0700235 r_body.append('{')
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600236 # Switch to this code section for the new per-instance storage and debug callbacks
Mike Stroyan313f7e62015-08-10 16:42:53 -0600237 if self.layer_name == 'ObjectTracker' or self.layer_name == 'Threading':
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600238 r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700239 r_body.append(' VkResult result = pInstanceTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);')
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600240 r_body.append(' if (VK_SUCCESS == result) {')
241 r_body.append(' layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);')
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700242 r_body.append(' result = layer_create_msg_callback(my_data->report_data,')
243 r_body.append(' pCreateInfo,')
244 r_body.append(' pAllocator,')
245 r_body.append(' pCallback);')
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600246 r_body.append(' }')
247 r_body.append(' return result;')
248 else:
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700249 r_body.append(' VkResult result = instance_dispatch_table(instance)->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);')
Jon Ashburn3a278b72015-10-06 17:05:21 -0600250 r_body.append(' if (VK_SUCCESS == result) {')
251 r_body.append(' layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);')
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700252 r_body.append(' result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pCallback);')
Jon Ashburn3a278b72015-10-06 17:05:21 -0600253 r_body.append(' }')
254 r_body.append(' return result;')
Tobin Ehlise8185062014-12-17 08:01:59 -0700255 r_body.append('}')
256 return "\n".join(r_body)
257
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600258 def _gen_destroy_msg_callback(self):
259 r_body = []
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600260 r_body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700261 r_body.append('VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, const VkAllocationCallbacks *pAllocator)')
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600262 r_body.append('{')
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600263 # Switch to this code section for the new per-instance storage and debug callbacks
Mike Stroyan313f7e62015-08-10 16:42:53 -0600264 if self.layer_name == 'ObjectTracker' or self.layer_name == 'Threading':
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600265 r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600266 else:
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700267 r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700268 r_body.append(' pInstanceTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);')
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700269 r_body.append(' layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);')
270 r_body.append(' layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);')
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600271 r_body.append('}')
272 return "\n".join(r_body)
Tobin Ehlise8185062014-12-17 08:01:59 -0700273
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700274 def _gen_debug_report_msg(self):
275 r_body = []
276 r_body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700277 r_body.append('VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg)')
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700278 r_body.append('{')
279 # Switch to this code section for the new per-instance storage and debug callbacks
280 if self.layer_name == 'ObjectTracker' or self.layer_name == 'Threading':
281 r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
282 else:
283 r_body.append(' VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700284 r_body.append(' pInstanceTable->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);')
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700285 r_body.append('}')
286 return "\n".join(r_body)
287
Tony Barbour59a47322015-06-24 16:06:58 -0600288 def _gen_layer_get_global_extension_props(self, layer="Generic"):
289 ggep_body = []
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600290 # generated layers do not provide any global extensions
291 ggep_body.append('%s' % self.lineinfo.get())
292
293 ggep_body.append('')
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700294 if self.layer_name == 'ObjectTracker' or self.layer_name == 'Threading':
295 ggep_body.append('static const VkExtensionProperties instance_extensions[] = {')
296 ggep_body.append(' {')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700297 ggep_body.append(' VK_EXT_DEBUG_REPORT_EXTENSION_NAME,')
298 ggep_body.append(' VK_EXT_DEBUG_REPORT_REVISION')
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700299 ggep_body.append(' }')
300 ggep_body.append('};')
Chia-I Wu9ab61502015-11-06 06:42:02 +0800301 ggep_body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties* pProperties)')
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600302 ggep_body.append('{')
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700303 if self.layer_name == 'ObjectTracker' or self.layer_name == 'Threading':
304 ggep_body.append(' return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);')
305 else:
306 ggep_body.append(' return util_GetExtensionProperties(0, NULL, pCount, pProperties);')
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600307 ggep_body.append('}')
308 return "\n".join(ggep_body)
309
310 def _gen_layer_get_global_layer_props(self, layer="Generic"):
311 ggep_body = []
312 if layer == 'Generic':
313 # Do nothing, extension definition part of generic.h
Tony Barbour59a47322015-06-24 16:06:58 -0600314 ggep_body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -0600315 else:
Tony Barbour59a47322015-06-24 16:06:58 -0600316 ggep_body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter79a5a962015-07-07 17:51:45 -0600317 ggep_body.append('static const VkLayerProperties globalLayerProps[] = {')
Tony Barbour59a47322015-06-24 16:06:58 -0600318 ggep_body.append(' {')
Tony Barbour59a47322015-06-24 16:06:58 -0600319 ggep_body.append(' "%s",' % layer)
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600320 ggep_body.append(' VK_API_VERSION, // specVersion')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800321 ggep_body.append(' VK_MAKE_VERSION(0, 1, 0), // implementationVersion')
Tony Barbour59a47322015-06-24 16:06:58 -0600322 ggep_body.append(' "layer: %s",' % layer)
323 ggep_body.append(' }')
324 ggep_body.append('};')
325 ggep_body.append('')
326 ggep_body.append('%s' % self.lineinfo.get())
Tony Barbour59a47322015-06-24 16:06:58 -0600327 ggep_body.append('')
Chia-I Wu9ab61502015-11-06 06:42:02 +0800328 ggep_body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties* pProperties)')
Tony Barbour59a47322015-06-24 16:06:58 -0600329 ggep_body.append('{')
Courtney Goeltzenleuchter79a5a962015-07-07 17:51:45 -0600330 ggep_body.append(' return util_GetLayerProperties(ARRAY_SIZE(globalLayerProps), globalLayerProps, pCount, pProperties);')
Tony Barbour59a47322015-06-24 16:06:58 -0600331 ggep_body.append('}')
332 return "\n".join(ggep_body)
333
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -0600334 def _gen_layer_get_physical_device_layer_props(self, layer="Generic"):
335 gpdlp_body = []
336 if layer == 'Generic':
337 # Do nothing, extension definition part of generic.h
338 gpdlp_body.append('%s' % self.lineinfo.get())
339 else:
340 gpdlp_body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter79a5a962015-07-07 17:51:45 -0600341 gpdlp_body.append('static const VkLayerProperties deviceLayerProps[] = {')
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -0600342 gpdlp_body.append(' {')
343 gpdlp_body.append(' "%s",' % layer)
344 gpdlp_body.append(' VK_API_VERSION,')
345 gpdlp_body.append(' VK_MAKE_VERSION(0, 1, 0),')
346 gpdlp_body.append(' "layer: %s",' % layer)
347 gpdlp_body.append(' }')
348 gpdlp_body.append('};')
Chia-I Wu9ab61502015-11-06 06:42:02 +0800349 gpdlp_body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties* pProperties)')
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -0600350 gpdlp_body.append('{')
Courtney Goeltzenleuchter79a5a962015-07-07 17:51:45 -0600351 gpdlp_body.append(' return util_GetLayerProperties(ARRAY_SIZE(deviceLayerProps), deviceLayerProps, pCount, pProperties);')
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -0600352 gpdlp_body.append('}')
353 gpdlp_body.append('')
354 return "\n".join(gpdlp_body)
355
Mike Stroyanbf237d72015-04-03 17:45:53 -0600356 def _generate_dispatch_entrypoints(self, qual=""):
Mike Stroyan938c2532015-04-03 13:58:35 -0600357 if qual:
358 qual += " "
359
Mike Stroyan938c2532015-04-03 13:58:35 -0600360 funcs = []
361 intercepted = []
362 for proto in self.protos:
Jon Ashburn8d1b0b52015-05-18 13:20:15 -0600363 if proto.name == "GetDeviceProcAddr" or proto.name == "GetInstanceProcAddr":
Jon Ashburn8fd08252015-05-28 16:25:02 -0600364 continue
Mike Stroyan70c05e82015-04-08 10:27:43 -0600365 else:
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -0600366 intercept = self.generate_intercept(proto, qual)
Mike Stroyan938c2532015-04-03 13:58:35 -0600367 if intercept is None:
368 # fill in default intercept for certain entrypoints
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700369 if 'CreateDebugReportCallbackEXT' == proto.name:
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600370 intercept = self._gen_layer_dbg_create_msg_callback()
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700371 elif 'DestroyDebugReportCallbackEXT' == proto.name:
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600372 intercept = self._gen_layer_dbg_destroy_msg_callback()
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700373 elif 'DebugReportMessageEXT' == proto.name:
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700374 intercept = self._gen_debug_report_msg()
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600375 elif 'CreateDevice' == proto.name:
376 funcs.append('/* CreateDevice HERE */')
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -0600377 elif 'EnumerateInstanceExtensionProperties' == proto.name:
Tony Barbour59a47322015-06-24 16:06:58 -0600378 intercept = self._gen_layer_get_global_extension_props(self.layer_name)
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -0600379 elif 'EnumerateInstanceLayerProperties' == proto.name:
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600380 intercept = self._gen_layer_get_global_layer_props(self.layer_name)
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -0600381 elif 'EnumerateDeviceLayerProperties' == proto.name:
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600382 intercept = self._gen_layer_get_physical_device_layer_props(self.layer_name)
Tony Barbour59a47322015-06-24 16:06:58 -0600383
Mike Stroyan938c2532015-04-03 13:58:35 -0600384 if intercept is not None:
385 funcs.append(intercept)
Ian Elliott7e40db92015-08-21 15:09:33 -0600386 if not "KHR" in proto.name:
Jon Ashburn747f2b62015-06-18 15:02:58 -0600387 intercepted.append(proto)
Mike Stroyan938c2532015-04-03 13:58:35 -0600388
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600389 prefix="vk"
Mike Stroyan938c2532015-04-03 13:58:35 -0600390 lookups = []
391 for proto in intercepted:
Mike Stroyan938c2532015-04-03 13:58:35 -0600392 lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600393 lookups.append(" return (PFN_vkVoidFunction) %s%s;" %
Mike Stroyan938c2532015-04-03 13:58:35 -0600394 (prefix, proto.name))
Mike Stroyan938c2532015-04-03 13:58:35 -0600395
396 # add customized layer_intercept_proc
397 body = []
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600398 body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600399 body.append("static inline PFN_vkVoidFunction layer_intercept_proc(const char *name)")
Mike Stroyan938c2532015-04-03 13:58:35 -0600400 body.append("{")
401 body.append(generate_get_proc_addr_check("name"))
402 body.append("")
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600403 body.append(" name += 2;")
Mike Stroyan938c2532015-04-03 13:58:35 -0600404 body.append(" %s" % "\n ".join(lookups))
405 body.append("")
406 body.append(" return NULL;")
407 body.append("}")
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600408 # add layer_intercept_instance_proc
409 lookups = []
410 for proto in self.protos:
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600411 if not proto_is_global(proto):
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600412 continue
413
414 if not proto in intercepted:
415 continue
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600416 if proto.name == "CreateDevice":
417 continue
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600418 lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600419 lookups.append(" return (PFN_vkVoidFunction) %s%s;" % (prefix, proto.name))
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600420
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600421 body.append("static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name)")
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600422 body.append("{")
423 body.append(generate_get_proc_addr_check("name"))
424 body.append("")
425 body.append(" name += 2;")
426 body.append(" %s" % "\n ".join(lookups))
427 body.append("")
428 body.append(" return NULL;")
429 body.append("}")
430
Mike Stroyan938c2532015-04-03 13:58:35 -0600431 funcs.append("\n".join(body))
Mike Stroyan938c2532015-04-03 13:58:35 -0600432 return "\n\n".join(funcs)
433
Tobin Ehlisca915872014-11-18 11:28:33 -0700434 def _generate_extensions(self):
435 exts = []
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600436 exts.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600437 exts.append(self._gen_create_msg_callback())
438 exts.append(self._gen_destroy_msg_callback())
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700439 exts.append(self._gen_debug_report_msg())
Tobin Ehlisb870cbb2015-04-15 07:46:12 -0600440 return "\n".join(exts)
441
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600442 def _generate_layer_gpa_function(self, extensions=[], instance_extensions=[]):
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600443 func_body = []
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600444#
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -0600445# New style of GPA Functions for the new layer_data/layer_logging changes
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600446#
Mike Stroyan313f7e62015-08-10 16:42:53 -0600447 if self.layer_name == 'ObjectTracker' or self.layer_name == 'Threading':
Chia-I Wu9ab61502015-11-06 06:42:02 +0800448 func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600449 "{\n"
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600450 " PFN_vkVoidFunction addr;\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600451 " if (device == VK_NULL_HANDLE) {\n"
452 " return NULL;\n"
453 " }\n"
454 " /* loader uses this to force layer initialization; device object is wrapped */\n"
455 " if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n"
456 " initDeviceTable(%s_device_table_map, (const VkBaseLayerObject *) device);\n"
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600457 " return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600458 " }\n\n"
459 " addr = layer_intercept_proc(funcName);\n"
460 " if (addr)\n"
461 " return addr;" % self.layer_name)
462 if 0 != len(extensions):
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -0600463 func_body.append('%s' % self.lineinfo.get())
464 func_body.append(' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);')
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600465 for (ext_enable, ext_list) in extensions:
466 extra_space = ""
467 if 0 != len(ext_enable):
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -0600468 func_body.append(' if (my_device_data->%s) {' % ext_enable)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600469 extra_space = " "
470 for ext_name in ext_list:
471 func_body.append(' %sif (!strcmp("%s", funcName))\n'
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600472 ' %sreturn reinterpret_cast<PFN_vkVoidFunction>(%s);' % (extra_space, ext_name, extra_space, ext_name))
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600473 if 0 != len(ext_enable):
474 func_body.append(' }\n')
475 func_body.append("\n if (get_dispatch_table(%s_device_table_map, device)->GetDeviceProcAddr == NULL)\n"
476 " return NULL;\n"
477 " return get_dispatch_table(%s_device_table_map, device)->GetDeviceProcAddr(device, funcName);\n"
478 "}\n" % (self.layer_name, self.layer_name))
Chia-I Wu9ab61502015-11-06 06:42:02 +0800479 func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600480 "{\n"
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600481 " PFN_vkVoidFunction addr;\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600482 " if (instance == VK_NULL_HANDLE) {\n"
483 " return NULL;\n"
484 " }\n"
485 " /* loader uses this to force layer initialization; instance object is wrapped */\n"
486 " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n"
487 " initInstanceTable(%s_instance_table_map, (const VkBaseLayerObject *) instance);\n"
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600488 " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600489 " }\n\n"
490 " addr = layer_intercept_instance_proc(funcName);\n"
491 " if (addr) {\n"
492 " return addr;"
493 " }\n" % self.layer_name)
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600494
Jon Ashburn3dc39382015-09-17 10:00:32 -0600495 table_declared = False
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600496 if 0 != len(instance_extensions):
Jon Ashburn3dc39382015-09-17 10:00:32 -0600497 for (ext_enable, ext_list) in instance_extensions:
498 extra_space = ""
499 if 0 != len(ext_enable):
500 if ext_enable == 'msg_callback_get_proc_addr':
501 func_body.append(" layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600502 " addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);\n"
503 " if (addr) {\n"
504 " return addr;\n"
Jon Ashburn3dc39382015-09-17 10:00:32 -0600505 " }\n")
506 else:
507 if table_declared == False:
508 func_body.append(" VkLayerInstanceDispatchTable* pTable = get_dispatch_table(%s_instance_table_map, instance);" % self.layer_name)
509 table_declared = True
510 func_body.append(' if (instanceExtMap.size() != 0 && instanceExtMap[pTable].%s)' % ext_enable)
511 func_body.append(' {')
512 extra_space = " "
513 for ext_name in ext_list:
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700514 if wsi_name(ext_name):
515 func_body.append('%s' % wsi_ifdef(ext_name))
Jon Ashburn3dc39382015-09-17 10:00:32 -0600516 func_body.append(' %sif (!strcmp("%s", funcName))\n'
517 ' return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (extra_space, ext_name, ext_name))
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700518 if wsi_name(ext_name):
519 func_body.append('%s' % wsi_endif(ext_name))
Jon Ashburn3dc39382015-09-17 10:00:32 -0600520 if 0 != len(ext_enable):
521 func_body.append(' }\n')
522
523 func_body.append(" if (get_dispatch_table(%s_instance_table_map, instance)->GetInstanceProcAddr == NULL) {\n"
524 " return NULL;\n"
525 " }\n"
526 " return get_dispatch_table(%s_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);\n"
527 "}\n" % (self.layer_name, self.layer_name))
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600528 return "\n".join(func_body)
529 else:
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600530 func_body.append('%s' % self.lineinfo.get())
Chia-I Wu9ab61502015-11-06 06:42:02 +0800531 func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600532 "{\n"
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600533 " PFN_vkVoidFunction addr;\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600534 " if (device == VK_NULL_HANDLE) {\n"
535 " return NULL;\n"
Jon Ashburn3a278b72015-10-06 17:05:21 -0600536 " }\n")
537 if self.layer_name == 'Generic':
538 func_body.append("\n"
539 " /* loader uses this to force layer initialization; device object is wrapped */\n"
540 " if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n"
541 " initDeviceTable((const VkBaseLayerObject *) device);\n"
542 " return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n"
543 " }\n\n"
544 " addr = layer_intercept_proc(funcName);\n"
545 " if (addr)\n"
546 " return addr;")
547 else:
548 func_body.append("\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600549 " loader_platform_thread_once(&initOnce, init%s);\n\n"
550 " /* loader uses this to force layer initialization; device object is wrapped */\n"
551 " if (!strcmp(\"vkGetDeviceProcAddr\", funcName)) {\n"
552 " initDeviceTable((const VkBaseLayerObject *) device);\n"
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600553 " return (PFN_vkVoidFunction) vkGetDeviceProcAddr;\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600554 " }\n\n"
555 " addr = layer_intercept_proc(funcName);\n"
556 " if (addr)\n"
557 " return addr;" % self.layer_name)
558 func_body.append('')
559 func_body.append(' VkLayerDispatchTable *pDisp = device_dispatch_table(device);')
560 if 0 != len(extensions):
561 extra_space = ""
562 for (ext_enable, ext_list) in extensions:
563 if 0 != len(ext_enable):
Jon Ashburn8acd2332015-09-16 18:08:32 -0600564 func_body.append(' if (deviceExtMap.size() != 0 && deviceExtMap[pDisp].%s)' % ext_enable)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600565 func_body.append(' {')
566 extra_space = " "
567 for ext_name in ext_list:
568 func_body.append(' %sif (!strcmp("%s", funcName))\n'
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600569 ' return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (extra_space, ext_name, ext_name))
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600570 if 0 != len(ext_enable):
571 func_body.append(' }')
572 func_body.append('%s' % self.lineinfo.get())
573 func_body.append(" {\n"
574 " if (pDisp->GetDeviceProcAddr == NULL)\n"
575 " return NULL;\n"
576 " return pDisp->GetDeviceProcAddr(device, funcName);\n"
577 " }\n"
578 "}\n")
Jon Ashburn3dc39382015-09-17 10:00:32 -0600579 func_body.append('%s' % self.lineinfo.get())
Chia-I Wu9ab61502015-11-06 06:42:02 +0800580 func_body.append("VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600581 "{\n"
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600582 " PFN_vkVoidFunction addr;\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600583 " if (instance == VK_NULL_HANDLE) {\n"
584 " return NULL;\n"
Jon Ashburn3a278b72015-10-06 17:05:21 -0600585 " }\n")
586 if self.layer_name == 'Generic':
587 func_body.append("\n"
588 " /* loader uses this to force layer initialization; instance object is wrapped */\n"
589 " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n"
590 " initInstanceTable((const VkBaseLayerObject *) instance);\n"
591 " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n"
592 " }\n\n"
593 " addr = layer_intercept_instance_proc(funcName);\n"
594 " if (addr)\n"
595 " return addr;")
596 else:
597 func_body.append(
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600598 " loader_platform_thread_once(&initOnce, init%s);\n\n"
599 " /* loader uses this to force layer initialization; instance object is wrapped */\n"
600 " if (!strcmp(\"vkGetInstanceProcAddr\", funcName)) {\n"
601 " initInstanceTable((const VkBaseLayerObject *) instance);\n"
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -0600602 " return (PFN_vkVoidFunction) vkGetInstanceProcAddr;\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600603 " }\n\n"
604 " addr = layer_intercept_instance_proc(funcName);\n"
605 " if (addr)\n"
606 " return addr;" % self.layer_name)
Jon Ashburn3dc39382015-09-17 10:00:32 -0600607 func_body.append("")
608 func_body.append(" VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);")
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600609 if 0 != len(instance_extensions):
Jon Ashburn3dc39382015-09-17 10:00:32 -0600610 extra_space = ""
611 for (ext_enable, ext_list) in instance_extensions:
612 if 0 != len(ext_enable):
Jon Ashburn3a278b72015-10-06 17:05:21 -0600613 if ext_enable == 'msg_callback_get_proc_addr':
614 func_body.append(" layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);\n"
615 " addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);\n"
616 " if (addr) {\n"
617 " return addr;\n"
618 " }\n")
619 else:
620 func_body.append(' if (instanceExtMap.size() != 0 && instanceExtMap[pTable].%s)' % ext_enable)
621 func_body.append(' {')
622 extra_space = " "
623 for ext_name in ext_list:
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700624 if wsi_name(ext_name):
625 func_body.append('%s' % wsi_ifdef(ext_name))
Jon Ashburn3a278b72015-10-06 17:05:21 -0600626 func_body.append(' %sif (!strcmp("%s", funcName))\n'
Jon Ashburn3dc39382015-09-17 10:00:32 -0600627 ' return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (extra_space, ext_name, ext_name))
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700628 if wsi_name(ext_name):
629 func_body.append('%s' % wsi_endif(ext_name))
Jon Ashburn3a278b72015-10-06 17:05:21 -0600630 if 0 != len(ext_enable):
631 func_body.append(' }\n')
Jon Ashburn3dc39382015-09-17 10:00:32 -0600632
633 func_body.append(" if (pTable->GetInstanceProcAddr == NULL)\n"
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600634 " return NULL;\n"
635 " return pTable->GetInstanceProcAddr(instance, funcName);\n"
636 "}\n")
637 return "\n".join(func_body)
Jon Ashburnf6b33db2015-05-05 14:22:52 -0600638
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600639
Mike Stroyaned238bb2015-05-15 08:50:57 -0600640 def _generate_layer_initialization(self, init_opts=False, prefix='vk', lockname=None, condname=None):
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600641 func_body = ["#include \"vk_dispatch_table_helper.h\""]
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600642 func_body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700643 func_body.append('static void init%s(layer_data *my_data, const VkAllocationCallbacks *pAllocator)\n'
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -0600644 '{\n' % self.layer_name)
Jon Ashburnd6badbc2015-02-16 08:26:50 -0700645 if init_opts:
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600646 func_body.append('%s' % self.lineinfo.get())
Jon Ashburn3a278b72015-10-06 17:05:21 -0600647 func_body.append(' uint32_t report_flags = 0;')
648 func_body.append(' uint32_t debug_action = 0;')
649 func_body.append(' FILE *log_output = NULL;')
650 func_body.append(' const char *option_str;\n')
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -0600651 func_body.append(' // initialize %s options' % self.layer_name)
Jon Ashburn3a278b72015-10-06 17:05:21 -0600652 func_body.append(' report_flags = getLayerOptionFlags("%sReportFlags", 0);' % self.layer_name)
653 func_body.append(' getLayerOptionEnum("%sDebugAction", (uint32_t *) &debug_action);' % self.layer_name)
Jon Ashburnd6badbc2015-02-16 08:26:50 -0700654 func_body.append('')
Jon Ashburn3a278b72015-10-06 17:05:21 -0600655 func_body.append(' if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)')
Jon Ashburnd6badbc2015-02-16 08:26:50 -0700656 func_body.append(' {')
Jon Ashburn3a278b72015-10-06 17:05:21 -0600657 func_body.append(' option_str = getLayerOption("%sLogFilename");' % self.layer_name)
658 func_body.append(' log_output = getLayerLogOutput(option_str,"%s");' % self.layer_name)
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700659 func_body.append(' VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;')
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700660 func_body.append(' memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700661 func_body.append(' dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;')
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700662 func_body.append(' dbgCreateInfo.flags = report_flags;')
663 func_body.append(' dbgCreateInfo.pfnCallback = log_callback;')
664 func_body.append(' dbgCreateInfo.pUserData = NULL;')
665 func_body.append(' layer_create_msg_callback(my_data->report_data, &dbgCreateInfo, pAllocator,')
Jon Ashburn3a278b72015-10-06 17:05:21 -0600666 func_body.append(' &my_data->logging_callback);')
Jon Ashburnd6badbc2015-02-16 08:26:50 -0700667 func_body.append(' }')
668 func_body.append('')
Tobin Ehlis36f1b462015-02-23 14:09:16 -0700669 if lockname is not None:
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600670 func_body.append('%s' % self.lineinfo.get())
Tobin Ehlis36f1b462015-02-23 14:09:16 -0700671 func_body.append(" if (!%sLockInitialized)" % lockname)
672 func_body.append(" {")
673 func_body.append(" // TODO/TBD: Need to delete this mutex sometime. How???")
674 func_body.append(" loader_platform_thread_create_mutex(&%sLock);" % lockname)
Mike Stroyaned238bb2015-05-15 08:50:57 -0600675 if condname is not None:
676 func_body.append(" loader_platform_thread_init_cond(&%sCond);" % condname)
Tobin Ehlis36f1b462015-02-23 14:09:16 -0700677 func_body.append(" %sLockInitialized = 1;" % lockname)
678 func_body.append(" }")
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600679 func_body.append("}\n")
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600680 func_body.append('')
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600681 return "\n".join(func_body)
682
Mike Stroyan313f7e62015-08-10 16:42:53 -0600683 def _generate_new_layer_initialization(self, init_opts=False, prefix='vk', lockname=None, condname=None):
684 func_body = ["#include \"vk_dispatch_table_helper.h\""]
685 func_body.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700686 func_body.append('static void init%s(layer_data *my_data, const VkAllocationCallbacks *pAllocator)\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -0600687 '{\n' % self.layer_name)
688 if init_opts:
689 func_body.append('%s' % self.lineinfo.get())
690 func_body.append(' uint32_t report_flags = 0;')
691 func_body.append(' uint32_t debug_action = 0;')
692 func_body.append(' FILE *log_output = NULL;')
693 func_body.append(' const char *strOpt;')
694 func_body.append(' // initialize %s options' % self.layer_name)
695 func_body.append(' report_flags = getLayerOptionFlags("%sReportFlags", 0);' % self.layer_name)
Jon Ashburn9ff6ae92015-10-06 17:20:01 -0600696 func_body.append(' getLayerOptionEnum("%sDebugAction", (uint32_t *) &debug_action);' % self.layer_name)
Mike Stroyan313f7e62015-08-10 16:42:53 -0600697 func_body.append('')
698 func_body.append(' if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)')
699 func_body.append(' {')
700 func_body.append(' strOpt = getLayerOption("%sLogFilename");' % self.layer_name)
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600701 func_body.append(' log_output = getLayerLogOutput(strOpt, "%s");' % self.layer_name)
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700702 func_body.append(' VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;')
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700703 func_body.append(' memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700704 func_body.append(' dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;')
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700705 func_body.append(' dbgCreateInfo.flags = report_flags;')
706 func_body.append(' dbgCreateInfo.pfnCallback = log_callback;')
707 func_body.append(' dbgCreateInfo.pUserData = log_output;')
708 func_body.append(' layer_create_msg_callback(my_data->report_data, &dbgCreateInfo, pAllocator,')
709 func_body.append(' &my_data->logging_callback);')
Mike Stroyan313f7e62015-08-10 16:42:53 -0600710 func_body.append(' }')
711 func_body.append('')
712 if lockname is not None:
713 func_body.append('%s' % self.lineinfo.get())
714 func_body.append(" if (!%sLockInitialized)" % lockname)
715 func_body.append(" {")
716 func_body.append(" // TODO/TBD: Need to delete this mutex sometime. How???")
717 func_body.append(" loader_platform_thread_create_mutex(&%sLock);" % lockname)
718 if condname is not None:
719 func_body.append(" loader_platform_thread_init_cond(&%sCond);" % condname)
720 func_body.append(" %sLockInitialized = 1;" % lockname)
721 func_body.append(" }")
722 func_body.append("}\n")
723 func_body.append('')
724 return "\n".join(func_body)
725
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600726class LayerFuncsSubcommand(Subcommand):
727 def generate_header(self):
David Pinedo9316d3b2015-11-06 12:54:48 -0700728 return '#include <vulkan/vk_layer.h>\n#include "loader.h"'
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600729
730 def generate_body(self):
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -0600731 return self._generate_dispatch_entrypoints("static")
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600732
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600733class GenericLayerSubcommand(Subcommand):
734 def generate_header(self):
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500735 gen_header = []
Courtney Goeltzenleuchter79a5a962015-07-07 17:51:45 -0600736 gen_header.append('%s' % self.lineinfo.get())
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500737 gen_header.append('#include <stdio.h>')
738 gen_header.append('#include <stdlib.h>')
739 gen_header.append('#include <string.h>')
740 gen_header.append('#include <unordered_map>')
Tobin Ehlisb835d1b2015-07-03 10:34:49 -0600741 gen_header.append('#include "vk_loader_platform.h"')
David Pinedo9316d3b2015-11-06 12:54:48 -0700742 gen_header.append('#include "vulkan/vk_layer.h"')
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -0600743 gen_header.append('#include "vk_layer_config.h"')
Jon Ashburn3a278b72015-10-06 17:05:21 -0600744 gen_header.append('#include "vk_layer_logging.h"')
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -0600745 gen_header.append('#include "vk_layer_table.h"')
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -0600746 gen_header.append('#include "vk_layer_extension_utils.h"')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500747 gen_header.append('')
Courtney Goeltzenleuchter79a5a962015-07-07 17:51:45 -0600748 gen_header.append('#include "generic.h"')
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600749 gen_header.append('')
Tobin Ehlisa30e7e52015-07-06 14:02:36 -0600750 gen_header.append('%s' % self.lineinfo.get())
751 gen_header.append('#define LAYER_EXT_ARRAY_SIZE 1')
752 gen_header.append('#define LAYER_DEV_EXT_ARRAY_SIZE 1')
Jon Ashburn3a278b72015-10-06 17:05:21 -0600753 gen_header.append('//static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
754 gen_header.append('static std::unordered_map<void *, layer_data *> layer_data_map;\n')
755 gen_header.append('template layer_data *get_my_data_ptr<layer_data>(')
756 gen_header.append(' void *data_key,')
757 gen_header.append(' std::unordered_map<void *, layer_data *> &data_map);\n')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500758 gen_header.append('')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500759 return "\n".join(gen_header)
Tobin Ehlis7a314ea2015-07-07 11:02:44 -0600760
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -0600761 def generate_intercept(self, proto, qual):
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -0600762 if proto.name in [ 'EnumerateInstanceLayerProperties', 'EnumerateInstanceExtensionProperties', 'EnumerateDeviceLayerProperties', 'EnumerateDeviceExtensionProperties' ]:
Mike Stroyan00087e62015-04-03 14:39:16 -0600763 # use default version
764 return None
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600765 decl = proto.c_func(prefix="vk", attr="VKAPI")
Mike Stroyan938c2532015-04-03 13:58:35 -0600766 ret_val = ''
767 stmt = ''
768 funcs = []
Jon Ashburn71836d92015-05-12 17:23:55 -0600769 table = ''
Jon Ashburn95a77ba2015-05-15 15:09:35 -0600770 if proto_is_global(proto):
Jon Ashburn71836d92015-05-12 17:23:55 -0600771 table = 'Instance'
Mike Stroyan938c2532015-04-03 13:58:35 -0600772 if proto.ret != "void":
Courtney Goeltzenleuchter0de9e212015-06-26 15:07:53 -0600773 funcs.append('%s' % self.lineinfo.get())
Jon Ashburnb0fbe912015-05-06 10:15:07 -0600774 ret_val = "%s result = " % proto.ret
Mike Stroyan938c2532015-04-03 13:58:35 -0600775 stmt = " return result;\n"
Jon Ashburn8ced4212015-05-22 12:01:50 -0600776 if proto.name == "CreateDevice":
Courtney Goeltzenleuchter0de9e212015-06-26 15:07:53 -0600777 funcs.append('%s' % self.lineinfo.get())
Mike Stroyan938c2532015-04-03 13:58:35 -0600778 funcs.append('%s%s\n'
779 '{\n'
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500780 ' char str[1024];\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600781 ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);\n'
782 ' sprintf(str, "At start of Generic layered %s\\n");\n'
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700783 ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,'
Michael Lentine010f4692015-11-03 16:19:46 -0800784 ' (uint64_t)physicalDevice, 0, 0, (char *) "Generic", "%%s", (char *) str);\n'
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600785 ' %sdevice_dispatch_table(*pDevice)->%s;\n'
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600786 ' if (result == VK_SUCCESS) {\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600787 ' my_data->report_data = layer_debug_report_create_device(my_data->report_data, *pDevice);\n'
Jon Ashburn747f2b62015-06-18 15:02:58 -0600788 ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n'
Mike Stroyan938c2532015-04-03 13:58:35 -0600789 ' }\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600790 ' sprintf(str, "Completed Generic layered %s\\n");\n'
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700791 ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, (uint64_t)physicalDevice, 0, 0, (char *) "Generic", "%%s", (char *) str);\n'
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500792 ' %s'
793 '}' % (qual, decl, proto.name, ret_val, proto.c_call(), proto.name, stmt))
794 elif proto.name == "DestroyDevice":
Courtney Goeltzenleuchter0de9e212015-06-26 15:07:53 -0600795 funcs.append('%s' % self.lineinfo.get())
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500796 funcs.append('%s%s\n'
797 '{\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -0600798 ' dispatch_key key = get_dispatch_key(device);\n'
Jon Ashburn747f2b62015-06-18 15:02:58 -0600799 ' VkLayerDispatchTable *pDisp = device_dispatch_table(device);\n'
Chia-I Wuf7458c52015-10-26 21:10:41 +0800800 ' pDisp->DestroyDevice(device, pAllocator);\n'
Jon Ashburn747f2b62015-06-18 15:02:58 -0600801 ' deviceExtMap.erase(pDisp);\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -0600802 ' destroy_device_dispatch_table(key);\n'
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500803 '}\n' % (qual, decl))
804 elif proto.name == "DestroyInstance":
Courtney Goeltzenleuchter0de9e212015-06-26 15:07:53 -0600805 funcs.append('%s' % self.lineinfo.get())
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500806 funcs.append('%s%s\n'
807 '{\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -0600808 ' dispatch_key key = get_dispatch_key(instance);\n'
Jon Ashburn3dc39382015-09-17 10:00:32 -0600809 ' VkLayerInstanceDispatchTable *pDisp = instance_dispatch_table(instance);\n'
Chia-I Wuf7458c52015-10-26 21:10:41 +0800810 ' pDisp->DestroyInstance(instance, pAllocator);\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600811 ' // Clean up logging callback, if any\n'
812 ' layer_data *my_data = get_my_data_ptr(key, layer_data_map);\n'
813 ' if (my_data->logging_callback) {\n'
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700814 ' layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback, pAllocator);\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600815 ' }\n\n'
816 ' layer_debug_report_destroy_instance(my_data->report_data);\n'
817 ' layer_data_map.erase(key);\n'
Jon Ashburn3dc39382015-09-17 10:00:32 -0600818 ' instanceExtMap.erase(pDisp);\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -0600819 ' destroy_instance_dispatch_table(key);\n'
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500820 '}\n' % (qual, decl))
Jon Ashburn3dc39382015-09-17 10:00:32 -0600821 elif proto.name == "CreateInstance":
Courtney Goeltzenleuchter0de9e212015-06-26 15:07:53 -0600822 funcs.append('%s' % self.lineinfo.get())
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500823 # CreateInstance needs to use the second parm instead of the first to set the correct dispatch table
Jon Ashburn3dc39382015-09-17 10:00:32 -0600824 funcs.append('%s%s\n'
825 '{\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600826 ' char str[1024];\n'
Jon Ashburn3dc39382015-09-17 10:00:32 -0600827 ' %sinstance_dispatch_table(*pInstance)->%s;\n'
828 ' if (result == VK_SUCCESS) {\n'
829 ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600830 ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n'
831 ' my_data->report_data = debug_report_create_instance(\n'
832 ' instance_dispatch_table(*pInstance),\n'
833 ' *pInstance,\n'
Chia-I Wud50a7d72015-10-26 20:48:51 +0800834 ' pCreateInfo->enabledExtensionNameCount,\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600835 ' pCreateInfo->ppEnabledExtensionNames);\n'
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700836 ' initGeneric(my_data, pAllocator);\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600837 ' sprintf(str, "Completed Generic layered %s\\n");\n'
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700838 ' log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, (uint64_t)*pInstance, 0, 0, (char *) "Generic", "%%s", (char *) str);\n'
Jon Ashburn3dc39382015-09-17 10:00:32 -0600839 ' }\n'
Tobin Ehlis1350a362015-09-17 16:27:04 -0600840 ' return result;\n'
Jon Ashburn3a278b72015-10-06 17:05:21 -0600841 '}\n' % (qual, decl, ret_val, proto.c_call(), proto.name))
Jon Ashburn3dc39382015-09-17 10:00:32 -0600842 else:
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700843 if wsi_name(proto.name):
844 funcs.append('%s' % wsi_ifdef(proto.name))
Jon Ashburn3dc39382015-09-17 10:00:32 -0600845 funcs.append('%s' % self.lineinfo.get())
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500846 dispatch_param = proto.params[0].name
847 # Must use 'instance' table for these APIs, 'device' table otherwise
848 table_type = ""
849 if proto_is_global(proto):
850 table_type = "instance"
851 else:
852 table_type = "device"
Mike Stroyan938c2532015-04-03 13:58:35 -0600853 funcs.append('%s%s\n'
854 '{\n'
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500855 ' %s%s_dispatch_table(%s)->%s;\n'
Mike Stroyan938c2532015-04-03 13:58:35 -0600856 '%s'
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -0500857 '}' % (qual, decl, ret_val, table_type, dispatch_param, proto.c_call(), stmt))
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700858 if wsi_name(proto.name):
859 funcs.append('%s' % wsi_endif(proto.name))
Mike Stroyan938c2532015-04-03 13:58:35 -0600860 return "\n\n".join(funcs)
861
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600862 def generate_body(self):
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -0600863 self.layer_name = "Generic"
Jon Ashburn3a278b72015-10-06 17:05:21 -0600864 instance_extensions=[('msg_callback_get_proc_addr', []),
865 ('wsi_enabled',
Ian Elliott05846062015-11-20 14:13:17 -0700866 ['vkGetPhysicalDeviceSurfaceSupportKHR',
867 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
868 'vkGetPhysicalDeviceSurfaceFormatsKHR',
869 'vkGetPhysicalDeviceSurfacePresentModesKHR'])]
Ian Elliott1064fe32015-07-06 14:31:32 -0600870 extensions=[('wsi_enabled',
Ian Elliott05846062015-11-20 14:13:17 -0700871 ['vkCreateSwapchainKHR',
Jon Ashburn8acd2332015-09-16 18:08:32 -0600872 'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
873 'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -0600874 body = [self._generate_layer_initialization(True),
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600875 self._generate_dispatch_entrypoints("VK_LAYER_EXPORT"),
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600876 self._gen_create_msg_callback(),
877 self._gen_destroy_msg_callback(),
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -0700878 self._gen_debug_report_msg(),
Jon Ashburn3dc39382015-09-17 10:00:32 -0600879 self._generate_layer_gpa_function(extensions, instance_extensions)]
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600880
881 return "\n\n".join(body)
882
Tobin Ehlise78dbd82015-04-09 09:19:36 -0600883class APIDumpSubcommand(Subcommand):
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600884 def generate_header(self):
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700885 header_txt = []
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600886 header_txt.append('%s' % self.lineinfo.get())
Tobin Ehlise78dbd82015-04-09 09:19:36 -0600887 header_txt.append('#include <fstream>')
888 header_txt.append('#include <iostream>')
889 header_txt.append('#include <string>')
Jon Ashburn747f2b62015-06-18 15:02:58 -0600890 header_txt.append('#include <string.h>')
Tobin Ehlise78dbd82015-04-09 09:19:36 -0600891 header_txt.append('')
Tobin Ehlis80d048e2015-08-28 09:57:53 -0600892 header_txt.append('#include "vk_loader_platform.h"')
David Pinedo9316d3b2015-11-06 12:54:48 -0700893 header_txt.append('#include "vulkan/vk_layer.h"')
Tobin Ehlis80d048e2015-08-28 09:57:53 -0600894 header_txt.append('#include "vk_struct_string_helper_cpp.h"')
895 header_txt.append('#include "vk_layer_table.h"')
896 header_txt.append('#include "vk_layer_extension_utils.h"')
897 header_txt.append('#include <unordered_map>')
Jon Ashburn6785fe72015-09-17 15:28:12 -0600898 header_txt.append('#include "apidump.h"')
Tobin Ehlis80d048e2015-08-28 09:57:53 -0600899 header_txt.append('')
Tobin Ehlise78dbd82015-04-09 09:19:36 -0600900 header_txt.append('static std::ofstream fileStream;')
901 header_txt.append('static std::string fileName = "vk_apidump.txt";')
902 header_txt.append('std::ostream* outputStream = NULL;')
903 header_txt.append('void ConfigureOutputStream(bool writeToFile, bool flushAfterWrite)')
904 header_txt.append('{')
905 header_txt.append(' if(writeToFile)')
906 header_txt.append(' {')
Tobin Ehlis93245a92015-09-18 14:32:12 -0600907 header_txt.append(' if (fileName == "stdout")')
908 header_txt.append(' {')
Tobin Ehlis80d048e2015-08-28 09:57:53 -0600909 header_txt.append(' outputStream = &std::cout;')
Tobin Ehlis93245a92015-09-18 14:32:12 -0600910 header_txt.append(' (*outputStream) << endl << "APIDump output filename \'stdout\' specified. Writing to STDOUT instead of a file." << endl << endl;')
911 header_txt.append(' } else {')
912 header_txt.append(' fileStream.open(fileName);')
913 header_txt.append(' if ((fileStream.rdstate() & fileStream.failbit) != 0) {')
914 header_txt.append(' outputStream = &std::cout;')
915 header_txt.append(' (*outputStream) << endl << "APIDump ERROR: Bad output filename specified: " << fileName << ". Writing to STDOUT instead" << endl << endl;')
916 header_txt.append(' }')
917 header_txt.append(' else')
918 header_txt.append(' outputStream = &fileStream;')
Tobin Ehlis80d048e2015-08-28 09:57:53 -0600919 header_txt.append(' }')
Tobin Ehlise78dbd82015-04-09 09:19:36 -0600920 header_txt.append(' }')
921 header_txt.append(' else')
922 header_txt.append(' {')
923 header_txt.append(' outputStream = &std::cout;')
924 header_txt.append(' }')
925 header_txt.append('')
926 header_txt.append(' if(flushAfterWrite)')
927 header_txt.append(' {')
928 header_txt.append(' outputStream->sync_with_stdio(true);')
929 header_txt.append(' }')
930 header_txt.append(' else')
931 header_txt.append(' {')
932 header_txt.append(' outputStream->sync_with_stdio(false);')
933 header_txt.append(' }')
934 header_txt.append('}')
935 header_txt.append('')
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600936 header_txt.append('%s' % self.lineinfo.get())
Jon Ashburnbacb0f52015-04-06 10:58:22 -0600937 header_txt.append('static VkBaseLayerObject *pCurObj;')
Tobin Ehlisa2b199c2015-04-27 17:30:04 -0600938 header_txt.append('static bool g_APIDumpDetailed = true;')
Tobin Ehlise78dbd82015-04-09 09:19:36 -0600939 header_txt.append('')
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -0600940 header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -0500941 header_txt.append('')
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700942 header_txt.append('static int printLockInitialized = 0;')
Tobin Ehlise78dbd82015-04-09 09:19:36 -0600943 header_txt.append('static loader_platform_thread_mutex printLock;')
944 header_txt.append('')
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600945 header_txt.append('%s' % self.lineinfo.get())
Tobin Ehlisa30e7e52015-07-06 14:02:36 -0600946 header_txt.append('#define LAYER_EXT_ARRAY_SIZE 1')
947 header_txt.append('#define LAYER_DEV_EXT_ARRAY_SIZE 1')
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700948 header_txt.append('#define MAX_TID 513')
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700949 header_txt.append('static loader_platform_thread_id tidMapping[MAX_TID] = {0};')
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700950 header_txt.append('static uint32_t maxTID = 0;')
951 header_txt.append('// Map actual TID to an index value and return that index')
952 header_txt.append('// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs')
953 header_txt.append('static uint32_t getTIDIndex() {')
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700954 header_txt.append(' loader_platform_thread_id tid = loader_platform_get_thread_id();')
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700955 header_txt.append(' for (uint32_t i = 0; i < maxTID; i++) {')
956 header_txt.append(' if (tid == tidMapping[i])')
957 header_txt.append(' return i;')
958 header_txt.append(' }')
959 header_txt.append(" // Don't yet have mapping, set it and return newly set index")
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700960 header_txt.append(' uint32_t retVal = (uint32_t) maxTID;')
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700961 header_txt.append(' tidMapping[maxTID++] = tid;')
962 header_txt.append(' assert(maxTID < MAX_TID);')
963 header_txt.append(' return retVal;')
964 header_txt.append('}')
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -0500965 header_txt.append('')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800966 header_txt.append('void interpret_memBarriers(const void* const* ppMemoryBarriers, uint32_t memoryBarrierCount)')
Mark Lobodzinskib9143d82015-07-30 10:11:32 -0600967 header_txt.append('{')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800968 header_txt.append(' if (ppMemoryBarriers) {')
Mark Lobodzinskib9143d82015-07-30 10:11:32 -0600969 header_txt.append(' string tmp_str;')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800970 header_txt.append(' for (uint32_t i = 0; i < memoryBarrierCount; i++) {')
971 header_txt.append(' switch(*(VkStructureType*)ppMemoryBarriers[i])')
Mark Lobodzinskib9143d82015-07-30 10:11:32 -0600972 header_txt.append(' {')
973 header_txt.append(' case VK_STRUCTURE_TYPE_MEMORY_BARRIER:')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800974 header_txt.append(' tmp_str = vk_print_vkmemorybarrier((VkMemoryBarrier*)ppMemoryBarriers[i], " ");')
Mark Lobodzinskib9143d82015-07-30 10:11:32 -0600975 header_txt.append(' break;')
976 header_txt.append(' case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER:')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800977 header_txt.append(' tmp_str = vk_print_vkbuffermemorybarrier((VkBufferMemoryBarrier*)ppMemoryBarriers[i], " ");')
Mark Lobodzinskib9143d82015-07-30 10:11:32 -0600978 header_txt.append(' break;')
979 header_txt.append(' case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER:')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800980 header_txt.append(' tmp_str = vk_print_vkimagememorybarrier((VkImageMemoryBarrier*)ppMemoryBarriers[i], " ");')
Mark Lobodzinskib9143d82015-07-30 10:11:32 -0600981 header_txt.append(' break;')
982 header_txt.append(' default:')
983 header_txt.append(' break;')
984 header_txt.append(' }')
985 header_txt.append('')
986 header_txt.append(' if (StreamControl::writeAddress == true) {')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800987 header_txt.append(' (*outputStream) << " ppMemoryBarriers[" << i << "] (" << &ppMemoryBarriers[i] << ")" << endl << tmp_str << endl;')
Mark Lobodzinskib9143d82015-07-30 10:11:32 -0600988 header_txt.append(' } else {')
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800989 header_txt.append(' (*outputStream) << " ppMemoryBarriers[" << i << "] (address)" << endl << " address" << endl;')
Mark Lobodzinskib9143d82015-07-30 10:11:32 -0600990 header_txt.append(' }')
991 header_txt.append(' }')
992 header_txt.append(' }')
993 header_txt.append('}')
994 header_txt.append('')
Tobin Ehlisd009bae2014-11-24 15:46:55 -0700995 return "\n".join(header_txt)
Tobin Ehlis12076fc2014-10-22 09:06:33 -0600996
Tobin Ehlise78dbd82015-04-09 09:19:36 -0600997 def generate_init(self):
998 func_body = []
Tobin Ehlis08fafd02015-06-12 12:49:01 -0600999 func_body.append('%s' % self.lineinfo.get())
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001000 func_body.append('#include "vk_dispatch_table_helper.h"')
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -06001001 func_body.append('#include "vk_layer_config.h"')
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001002 func_body.append('')
1003 func_body.append('static void init%s(void)' % self.layer_name)
1004 func_body.append('{')
1005 func_body.append(' using namespace StreamControl;')
1006 func_body.append('')
Tobin Ehlisa8700972015-08-26 16:18:52 -06001007 func_body.append(' char const*const logName = getLayerOption("APIDumpLogFilename");')
1008 func_body.append(' if(logName != NULL)')
1009 func_body.append(' {')
1010 func_body.append(' fileName = logName;')
1011 func_body.append(' }')
1012 func_body.append('')
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001013 func_body.append(' char const*const detailedStr = getLayerOption("APIDumpDetailed");')
1014 func_body.append(' if(detailedStr != NULL)')
1015 func_body.append(' {')
1016 func_body.append(' if(strcmp(detailedStr, "TRUE") == 0)')
1017 func_body.append(' {')
1018 func_body.append(' g_APIDumpDetailed = true;')
1019 func_body.append(' }')
1020 func_body.append(' else if(strcmp(detailedStr, "FALSE") == 0)')
1021 func_body.append(' {')
1022 func_body.append(' g_APIDumpDetailed = false;')
1023 func_body.append(' }')
1024 func_body.append(' }')
1025 func_body.append('')
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001026 func_body.append(' char const*const writeToFileStr = getLayerOption("APIDumpFile");')
1027 func_body.append(' bool writeToFile = false;')
1028 func_body.append(' if(writeToFileStr != NULL)')
1029 func_body.append(' {')
1030 func_body.append(' if(strcmp(writeToFileStr, "TRUE") == 0)')
1031 func_body.append(' {')
1032 func_body.append(' writeToFile = true;')
1033 func_body.append(' }')
1034 func_body.append(' else if(strcmp(writeToFileStr, "FALSE") == 0)')
1035 func_body.append(' {')
1036 func_body.append(' writeToFile = false;')
1037 func_body.append(' }')
1038 func_body.append(' }')
1039 func_body.append('')
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001040 func_body.append('%s' % self.lineinfo.get())
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001041 func_body.append(' char const*const noAddrStr = getLayerOption("APIDumpNoAddr");')
1042 func_body.append(' if(noAddrStr != NULL)')
1043 func_body.append(' {')
1044 func_body.append(' if(strcmp(noAddrStr, "FALSE") == 0)')
1045 func_body.append(' {')
1046 func_body.append(' StreamControl::writeAddress = true;')
1047 func_body.append(' }')
1048 func_body.append(' else if(strcmp(noAddrStr, "TRUE") == 0)')
1049 func_body.append(' {')
1050 func_body.append(' StreamControl::writeAddress = false;')
1051 func_body.append(' }')
1052 func_body.append(' }')
1053 func_body.append('')
1054 func_body.append(' char const*const flushAfterWriteStr = getLayerOption("APIDumpFlush");')
1055 func_body.append(' bool flushAfterWrite = false;')
1056 func_body.append(' if(flushAfterWriteStr != NULL)')
1057 func_body.append(' {')
1058 func_body.append(' if(strcmp(flushAfterWriteStr, "TRUE") == 0)')
1059 func_body.append(' {')
1060 func_body.append(' flushAfterWrite = true;')
1061 func_body.append(' }')
1062 func_body.append(' else if(strcmp(flushAfterWriteStr, "FALSE") == 0)')
1063 func_body.append(' {')
1064 func_body.append(' flushAfterWrite = false;')
1065 func_body.append(' }')
1066 func_body.append(' }')
1067 func_body.append('')
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001068 func_body.append('%s' % self.lineinfo.get())
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001069 func_body.append(' ConfigureOutputStream(writeToFile, flushAfterWrite);')
1070 func_body.append('')
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001071 func_body.append(' if (!printLockInitialized)')
1072 func_body.append(' {')
1073 func_body.append(' // TODO/TBD: Need to delete this mutex sometime. How???')
1074 func_body.append(' loader_platform_thread_create_mutex(&printLock);')
1075 func_body.append(' printLockInitialized = 1;')
1076 func_body.append(' }')
1077 func_body.append('}')
1078 func_body.append('')
1079 return "\n".join(func_body)
Tobin Ehlis99f88672015-01-10 12:42:41 -07001080
Mike Stroyanbf237d72015-04-03 17:45:53 -06001081 def generate_intercept(self, proto, qual):
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06001082 if proto.name in [ 'EnumerateInstanceLayerProperties','EnumerateInstanceExtensionProperties','EnumerateDeviceLayerProperties','EnumerateDeviceExtensionProperties']:
Jon Ashburn9fd4cc42015-04-10 14:33:07 -06001083 return None
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001084 decl = proto.c_func(prefix="vk", attr="VKAPI")
Mike Stroyanbf237d72015-04-03 17:45:53 -06001085 ret_val = ''
1086 stmt = ''
1087 funcs = []
1088 sp_param_dict = {} # Store 'index' for struct param to print, or an name of binding "Count" param for array to print
1089 create_params = 0 # Num of params at end of function that are created and returned as output values
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001090 if 'AllocateDescriptorSets' in proto.name:
Cody Northrop1e4f8022015-08-03 12:47:29 -06001091 create_params = -1
Mike Stroyanbf237d72015-04-03 17:45:53 -06001092 elif 'Create' in proto.name or 'Alloc' in proto.name or 'MapMemory' in proto.name:
1093 create_params = -1
1094 if proto.ret != "void":
Jon Ashburnb0fbe912015-05-06 10:15:07 -06001095 ret_val = "%s result = " % proto.ret
Mike Stroyanbf237d72015-04-03 17:45:53 -06001096 stmt = " return result;\n"
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001097 f_open = 'loader_platform_thread_lock_mutex(&printLock);\n '
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001098 log_func = '%s\n' % self.lineinfo.get()
1099 log_func += ' if (StreamControl::writeAddress == true) {'
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001100 log_func += '\n (*outputStream) << "t{" << getTIDIndex() << "} vk%s(' % proto.name
1101 log_func_no_addr = '\n (*outputStream) << "t{" << getTIDIndex() << "} vk%s(' % proto.name
1102 f_close = '\n loader_platform_thread_unlock_mutex(&printLock);'
Mike Stroyanbf237d72015-04-03 17:45:53 -06001103 pindex = 0
1104 prev_count_name = ''
1105 for p in proto.params:
1106 cp = False
1107 if 0 != create_params:
1108 # If this is any of the N last params of the func, treat as output
1109 for y in range(-1, create_params-1, -1):
1110 if p.name == proto.params[y].name:
1111 cp = True
1112 (pft, pfi) = self._get_printf_params(p.ty, p.name, cp, cpp=True)
Jon Ashburn8acd2332015-09-16 18:08:32 -06001113 if p.name == "pSwapchain" or p.name == "pSwapchainImages":
Chia-I Wue2fc5522015-10-26 20:04:44 +08001114 log_func += '%s = " << %s << ", ' % (p.name, p.name)
Mark Lobodzinski25a2cc82015-12-02 16:12:08 -07001115 elif p.name == "swapchain" or p.name == "visual_id":
Chia-I Wue2fc5522015-10-26 20:04:44 +08001116 log_func += '%s = " << %s << ", ' % (p.name, p.name)
Ian Elliott1064fe32015-07-06 14:31:32 -06001117 else:
1118 log_func += '%s = " << %s << ", ' % (p.name, pfi)
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001119 if "%p" == pft:
1120 log_func_no_addr += '%s = address, ' % (p.name)
1121 else:
1122 log_func_no_addr += '%s = " << %s << ", ' % (p.name, pfi)
Tobin Ehlis08541742015-04-16 15:56:11 -06001123 if prev_count_name != '' and (prev_count_name.replace('Count', '')[1:] in p.name):
Mike Stroyanbf237d72015-04-03 17:45:53 -06001124 sp_param_dict[pindex] = prev_count_name
Tobin Ehlis08541742015-04-16 15:56:11 -06001125 prev_count_name = ''
Chia-I Wuf8693382015-04-16 22:02:10 +08001126 elif vk_helper.is_type(p.ty.strip('*').replace('const ', ''), 'struct'):
Mike Stroyanbf237d72015-04-03 17:45:53 -06001127 sp_param_dict[pindex] = 'index'
Mike Stroyanbf237d72015-04-03 17:45:53 -06001128 if p.name.endswith('Count'):
1129 if '*' in p.ty:
1130 prev_count_name = "*%s" % p.name
1131 else:
1132 prev_count_name = p.name
Courtney Goeltzenleuchterf260f6c2015-09-23 12:28:10 -06001133 else:
1134 prev_count_name = ''
Jon Ashburn9fd4cc42015-04-10 14:33:07 -06001135 pindex += 1
Mike Stroyanbf237d72015-04-03 17:45:53 -06001136 log_func = log_func.strip(', ')
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001137 log_func_no_addr = log_func_no_addr.strip(', ')
Jon Ashburnb0fbe912015-05-06 10:15:07 -06001138 if proto.ret == "VkResult":
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001139 log_func += ') = " << string_VkResult((VkResult)result) << endl'
1140 log_func_no_addr += ') = " << string_VkResult((VkResult)result) << endl'
Jon Ashburnb0fbe912015-05-06 10:15:07 -06001141 elif proto.ret == "void*":
1142 log_func += ') = " << result << endl'
1143 log_func_no_addr += ') = " << result << endl'
Mike Stroyanbf237d72015-04-03 17:45:53 -06001144 else:
1145 log_func += ')\\n"'
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001146 log_func_no_addr += ')\\n"'
Mike Stroyanbf237d72015-04-03 17:45:53 -06001147 log_func += ';'
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001148 log_func_no_addr += ';'
Tobin Ehlisa30e7e52015-07-06 14:02:36 -06001149 log_func += '\n }\n else {%s\n }' % log_func_no_addr;
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001150 log_func += '\n%s' % self.lineinfo.get()
Courtney Goeltzenleuchterf260f6c2015-09-23 12:28:10 -06001151 # log_func += '\n// Proto %s has param_dict: %s' % (proto.name, sp_param_dict)
Mike Stroyanbf237d72015-04-03 17:45:53 -06001152 if len(sp_param_dict) > 0:
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001153 indent = ' '
1154 log_func += '\n%sif (g_APIDumpDetailed) {' % indent
1155 indent += ' '
Mike Stroyanbf237d72015-04-03 17:45:53 -06001156 i_decl = False
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001157 log_func += '\n%s' % self.lineinfo.get()
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001158 log_func += '\n%sstring tmp_str;' % indent
Mike Stroyanbf237d72015-04-03 17:45:53 -06001159 for sp_index in sp_param_dict:
Courtney Goeltzenleuchterf260f6c2015-09-23 12:28:10 -06001160 # log_func += '\n// sp_index: %s' % str(sp_index)
Mike Stroyanbf237d72015-04-03 17:45:53 -06001161 if 'index' == sp_param_dict[sp_index]:
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -06001162 cis_print_func = 'vk_print_%s' % (proto.params[sp_index].ty.replace('const ', '').strip('*').lower())
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001163 local_name = proto.params[sp_index].name
1164 if '*' not in proto.params[sp_index].ty:
1165 local_name = '&%s' % proto.params[sp_index].name
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001166 log_func += '\n%s' % self.lineinfo.get()
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001167 log_func += '\n%sif (%s) {' % (indent, local_name)
1168 indent += ' '
1169 log_func += '\n%stmp_str = %s(%s, " ");' % (indent, cis_print_func, local_name)
1170 log_func += '\n%s(*outputStream) << " %s (" << %s << ")" << endl << tmp_str << endl;' % (indent, local_name, local_name)
1171 indent = indent[4:]
1172 log_func += '\n%s}' % (indent)
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001173 elif 'memoryBarrierCount' == sp_param_dict[sp_index]: # call helper function
1174 log_func += '\n%sif (ppMemoryBarriers) {' % (indent)
1175 log_func += '\n%s interpret_memBarriers(ppMemoryBarriers, memoryBarrierCount);' % (indent)
Mark Lobodzinskib9143d82015-07-30 10:11:32 -06001176 log_func += '\n%s}' % (indent)
Mike Stroyanbf237d72015-04-03 17:45:53 -06001177 else: # We have a count value stored to iterate over an array
1178 print_cast = ''
1179 print_func = ''
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -06001180 if vk_helper.is_type(proto.params[sp_index].ty.strip('*').replace('const ', ''), 'struct'):
Mike Stroyanbf237d72015-04-03 17:45:53 -06001181 print_cast = '&'
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -06001182 print_func = 'vk_print_%s' % proto.params[sp_index].ty.replace('const ', '').strip('*').lower()
Mike Stroyanbf237d72015-04-03 17:45:53 -06001183 else:
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001184 print_cast = ''
Mike Stroyanbf237d72015-04-03 17:45:53 -06001185 print_func = 'string_convert_helper'
1186 #cis_print_func = 'tmp_str = string_convert_helper((void*)%s[i], " ");' % proto.params[sp_index].name
Chia-I Wue2fc5522015-10-26 20:04:44 +08001187 cis_print_func = 'tmp_str = %s(%s%s[i], " ");' % (print_func, print_cast, proto.params[sp_index].name)
Mike Stroyanbf237d72015-04-03 17:45:53 -06001188 if not i_decl:
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001189 log_func += '\n%suint32_t i;' % (indent)
Mike Stroyanbf237d72015-04-03 17:45:53 -06001190 i_decl = True
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001191 log_func += '\n%sif (%s) {' % (indent, proto.params[sp_index].name)
1192 indent += ' '
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001193 log_func += '\n%s' % self.lineinfo.get()
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001194 log_func += '\n%sfor (i = 0; i < %s; i++) {' % (indent, sp_param_dict[sp_index])
1195 indent += ' '
1196 log_func += '\n%s%s' % (indent, cis_print_func)
Tobin Ehlis45a23a82015-04-28 10:58:20 -06001197 log_func += '\n%sif (StreamControl::writeAddress == true) {' % (indent)
1198 indent += ' '
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001199 log_func += '\n%s(*outputStream) << " %s[" << i << "] (" << %s%s[i] << ")" << endl << tmp_str << endl;' % (indent, proto.params[sp_index].name, '&', proto.params[sp_index].name)
1200 indent = indent[4:]
Tobin Ehlis45a23a82015-04-28 10:58:20 -06001201 log_func += '\n%s} else {' % (indent)
1202 indent += ' '
1203 log_func += '\n%s(*outputStream) << " %s[" << i << "] (address)" << endl << " address" << endl;' % (indent, proto.params[sp_index].name)
1204 indent = indent[4:]
1205 log_func += '\n%s}' % (indent)
1206 indent = indent[4:]
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001207 log_func += '\n%s}' % (indent)
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001208 indent = indent[4:]
1209 log_func += '\n%s}' % (indent)
Tobin Ehlisa2b199c2015-04-27 17:30:04 -06001210 indent = indent[4:]
1211 log_func += '\n%s}' % (indent)
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001212 table_type = ''
Jon Ashburn95a77ba2015-05-15 15:09:35 -06001213 if proto_is_global(proto):
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001214 table_type = 'instance'
1215 else:
1216 table_type = 'device'
Jon Ashburn3dc39382015-09-17 10:00:32 -06001217 dispatch_param = proto.params[0].name
Jon Ashburn71836d92015-05-12 17:23:55 -06001218
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001219 if proto.name == "CreateInstance":
1220 dispatch_param = '*' + proto.params[1].name
Jon Ashburn3dc39382015-09-17 10:00:32 -06001221 funcs.append('%s%s\n'
1222 '{\n'
1223 ' using namespace StreamControl;\n'
1224 ' %sinstance_dispatch_table(*pInstance)->%s;\n'
1225 ' if (result == VK_SUCCESS) {\n'
1226 ' createInstanceRegisterExtensions(pCreateInfo, *pInstance);\n'
1227 ' }\n'
1228 ' %s%s%s\n'
1229 '%s'
1230 '}\n' % (qual, decl, ret_val, proto.c_call(), f_open, log_func, f_close, stmt))
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001231
Jon Ashburn3dc39382015-09-17 10:00:32 -06001232 elif proto.name == "CreateDevice":
Courtney Goeltzenleuchter0de9e212015-06-26 15:07:53 -06001233 funcs.append('%s\n' % self.lineinfo.get())
Jon Ashburn747f2b62015-06-18 15:02:58 -06001234 funcs.append('%s%s\n'
1235 '{\n'
1236 ' using namespace StreamControl;\n'
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -06001237 ' %sdevice_dispatch_table(*pDevice)->%s;\n'
Jon Ashburn747f2b62015-06-18 15:02:58 -06001238 ' if (result == VK_SUCCESS)\n'
1239 ' createDeviceRegisterExtensions(pCreateInfo, *pDevice);\n'
1240 ' %s%s%s\n'
1241 '%s'
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -06001242 '}' % (qual, decl, ret_val, proto.c_call(), f_open, log_func, f_close, stmt))
Jon Ashburn747f2b62015-06-18 15:02:58 -06001243 elif proto.name == "DestroyDevice":
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001244 funcs.append('%s%s\n'
1245 '{\n'
1246 ' using namespace StreamControl;\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -06001247 ' dispatch_key key = get_dispatch_key(device);\n'
Jon Ashburn3dc39382015-09-17 10:00:32 -06001248 ' VkLayerDispatchTable *pDisp = %s_dispatch_table(%s);\n'
Jon Ashburn747f2b62015-06-18 15:02:58 -06001249 ' %spDisp->%s;\n'
1250 ' deviceExtMap.erase(pDisp);\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -06001251 ' destroy_device_dispatch_table(key);\n'
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001252 ' %s%s%s\n'
1253 '%s'
Jon Ashburn747f2b62015-06-18 15:02:58 -06001254 '}' % (qual, decl, table_type, dispatch_param, ret_val, proto.c_call(), f_open, log_func, f_close, stmt))
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001255 elif proto.name == "DestroyInstance":
1256 funcs.append('%s%s\n'
1257 '{\n'
1258 ' using namespace StreamControl;\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -06001259 ' dispatch_key key = get_dispatch_key(instance);\n'
Jon Ashburn3dc39382015-09-17 10:00:32 -06001260 ' VkLayerInstanceDispatchTable *pDisp = %s_dispatch_table(%s);\n'
1261 ' %spDisp->%s;\n'
1262 ' instanceExtMap.erase(pDisp);\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -06001263 ' destroy_instance_dispatch_table(key);\n'
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001264 ' %s%s%s\n'
1265 '%s'
Jon Ashburn3dc39382015-09-17 10:00:32 -06001266 '}' % (qual, decl, table_type, dispatch_param, ret_val, proto.c_call(), f_open, log_func, f_close, stmt))
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001267 else:
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001268 if wsi_name(decl):
1269 funcs.append('%s' % wsi_ifdef(decl))
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001270 funcs.append('%s%s\n'
1271 '{\n'
1272 ' using namespace StreamControl;\n'
1273 ' %s%s_dispatch_table(%s)->%s;\n'
Jon Ashburnbacb0f52015-04-06 10:58:22 -06001274 ' %s%s%s\n'
1275 '%s'
Mark Lobodzinski4c7ac0a2015-05-26 09:29:09 -05001276 '}' % (qual, decl, ret_val, table_type, dispatch_param, proto.c_call(), f_open, log_func, f_close, stmt))
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001277 if wsi_name(decl):
1278 funcs.append('%s' % wsi_endif(decl))
Mike Stroyanbf237d72015-04-03 17:45:53 -06001279 return "\n\n".join(funcs)
1280
Tobin Ehlis99f88672015-01-10 12:42:41 -07001281 def generate_body(self):
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001282 self.layer_name = "APIDump"
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001283 if sys.platform.startswith('win32'):
Michael Lentine64e2ebd2015-12-03 14:33:09 -08001284 instance_extensions=[('wsi_enabled',
1285 ['vkGetPhysicalDeviceSurfaceSupportKHR',
1286 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
1287 'vkGetPhysicalDeviceSurfaceFormatsKHR',
1288 'vkGetPhysicalDeviceSurfacePresentModesKHR',
1289 'vkCreateWin32SurfaceKHR',
1290 'vkGetPhysicalDeviceWin32PresentationSupportKHR'])]
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001291 elif sys.platform.startswith('linux'):
Michael Lentine64e2ebd2015-12-03 14:33:09 -08001292 instance_extensions=[('wsi_enabled',
1293 ['vkGetPhysicalDeviceSurfaceSupportKHR',
1294 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
1295 'vkGetPhysicalDeviceSurfaceFormatsKHR',
1296 'vkGetPhysicalDeviceSurfacePresentModesKHR',
1297 'vkCreateXcbSurfaceKHR',
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -07001298 'vkGetPhysicalDeviceXcbPresentationSupportKHR'])]
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001299 # TODO: Add cases for Mir, Xlib, Wayland
1300 else:
1301 instance_extensions=[('wsi_enabled',
1302 ['vkGetPhysicalDeviceSurfaceSupportKHR',
1303 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
1304 'vkGetPhysicalDeviceSurfaceFormatsKHR',
1305 'vkGetPhysicalDeviceSurfacePresentModesKHR'])]
Ian Elliott1064fe32015-07-06 14:31:32 -06001306 extensions=[('wsi_enabled',
Ian Elliott05846062015-11-20 14:13:17 -07001307 ['vkCreateSwapchainKHR',
Jon Ashburn8acd2332015-09-16 18:08:32 -06001308 'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
1309 'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
Tobin Ehlise78dbd82015-04-09 09:19:36 -06001310 body = [self.generate_init(),
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001311 self._generate_dispatch_entrypoints("VK_LAYER_EXPORT"),
Jon Ashburn3dc39382015-09-17 10:00:32 -06001312 self._generate_layer_gpa_function(extensions, instance_extensions)]
Tobin Ehlis99f88672015-01-10 12:42:41 -07001313 return "\n\n".join(body)
1314
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001315class ObjectTrackerSubcommand(Subcommand):
1316 def generate_header(self):
1317 header_txt = []
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001318 header_txt.append('%s' % self.lineinfo.get())
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001319 header_txt.append('#include <stdio.h>')
1320 header_txt.append('#include <stdlib.h>')
1321 header_txt.append('#include <string.h>')
1322 header_txt.append('#include <inttypes.h>')
1323 header_txt.append('')
David Pinedo9316d3b2015-11-06 12:54:48 -07001324 header_txt.append('#include "vulkan/vulkan.h"')
Tobin Ehlisb835d1b2015-07-03 10:34:49 -06001325 header_txt.append('#include "vk_loader_platform.h"')
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001326 header_txt.append('')
Tobin Ehlis803cc492015-06-08 17:36:28 -06001327 header_txt.append('#include <unordered_map>')
1328 header_txt.append('using namespace std;')
David Pinedo9316d3b2015-11-06 12:54:48 -07001329 header_txt.append('#include "vulkan/vk_layer.h"')
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -06001330 header_txt.append('#include "vk_layer_config.h"')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001331 header_txt.append('#include "vulkan/vk_ext_debug_report.h"')
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -06001332 header_txt.append('#include "vk_layer_table.h"')
1333 header_txt.append('#include "vk_layer_data.h"')
1334 header_txt.append('#include "vk_layer_logging.h"')
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001335 header_txt.append('')
1336# NOTE: The non-autoGenerated code is in the object_track.h header file
1337 header_txt.append('#include "object_track.h"')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05001338 header_txt.append('')
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -06001339 header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05001340 header_txt.append('')
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001341 return "\n".join(header_txt)
1342
Tony Barboura05dbaa2015-07-09 17:31:46 -06001343 def generate_maps(self):
1344 maps_txt = []
1345 for o in vulkan.core.objects:
Michael Lentine13803dc2015-11-04 14:35:12 -08001346 maps_txt.append('unordered_map<uint64_t, OBJTRACK_NODE*> %sMap;' % (o))
1347 maps_txt.append('unordered_map<uint64_t, OBJTRACK_NODE*> VkSwapchainKHRMap;')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001348 return "\n".join(maps_txt)
1349
1350 def generate_procs(self):
1351 procs_txt = []
1352 for o in vulkan.core.objects:
1353 procs_txt.append('%s' % self.lineinfo.get())
Michael Lentine13803dc2015-11-04 14:35:12 -08001354 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', o)
1355 name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
Tobin Ehlis154e0462015-08-26 11:22:09 -06001356 if o in vulkan.object_dispatch_list:
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001357 procs_txt.append('static void create_%s(%s dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o, o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001358 else:
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001359 procs_txt.append('static void create_%s(VkDevice dispatchable_object, %s vkObj, VkDebugReportObjectTypeEXT objType)' % (name, o))
Chia-I Wue2fc5522015-10-26 20:04:44 +08001360 procs_txt.append('{')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001361 procs_txt.append(' log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFO_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",')
1362 procs_txt.append(' "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeEXT(objType),')
Chia-I Wue2fc5522015-10-26 20:04:44 +08001363 procs_txt.append(' reinterpret_cast<uint64_t>(vkObj));')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001364 procs_txt.append('')
1365 procs_txt.append(' OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;')
1366 procs_txt.append(' pNewObjNode->objType = objType;')
1367 procs_txt.append(' pNewObjNode->status = OBJSTATUS_NONE;')
Chia-I Wue2fc5522015-10-26 20:04:44 +08001368 procs_txt.append(' pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);')
Michael Lentine13803dc2015-11-04 14:35:12 -08001369 procs_txt.append(' %sMap[(uint64_t)vkObj] = pNewObjNode;' % (o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001370 procs_txt.append(' uint32_t objIndex = objTypeToIndex(objType);')
1371 procs_txt.append(' numObjs[objIndex]++;')
1372 procs_txt.append(' numTotalObjs++;')
1373 procs_txt.append('}')
1374 procs_txt.append('')
1375 procs_txt.append('%s' % self.lineinfo.get())
Tobin Ehlisec598302015-09-15 15:02:17 -06001376 # TODO : This is not complete and currently requires some hand-coded function in the header
1377 # Really we want to capture the set of all objects and their associated dispatchable objects
1378 # that are bound by the API calls:
1379 # foreach API Call
1380 # foreach object type seen by call
1381 # create validate_object(disp_obj, object)
Tobin Ehlis154e0462015-08-26 11:22:09 -06001382 if o in vulkan.object_dispatch_list:
Michael Lentine13803dc2015-11-04 14:35:12 -08001383 procs_txt.append('static VkBool32 validate_%s(%s dispatchable_object, %s object)' % (name, o, o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001384 else:
Michael Lentine13803dc2015-11-04 14:35:12 -08001385 procs_txt.append('static VkBool32 validate_%s(VkDevice dispatchable_object, %s object)' % (name, o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001386 procs_txt.append('{')
Tobin Ehlis154e0462015-08-26 11:22:09 -06001387 if o in vulkan.object_dispatch_list:
Michael Lentine13803dc2015-11-04 14:35:12 -08001388 procs_txt.append(' if (%sMap.find((uint64_t)object) == %sMap.end()) {' % (o, o))
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001389 procs_txt.append(' return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0, reinterpret_cast<uint64_t>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",')
Michael Lentine010f4692015-11-03 16:19:46 -08001390 procs_txt.append(' "Invalid %s Object 0x%%" PRIx64 ,reinterpret_cast<uint64_t>(object));' % o)
Tony Barboura05dbaa2015-07-09 17:31:46 -06001391 else:
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001392 if o == "VkImage":
1393 procs_txt.append(' // We need to validate normal image objects and those from the swapchain')
Michael Lentine13803dc2015-11-04 14:35:12 -08001394 procs_txt.append(' if ((%sMap.find((uint64_t)object) == %sMap.end()) &&' % (o, o))
1395 procs_txt.append(' (swapchainImageMap.find((uint64_t)object) == swapchainImageMap.end())) {')
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001396 else:
Michael Lentine13803dc2015-11-04 14:35:12 -08001397 procs_txt.append(' if (%sMap.find((uint64_t)object) == %sMap.end()) {' % (o, o))
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001398 procs_txt.append(' return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",')
Michael Lentine010f4692015-11-03 16:19:46 -08001399 procs_txt.append(' "Invalid %s Object 0x%%" PRIx64, reinterpret_cast<uint64_t>(object));' % o)
Tony Barboura05dbaa2015-07-09 17:31:46 -06001400 procs_txt.append(' }')
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -06001401 procs_txt.append(' return VK_FALSE;')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001402 procs_txt.append('}')
1403 procs_txt.append('')
1404 procs_txt.append('')
1405 procs_txt.append('%s' % self.lineinfo.get())
Tobin Ehlis154e0462015-08-26 11:22:09 -06001406 if o in vulkan.object_dispatch_list:
Michael Lentine13803dc2015-11-04 14:35:12 -08001407 procs_txt.append('static void destroy_%s(%s dispatchable_object, %s object)' % (name, o, o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001408 else:
Michael Lentine13803dc2015-11-04 14:35:12 -08001409 procs_txt.append('static void destroy_%s(VkDevice dispatchable_object, %s object)' % (name, o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001410 procs_txt.append('{')
Michael Lentine13803dc2015-11-04 14:35:12 -08001411 procs_txt.append(' uint64_t object_handle = reinterpret_cast<uint64_t>(object);')
1412 procs_txt.append(' if (%sMap.find(object_handle) != %sMap.end()) {' % (o, o))
1413 procs_txt.append(' OBJTRACK_NODE* pNode = %sMap[(uint64_t)object];' % (o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001414 procs_txt.append(' uint32_t objIndex = objTypeToIndex(pNode->objType);')
1415 procs_txt.append(' assert(numTotalObjs > 0);')
1416 procs_txt.append(' numTotalObjs--;')
1417 procs_txt.append(' assert(numObjs[objIndex] > 0);')
1418 procs_txt.append(' numObjs[objIndex]--;')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001419 procs_txt.append(' log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFO_BIT_EXT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",')
Michael Lentine010f4692015-11-03 16:19:46 -08001420 procs_txt.append(' "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001421 procs_txt.append(' string_VkDebugReportObjectTypeEXT(pNode->objType), reinterpret_cast<uint64_t>(object), numTotalObjs, numObjs[objIndex],')
1422 procs_txt.append(' string_VkDebugReportObjectTypeEXT(pNode->objType));')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001423 procs_txt.append(' delete pNode;')
Michael Lentine13803dc2015-11-04 14:35:12 -08001424 procs_txt.append(' %sMap.erase(object_handle);' % (o))
Chia-I Wue2fc5522015-10-26 20:04:44 +08001425 procs_txt.append(' } else {')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001426 procs_txt.append(' log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",')
Chia-I Wue2fc5522015-10-26 20:04:44 +08001427 procs_txt.append(' "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",')
Michael Lentine13803dc2015-11-04 14:35:12 -08001428 procs_txt.append(' object_handle);')
Chia-I Wue2fc5522015-10-26 20:04:44 +08001429 procs_txt.append(' }')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001430 procs_txt.append('}')
1431 procs_txt.append('')
1432 procs_txt.append('%s' % self.lineinfo.get())
Tobin Ehlis154e0462015-08-26 11:22:09 -06001433 if o in vulkan.object_dispatch_list:
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001434 procs_txt.append('static VkBool32 set_%s_status(%s dispatchable_object, %s object, VkDebugReportObjectTypeEXT objType, ObjectStatusFlags status_flag)' % (name, o, o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001435 else:
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001436 procs_txt.append('static VkBool32 set_%s_status(VkDevice dispatchable_object, %s object, VkDebugReportObjectTypeEXT objType, ObjectStatusFlags status_flag)' % (name, o))
Chia-I Wue2fc5522015-10-26 20:04:44 +08001437 procs_txt.append('{')
1438 procs_txt.append(' if (object != VK_NULL_HANDLE) {')
Michael Lentine13803dc2015-11-04 14:35:12 -08001439 procs_txt.append(' uint64_t object_handle = reinterpret_cast<uint64_t>(object);')
1440 procs_txt.append(' if (%sMap.find(object_handle) != %sMap.end()) {' % (o, o))
1441 procs_txt.append(' OBJTRACK_NODE* pNode = %sMap[object_handle];' % (o))
Tobin Ehlis154e0462015-08-26 11:22:09 -06001442 procs_txt.append(' pNode->status |= status_flag;')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001443 procs_txt.append(' }')
1444 procs_txt.append(' else {')
1445 procs_txt.append(' // If we do not find it print an error')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001446 procs_txt.append(' return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",')
Chia-I Wue2fc5522015-10-26 20:04:44 +08001447 procs_txt.append(' "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001448 procs_txt.append(' object_handle, string_VkDebugReportObjectTypeEXT(objType));')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001449 procs_txt.append(' }')
1450 procs_txt.append(' }')
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -06001451 procs_txt.append(' return VK_FALSE;')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001452 procs_txt.append('}')
1453 procs_txt.append('')
1454 procs_txt.append('%s' % self.lineinfo.get())
Michael Lentine13803dc2015-11-04 14:35:12 -08001455 procs_txt.append('static VkBool32 validate_%s_status(' % (name))
Tobin Ehlis154e0462015-08-26 11:22:09 -06001456 if o in vulkan.object_dispatch_list:
Tony Barboura05dbaa2015-07-09 17:31:46 -06001457 procs_txt.append('%s dispatchable_object, %s object,' % (o, o))
1458 else:
1459 procs_txt.append('VkDevice dispatchable_object, %s object,' % (o))
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001460 procs_txt.append(' VkDebugReportObjectTypeEXT objType,')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001461 procs_txt.append(' ObjectStatusFlags status_mask,')
1462 procs_txt.append(' ObjectStatusFlags status_flag,')
1463 procs_txt.append(' VkFlags msg_flags,')
1464 procs_txt.append(' OBJECT_TRACK_ERROR error_code,')
1465 procs_txt.append(' const char *fail_msg)')
1466 procs_txt.append('{')
Michael Lentine13803dc2015-11-04 14:35:12 -08001467 procs_txt.append(' uint64_t object_handle = reinterpret_cast<uint64_t>(object);')
1468 procs_txt.append(' if (%sMap.find(object_handle) != %sMap.end()) {' % (o, o))
1469 procs_txt.append(' OBJTRACK_NODE* pNode = %sMap[object_handle];' % (o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001470 procs_txt.append(' if ((pNode->status & status_mask) != status_flag) {')
Michael Lentine13803dc2015-11-04 14:35:12 -08001471 procs_txt.append(' log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, object_handle, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001472 procs_txt.append(' "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkDebugReportObjectTypeEXT(objType),')
Michael Lentine13803dc2015-11-04 14:35:12 -08001473 procs_txt.append(' object_handle, fail_msg);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001474 procs_txt.append(' return VK_FALSE;')
1475 procs_txt.append(' }')
1476 procs_txt.append(' return VK_TRUE;')
1477 procs_txt.append(' }')
1478 procs_txt.append(' else {')
1479 procs_txt.append(' // If we do not find it print an error')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001480 procs_txt.append(' log_msg(mdd(dispatchable_object), msg_flags, (VkDebugReportObjectTypeEXT) 0, object_handle, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",')
Chia-I Wue2fc5522015-10-26 20:04:44 +08001481 procs_txt.append(' "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001482 procs_txt.append(' object_handle, string_VkDebugReportObjectTypeEXT(objType));')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001483 procs_txt.append(' return VK_FALSE;')
1484 procs_txt.append(' }')
1485 procs_txt.append('}')
1486 procs_txt.append('')
1487 procs_txt.append('%s' % self.lineinfo.get())
Tobin Ehlis154e0462015-08-26 11:22:09 -06001488 if o in vulkan.object_dispatch_list:
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001489 procs_txt.append('static VkBool32 reset_%s_status(%s dispatchable_object, %s object, VkDebugReportObjectTypeEXT objType, ObjectStatusFlags status_flag)' % (name, o, o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001490 else:
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001491 procs_txt.append('static VkBool32 reset_%s_status(VkDevice dispatchable_object, %s object, VkDebugReportObjectTypeEXT objType, ObjectStatusFlags status_flag)' % (name, o))
Chia-I Wue2fc5522015-10-26 20:04:44 +08001492 procs_txt.append('{')
Michael Lentine13803dc2015-11-04 14:35:12 -08001493 procs_txt.append(' uint64_t object_handle = reinterpret_cast<uint64_t>(object);')
1494 procs_txt.append(' if (%sMap.find(object_handle) != %sMap.end()) {' % (o, o))
1495 procs_txt.append(' OBJTRACK_NODE* pNode = %sMap[object_handle];' % (o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001496 procs_txt.append(' pNode->status &= ~status_flag;')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001497 procs_txt.append(' }')
1498 procs_txt.append(' else {')
1499 procs_txt.append(' // If we do not find it print an error')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001500 procs_txt.append(' return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, objType, object_handle, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",')
Chia-I Wue2fc5522015-10-26 20:04:44 +08001501 procs_txt.append(' "Unable to reset status for non-existent object 0x%" PRIxLEAST64 " of %s type",')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001502 procs_txt.append(' object_handle, string_VkDebugReportObjectTypeEXT(objType));')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001503 procs_txt.append(' }')
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -06001504 procs_txt.append(' return VK_FALSE;')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001505 procs_txt.append('}')
1506 procs_txt.append('')
1507 return "\n".join(procs_txt)
1508
Mark Lobodzinski64d57752015-07-17 11:51:24 -06001509 def generate_destroy_instance(self):
Tony Barboura05dbaa2015-07-09 17:31:46 -06001510 gedi_txt = []
1511 gedi_txt.append('%s' % self.lineinfo.get())
Mark Lobodzinski2141f652015-09-07 13:59:43 -06001512 gedi_txt.append('void vkDestroyInstance(')
Chia-I Wuf7458c52015-10-26 21:10:41 +08001513 gedi_txt.append('VkInstance instance,')
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001514 gedi_txt.append('const VkAllocationCallbacks* pAllocator)')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001515 gedi_txt.append('{')
1516 gedi_txt.append(' loader_platform_thread_lock_mutex(&objLock);')
Michael Lentine13803dc2015-11-04 14:35:12 -08001517 gedi_txt.append(' validate_instance(instance, instance);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001518 gedi_txt.append('')
Michael Lentine13803dc2015-11-04 14:35:12 -08001519 gedi_txt.append(' destroy_instance(instance, instance);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001520 gedi_txt.append(' // Report any remaining objects in LL')
1521 for o in vulkan.core.objects:
Mike Stroyan0699a792015-08-18 14:48:34 -06001522 if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue']:
Tony Barboura05dbaa2015-07-09 17:31:46 -06001523 continue
1524 gedi_txt.append(' for (auto it = %sMap.begin(); it != %sMap.end(); ++it) {' % (o, o))
1525 gedi_txt.append(' OBJTRACK_NODE* pNode = it->second;')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001526 gedi_txt.append(' log_msg(mid(instance), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, 0, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
1527 gedi_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
Tony Barbour343d6212015-07-10 18:32:33 -06001528 gedi_txt.append(' pNode->vkObj);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001529 gedi_txt.append(' }')
Mike Stroyan0699a792015-08-18 14:48:34 -06001530 gedi_txt.append(' %sMap.clear();' % (o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001531 gedi_txt.append('')
1532 gedi_txt.append(' dispatch_key key = get_dispatch_key(instance);')
1533 gedi_txt.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, instance);')
Chia-I Wuf7458c52015-10-26 21:10:41 +08001534 gedi_txt.append(' pInstanceTable->DestroyInstance(instance, pAllocator);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001535 gedi_txt.append('')
1536 gedi_txt.append(' // Clean up logging callback, if any')
1537 gedi_txt.append(' layer_data *my_data = get_my_data_ptr(key, layer_data_map);')
1538 gedi_txt.append(' if (my_data->logging_callback) {')
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07001539 gedi_txt.append(' layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback, pAllocator);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001540 gedi_txt.append(' }')
1541 gedi_txt.append('')
1542 gedi_txt.append(' layer_debug_report_destroy_instance(mid(instance));')
1543 gedi_txt.append(' layer_data_map.erase(pInstanceTable);')
1544 gedi_txt.append('')
Jon Ashburn3dc39382015-09-17 10:00:32 -06001545 gedi_txt.append(' instanceExtMap.erase(pInstanceTable);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001546 gedi_txt.append(' loader_platform_thread_unlock_mutex(&objLock);')
Mike Stroyan0699a792015-08-18 14:48:34 -06001547 # The loader holds a mutex that protects this from other threads
1548 gedi_txt.append(' ObjectTracker_instance_table_map.erase(key);')
1549 gedi_txt.append(' if (ObjectTracker_instance_table_map.empty()) {')
1550 gedi_txt.append(' // Release mutex when destroying last instance.')
1551 gedi_txt.append(' loader_platform_thread_delete_mutex(&objLock);')
1552 gedi_txt.append(' objLockInitialized = 0;')
1553 gedi_txt.append(' }')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001554 gedi_txt.append('}')
1555 gedi_txt.append('')
1556 return "\n".join(gedi_txt)
1557
Mark Lobodzinski64d57752015-07-17 11:51:24 -06001558 def generate_destroy_device(self):
Tony Barboura05dbaa2015-07-09 17:31:46 -06001559 gedd_txt = []
1560 gedd_txt.append('%s' % self.lineinfo.get())
Mark Lobodzinski2141f652015-09-07 13:59:43 -06001561 gedd_txt.append('void vkDestroyDevice(')
Chia-I Wuf7458c52015-10-26 21:10:41 +08001562 gedd_txt.append('VkDevice device,')
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001563 gedd_txt.append('const VkAllocationCallbacks* pAllocator)')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001564 gedd_txt.append('{')
1565 gedd_txt.append(' loader_platform_thread_lock_mutex(&objLock);')
Michael Lentine13803dc2015-11-04 14:35:12 -08001566 gedd_txt.append(' validate_device(device, device);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001567 gedd_txt.append('')
Michael Lentine13803dc2015-11-04 14:35:12 -08001568 gedd_txt.append(' destroy_device(device, device);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001569 gedd_txt.append(' // Report any remaining objects in LL')
1570 for o in vulkan.core.objects:
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001571 # DescriptorSets and Command Buffers are destroyed through their pools, not explicitly
1572 if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue', 'VkDevice', 'VkDescriptorSet', 'VkCommandBuffer']:
Tony Barboura05dbaa2015-07-09 17:31:46 -06001573 continue
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001574 gedd_txt.append(' for (auto it = %sMap.begin(); it != %sMap.end(); ++it) {' % (o, o))
1575 gedd_txt.append(' OBJTRACK_NODE* pNode = it->second;')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001576 gedd_txt.append(' log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, 0, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
1577 gedd_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001578 gedd_txt.append(' pNode->vkObj);')
1579 gedd_txt.append(' }')
Mike Stroyan0699a792015-08-18 14:48:34 -06001580 gedd_txt.append(' %sMap.clear();' % (o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001581 gedd_txt.append('')
1582 gedd_txt.append(" // Clean up Queue's MemRef Linked Lists")
1583 gedd_txt.append(' destroyQueueMemRefLists();')
1584 gedd_txt.append('')
1585 gedd_txt.append(' loader_platform_thread_unlock_mutex(&objLock);')
1586 gedd_txt.append('')
1587 gedd_txt.append(' dispatch_key key = get_dispatch_key(device);')
1588 gedd_txt.append(' VkLayerDispatchTable *pDisp = get_dispatch_table(ObjectTracker_device_table_map, device);')
Chia-I Wuf7458c52015-10-26 21:10:41 +08001589 gedd_txt.append(' pDisp->DestroyDevice(device, pAllocator);')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001590 gedd_txt.append(' ObjectTracker_device_table_map.erase(key);')
1591 gedd_txt.append(' assert(ObjectTracker_device_table_map.size() == 0 && "Should not have any instance mappings hanging around");')
1592 gedd_txt.append('')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001593 gedd_txt.append('}')
1594 gedd_txt.append('')
1595 return "\n".join(gedd_txt)
1596
1597 def generate_command_buffer_validates(self):
1598 cbv_txt = []
1599 cbv_txt.append('%s' % self.lineinfo.get())
Courtney Goeltzenleuchter49c73082015-09-17 15:06:17 -06001600 for o in ['VkPipeline',
Tony Barboura05dbaa2015-07-09 17:31:46 -06001601 'VkPipelineLayout', 'VkBuffer', 'VkEvent', 'VkQueryPool', 'VkRenderPass', 'VkFramebuffer']:
Michael Lentine13803dc2015-11-04 14:35:12 -08001602 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', o)
1603 name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
1604 cbv_txt.append('static VkBool32 validate_%s(VkCommandBuffer dispatchable_object, %s object)' % (name, o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001605 cbv_txt.append('{')
Michael Lentine13803dc2015-11-04 14:35:12 -08001606 cbv_txt.append(' uint64_t object_handle = reinterpret_cast<uint64_t>(object);')
1607 cbv_txt.append(' if (%sMap.find(object_handle) == %sMap.end()) {' % (o, o))
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001608 cbv_txt.append(' return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0, object_handle, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",')
Michael Lentine13803dc2015-11-04 14:35:12 -08001609 cbv_txt.append(' "Invalid %s Object 0x%%" PRIx64, object_handle);' % (o))
Tony Barboura05dbaa2015-07-09 17:31:46 -06001610 cbv_txt.append(' }')
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -06001611 cbv_txt.append(' return VK_FALSE;')
Tony Barboura05dbaa2015-07-09 17:31:46 -06001612 cbv_txt.append('}')
1613 cbv_txt.append('')
1614 return "\n".join(cbv_txt)
1615
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -06001616 def generate_intercept(self, proto, qual):
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001617 if proto.name in [ 'CreateDebugReportCallbackEXT', 'EnumerateInstanceLayerProperties', 'EnumerateInstanceExtensionProperties','EnumerateDeviceLayerProperties', 'EnumerateDeviceExtensionProperties' ]:
Mike Stroyan00087e62015-04-03 14:39:16 -06001618 # use default version
1619 return None
Mark Lobodzinski7c75b852015-05-05 15:01:37 -05001620
Tony Barboura05dbaa2015-07-09 17:31:46 -06001621 # Create map of object names to object type enums of the form VkName : VkObjectTypeName
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001622 obj_type_mapping = {base_t : base_t.replace("Vk", "VkDebugReportObjectType") for base_t in vulkan.object_type_list}
Mark Lobodzinski7c75b852015-05-05 15:01:37 -05001623 # Convert object type enum names from UpperCamelCase to UPPER_CASE_WITH_UNDERSCORES
1624 for objectName, objectTypeEnum in obj_type_mapping.items():
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001625 obj_type_mapping[objectName] = ucc_to_U_C_C(objectTypeEnum) + '_EXT';
Mark Lobodzinski7c75b852015-05-05 15:01:37 -05001626 # Command Buffer Object doesn't follow the rule.
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001627 obj_type_mapping['VkCommandBuffer'] = "VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT"
1628 obj_type_mapping['VkShaderModule'] = "VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT"
Mike Stroyan00087e62015-04-03 14:39:16 -06001629
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001630 explicit_object_tracker_functions = [
1631 "CreateInstance",
Tobin Ehlisec598302015-09-15 15:02:17 -06001632 "EnumeratePhysicalDevices",
Cody Northropd0802882015-08-03 17:04:53 -06001633 "GetPhysicalDeviceQueueFamilyProperties",
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001634 "CreateDevice",
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001635 "GetDeviceQueue",
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +08001636 "QueueBindSparse",
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001637 "AllocateDescriptorSets",
Tony Barbour770f80d2015-07-20 10:52:13 -06001638 "FreeDescriptorSets",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001639 "AllocateCommandBuffers",
1640 "FreeCommandBuffers",
1641 "DestroyDescriptorPool",
1642 "DestroyCommandPool",
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001643 "MapMemory",
1644 "UnmapMemory",
1645 "FreeMemory",
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001646 "DestroySwapchainKHR",
1647 "GetSwapchainImagesKHR"
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001648 ]
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001649 decl = proto.c_func(prefix="vk", attr="VKAPI")
Mike Stroyan00087e62015-04-03 14:39:16 -06001650 param0_name = proto.params[0].name
Mark Lobodzinski48bd16d2015-05-08 09:12:28 -05001651 using_line = ''
Mike Stroyan00087e62015-04-03 14:39:16 -06001652 create_line = ''
Mark Lobodzinski64d57752015-07-17 11:51:24 -06001653 destroy_line = ''
Tobin Ehlis154e0462015-08-26 11:22:09 -06001654 # 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
1655 loop_params = defaultdict(list) # Dict uses loop count as key to make final code generation cleaner so params shared in single loop where needed
Michael Lentine13803dc2015-11-04 14:35:12 -08001656 loop_types = defaultdict(list)
Tobin Ehlis2717d132015-07-10 18:25:07 -06001657 # TODO : For now skipping objs that can be NULL. Really should check these and have special case that allows them to be NULL
Tobin Ehlis154e0462015-08-26 11:22:09 -06001658 # or better yet, these should be encoded into an API json definition and we generate checks from there
1659 # 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)
1660 # param names may be directly passed to the function, or may be a field in a struct param
1661 valid_null_object_names = {'CreateGraphicsPipelines' : ['basePipelineHandle'],
1662 'CreateComputePipelines' : ['basePipelineHandle'],
1663 'BeginCommandBuffer' : ['renderPass', 'framebuffer'],
Tobin Ehlisec598302015-09-15 15:02:17 -06001664 'QueueSubmit' : ['fence'],
Tobin Ehlisba31cab2015-11-02 15:24:32 -07001665 'UpdateDescriptorSets' : ['pTexelBufferView'],
Tobin Ehlis154e0462015-08-26 11:22:09 -06001666 }
Tobin Ehlis154e0462015-08-26 11:22:09 -06001667 param_count = 'NONE' # keep track of arrays passed directly into API functions
Tobin Ehlis803cc492015-06-08 17:36:28 -06001668 for p in proto.params:
Tobin Ehlisec598302015-09-15 15:02:17 -06001669 base_type = p.ty.replace('const ', '').strip('*')
Tobin Ehlis154e0462015-08-26 11:22:09 -06001670 if 'count' in p.name.lower():
1671 param_count = p.name
Tobin Ehlisec598302015-09-15 15:02:17 -06001672 if base_type in vulkan.core.objects:
1673 # This is an object to potentially check for validity. First see if it's an array
1674 if '*' in p.ty and 'const' in p.ty and param_count != 'NONE':
1675 loop_params[param_count].append(p.name)
Michael Lentine13803dc2015-11-04 14:35:12 -08001676 loop_types[param_count].append(str(p.ty[6:-1]))
Tobin Ehlisec598302015-09-15 15:02:17 -06001677 # Not an array, check for just a base Object that's not in exceptions
1678 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]):
Tobin Ehlis154e0462015-08-26 11:22:09 -06001679 loop_params[0].append(p.name)
Michael Lentine13803dc2015-11-04 14:35:12 -08001680 loop_types[0].append(str(p.ty))
Tobin Ehlisec598302015-09-15 15:02:17 -06001681 elif vk_helper.is_type(base_type, 'struct'):
1682 struct_type = base_type
Tobin Ehlis9d675942015-06-30 14:32:16 -06001683 if vk_helper.typedef_rev_dict[struct_type] in vk_helper.struct_dict:
1684 struct_type = vk_helper.typedef_rev_dict[struct_type]
Tobin Ehlis82b3db52015-10-23 17:52:53 -06001685 # Parse elements of this struct param to identify objects and/or arrays of objects
Tobin Ehlis9d675942015-06-30 14:32:16 -06001686 for m in sorted(vk_helper.struct_dict[struct_type]):
1687 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']:
Tobin Ehlis154e0462015-08-26 11:22:09 -06001688 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]:
Tobin Ehlis82b3db52015-10-23 17:52:53 -06001689 # This is not great, but gets the job done for now, but If we have a count and this param is a ptr w/
1690 # last letter 's' OR non-'count' string of count is in the param name, then this is a dynamically sized array param
1691 param_array = False
1692 if param_count != 'NONE':
1693 if '*' in p.ty:
1694 if 's' == p.name[-1] or param_count.lower().replace('count', '') in p.name.lower():
1695 param_array = True
1696 if param_array:
Tobin Ehlis154e0462015-08-26 11:22:09 -06001697 param_name = '%s[i].%s' % (p.name, vk_helper.struct_dict[struct_type][m]['name'])
Tobin Ehlis46d53622015-07-10 11:10:21 -06001698 else:
Tobin Ehlis154e0462015-08-26 11:22:09 -06001699 param_name = '%s->%s' % (p.name, vk_helper.struct_dict[struct_type][m]['name'])
1700 if vk_helper.struct_dict[struct_type][m]['dyn_array']:
Tobin Ehlis82b3db52015-10-23 17:52:53 -06001701 if param_count != 'NONE': # this will be a double-embedded loop, use comma delineated 'count,name' for param_name
1702 loop_count = '%s[i].%s' % (p.name, vk_helper.struct_dict[struct_type][m]['array_size'])
1703 loop_params[param_count].append('%s,%s' % (loop_count, param_name))
Michael Lentine13803dc2015-11-04 14:35:12 -08001704 loop_types[param_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type']))
Tobin Ehlis82b3db52015-10-23 17:52:53 -06001705 else:
1706 loop_count = '%s->%s' % (p.name, vk_helper.struct_dict[struct_type][m]['array_size'])
1707 loop_params[loop_count].append(param_name)
Michael Lentine13803dc2015-11-04 14:35:12 -08001708 loop_types[loop_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type']))
Tobin Ehlis154e0462015-08-26 11:22:09 -06001709 else:
1710 if '[' in param_name: # dynamic array param, set size
1711 loop_params[param_count].append(param_name)
Michael Lentine13803dc2015-11-04 14:35:12 -08001712 loop_types[param_count].append('%s' % (vk_helper.struct_dict[struct_type][m]['type']))
Tobin Ehlis154e0462015-08-26 11:22:09 -06001713 else:
1714 loop_params[0].append(param_name)
Michael Lentine13803dc2015-11-04 14:35:12 -08001715 loop_types[0].append('%s' % (vk_helper.struct_dict[struct_type][m]['type']))
Mike Stroyan00087e62015-04-03 14:39:16 -06001716 funcs = []
Tobin Ehlis803cc492015-06-08 17:36:28 -06001717 mutex_unlock = False
Tobin Ehlis154e0462015-08-26 11:22:09 -06001718 funcs.append('%s\n' % self.lineinfo.get())
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001719 if proto.name in explicit_object_tracker_functions:
Jon Ashburn4d9f4652015-04-08 21:33:34 -06001720 funcs.append('%s%s\n'
1721 '{\n'
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001722 ' return explicit_%s;\n'
1723 '}' % (qual, decl, proto.c_call()))
1724 return "".join(funcs)
Mark Lobodzinski308d7792015-11-24 10:28:31 -07001725 # Temporarily prevent DestroySurface call from being generated until WSI layer support is fleshed out
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -07001726 elif 'DestroyInstance' in proto.name or 'DestroyDevice' in proto.name: # LUGMAL or 'SurfaceKHR' in proto.name:
Mark Lobodzinski64d57752015-07-17 11:51:24 -06001727 return ""
Jon Ashburn4d9f4652015-04-08 21:33:34 -06001728 else:
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001729 if 'Create' in proto.name or 'Alloc' in proto.name:
Michael Lentine13803dc2015-11-04 14:35:12 -08001730 typ = proto.params[-1].ty.strip('*').replace('const ', '');
1731 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ)
1732 name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001733 create_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
1734 create_line += ' if (result == VK_SUCCESS) {\n'
Michael Lentine13803dc2015-11-04 14:35:12 -08001735 create_line += ' create_%s(%s, *%s, %s);\n' % (name, param0_name, proto.params[-1].name, obj_type_mapping[typ])
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001736 create_line += ' }\n'
1737 create_line += ' loader_platform_thread_unlock_mutex(&objLock);\n'
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -06001738 if 'FreeCommandBuffers' in proto.name:
Michael Lentine13803dc2015-11-04 14:35:12 -08001739 typ = proto.params[-1].ty.strip('*').replace('const ', '');
1740 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ)
1741 name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -06001742 funcs.append('%s\n' % self.lineinfo.get())
1743 destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
Chia-I Wud50a7d72015-10-26 20:48:51 +08001744 destroy_line += ' for (uint32_t i = 0; i < commandBufferCount; i++) {\n'
Michael Lentine13803dc2015-11-04 14:35:12 -08001745 destroy_line += ' destroy_%s(%s[i], %s[i]);\n' % (name, proto.params[-1].name, proto.params[-1].name)
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -06001746 destroy_line += ' }\n'
1747 destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n'
Mark Lobodzinski64d57752015-07-17 11:51:24 -06001748 if 'Destroy' in proto.name:
Michael Lentine13803dc2015-11-04 14:35:12 -08001749 typ = proto.params[-2].ty.strip('*').replace('const ', '');
1750 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ)
1751 name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -06001752 funcs.append('%s\n' % self.lineinfo.get())
Mark Lobodzinski64d57752015-07-17 11:51:24 -06001753 destroy_line = ' loader_platform_thread_lock_mutex(&objLock);\n'
Mark Lobodzinski2141f652015-09-07 13:59:43 -06001754# destroy_line += ' if (result == VK_SUCCESS) {\n'
Michael Lentine13803dc2015-11-04 14:35:12 -08001755 destroy_line += ' destroy_%s(%s, %s);\n' % (name, param0_name, proto.params[-2].name)
Mark Lobodzinski2141f652015-09-07 13:59:43 -06001756# destroy_line += ' }\n'
Mark Lobodzinski64d57752015-07-17 11:51:24 -06001757 destroy_line += ' loader_platform_thread_unlock_mutex(&objLock);\n'
Tobin Ehlis154e0462015-08-26 11:22:09 -06001758 if len(loop_params) > 0:
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -06001759 using_line += ' VkBool32 skipCall = VK_FALSE;\n'
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001760 if not mutex_unlock:
1761 using_line += ' loader_platform_thread_lock_mutex(&objLock);\n'
1762 mutex_unlock = True
Michael Lentine13803dc2015-11-04 14:35:12 -08001763 for lc,lt in zip(loop_params,loop_types):
Tobin Ehlis154e0462015-08-26 11:22:09 -06001764 if 0 == lc: # No looping required for these params
Michael Lentine13803dc2015-11-04 14:35:12 -08001765 for opn,typ in zip(loop_params[lc],loop_types[lt]):
1766 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ)
1767 name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
Tobin Ehlis154e0462015-08-26 11:22:09 -06001768 if '->' in opn:
1769 using_line += ' if (%s)\n' % (opn.split('-')[0])
Michael Lentine13803dc2015-11-04 14:35:12 -08001770 using_line += ' skipCall |= validate_%s(%s, %s);\n' % (name, param0_name, opn)
Tobin Ehlis154e0462015-08-26 11:22:09 -06001771 else:
Mark Lobodzinski308d7792015-11-24 10:28:31 -07001772 if 'AcquireNext' in proto.name and 'fence' == name:
1773 using_line += ' if (fence != VK_NULL_HANDLE) {\n'
1774 using_line += ' skipCall |= validate_%s(%s, %s);\n' % (name, param0_name, opn)
1775 using_line += ' }\n'
Mark Lobodzinskic0ed6d02015-12-07 15:55:11 -07001776 elif ('CreateGraphicsPipelines' in proto.name or 'CreateComputePipelines' in proto.name) and 'pipelineCache' == opn:
1777 using_line += ' // PipelineCache is optional, validate if present\n'
1778 using_line += ' if (pipelineCache != VK_NULL_HANDLE) {\n'
1779 using_line += ' skipCall |= validate_%s(%s, %s);\n' % (name, param0_name, opn)
1780 using_line += ' }\n'
Mark Lobodzinski308d7792015-11-24 10:28:31 -07001781 else:
1782 using_line += ' skipCall |= validate_%s(%s, %s);\n' % (name, param0_name, opn)
Tobin Ehlis9d675942015-06-30 14:32:16 -06001783 else:
Tobin Ehlis154e0462015-08-26 11:22:09 -06001784 base_param = loop_params[lc][0].split('-')[0].split('[')[0]
1785 using_line += ' if (%s) {\n' % base_param
Tobin Ehlisdaab02d2015-10-23 16:57:03 -06001786 using_line += ' for (uint32_t i=0; i<%s; i++) {\n' % lc
Michael Lentine13803dc2015-11-04 14:35:12 -08001787 for opn,typ in zip(loop_params[lc],loop_types[lt]):
1788 name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', typ)
1789 name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()[3:]
Tobin Ehlis82b3db52015-10-23 17:52:53 -06001790 if ',' in opn: # double-embedded loop
1791 (inner_lc, inner_param) = opn.split(',')
1792 using_line += ' if (%s) {\n' % inner_param
1793 using_line += ' for (uint32_t j=0; j<%s; j++) {\n' % inner_lc
Michael Lentine13803dc2015-11-04 14:35:12 -08001794 using_line += ' skipCall |= validate_%s(%s, %s[j]);\n' % (name, param0_name, inner_param)
Tobin Ehlis82b3db52015-10-23 17:52:53 -06001795 using_line += ' }\n'
1796 using_line += ' }\n'
1797 elif '[' in opn: # API func param is array
Michael Lentine13803dc2015-11-04 14:35:12 -08001798 using_line += ' skipCall |= validate_%s(%s, %s);\n' % (name, param0_name, opn)
Tobin Ehlis154e0462015-08-26 11:22:09 -06001799 else: # struct element is array
Michael Lentine13803dc2015-11-04 14:35:12 -08001800 using_line += ' skipCall |= validate_%s(%s, %s[i]);\n' % (name, param0_name, opn)
Tobin Ehlis154e0462015-08-26 11:22:09 -06001801 using_line += ' }\n'
1802 using_line += ' }\n'
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001803 if mutex_unlock:
1804 using_line += ' loader_platform_thread_unlock_mutex(&objLock);\n'
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -06001805 if len(loop_params) > 0:
1806 using_line += ' if (skipCall)\n'
1807 if proto.ret != "void":
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001808 using_line += ' return VK_ERROR_VALIDATION_FAILED_EXT;\n'
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -06001809 else:
1810 using_line += ' return;\n'
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001811 ret_val = ''
1812 stmt = ''
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001813 if proto.ret != "void":
1814 ret_val = "%s result = " % proto.ret
1815 stmt = " return result;\n"
1816
1817 dispatch_param = proto.params[0].name
1818 if 'CreateInstance' in proto.name:
1819 dispatch_param = '*' + proto.params[1].name
1820
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05001821 # Must use 'instance' table for these APIs, 'device' table otherwise
1822 table_type = ""
1823 if proto_is_global(proto):
1824 table_type = "instance"
1825 else:
1826 table_type = "device"
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001827 if wsi_name(proto.name):
1828 funcs.append('%s' % wsi_ifdef(proto.name))
Mike Stroyan00087e62015-04-03 14:39:16 -06001829 funcs.append('%s%s\n'
1830 '{\n'
1831 '%s'
Mike Stroyan00087e62015-04-03 14:39:16 -06001832 '%s'
Mike Stroyan38820b32015-09-28 13:47:29 -06001833 ' %sget_dispatch_table(ObjectTracker_%s_table_map, %s)->%s;\n'
1834 '%s'
1835 '%s'
1836 '}' % (qual, decl, using_line, destroy_line, ret_val, table_type, dispatch_param, proto.c_call(), create_line, stmt))
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001837 if wsi_name(proto.name):
1838 funcs.append('%s' % wsi_endif(proto.name))
Mike Stroyan00087e62015-04-03 14:39:16 -06001839 return "\n\n".join(funcs)
1840
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001841 def generate_body(self):
Mike Stroyan3e3a1eb2015-04-03 17:13:23 -06001842 self.layer_name = "ObjectTracker"
Ian Elliott1064fe32015-07-06 14:31:32 -06001843 extensions=[('wsi_enabled',
Ian Elliott05846062015-11-20 14:13:17 -07001844 ['vkCreateSwapchainKHR',
Jon Ashburn8acd2332015-09-16 18:08:32 -06001845 'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
1846 'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001847 if sys.platform.startswith('win32'):
Michael Lentine64e2ebd2015-12-03 14:33:09 -08001848 instance_extensions=[('msg_callback_get_proc_addr', []),
1849 ('wsi_enabled',
1850 ['vkGetPhysicalDeviceSurfaceSupportKHR',
1851 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
1852 'vkGetPhysicalDeviceSurfaceFormatsKHR',
1853 'vkGetPhysicalDeviceSurfacePresentModesKHR',
1854 'vkCreateWin32SurfaceKHR',
1855 'vkGetPhysicalDeviceWin32PresentationSupportKHR'])]
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001856 elif sys.platform.startswith('linux'):
Michael Lentine64e2ebd2015-12-03 14:33:09 -08001857 instance_extensions=[('msg_callback_get_proc_addr', []),
1858 ('wsi_enabled',
1859 ['vkGetPhysicalDeviceSurfaceSupportKHR',
1860 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
1861 'vkGetPhysicalDeviceSurfaceFormatsKHR',
1862 'vkGetPhysicalDeviceSurfacePresentModesKHR',
1863 'vkCreateXcbSurfaceKHR',
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -07001864 'vkGetPhysicalDeviceXcbPresentationSupportKHR'])]
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -07001865 # TODO: Add cases for Mir, Wayland and Xlib
1866 else: # android
1867 instance_extensions=[('msg_callback_get_proc_addr', []),
1868 ('wsi_enabled',
1869 ['vkGetPhysicalDeviceSurfaceSupportKHR',
1870 'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
1871 'vkGetPhysicalDeviceSurfaceFormatsKHR',
1872 'vkGetPhysicalDeviceSurfacePresentModesKHR'])]
Tony Barboura05dbaa2015-07-09 17:31:46 -06001873 body = [self.generate_maps(),
1874 self.generate_procs(),
Mark Lobodzinski64d57752015-07-17 11:51:24 -06001875 self.generate_destroy_instance(),
1876 self.generate_destroy_device(),
Tony Barboura05dbaa2015-07-09 17:31:46 -06001877 self.generate_command_buffer_validates(),
1878 self._generate_dispatch_entrypoints("VK_LAYER_EXPORT"),
Tobin Ehlisca915872014-11-18 11:28:33 -07001879 self._generate_extensions(),
Jon Ashburn747f2b62015-06-18 15:02:58 -06001880 self._generate_layer_gpa_function(extensions,
Jon Ashburn3dc39382015-09-17 10:00:32 -06001881 instance_extensions)]
Tobin Ehlis12076fc2014-10-22 09:06:33 -06001882 return "\n\n".join(body)
Courtney Goeltzenleuchterb412d212014-11-18 10:40:29 -07001883
Mike Stroyan3712d5c2015-04-02 11:59:05 -06001884class ThreadingSubcommand(Subcommand):
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001885 thread_check_dispatchable_objects = [
1886 "VkQueue",
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001887 "VkCommandBuffer",
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001888 ]
1889 thread_check_nondispatchable_objects = [
1890 "VkDeviceMemory",
1891 "VkBuffer",
1892 "VkImage",
1893 "VkDescriptorSet",
1894 "VkDescriptorPool",
1895 "VkSemaphore"
1896 ]
Mike Stroyan313f7e62015-08-10 16:42:53 -06001897 thread_check_object_types = {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001898 'VkInstance' : 'VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT',
1899 'VkPhysicalDevice' : 'VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT',
1900 'VkDevice' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT',
1901 'VkQueue' : 'VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT',
1902 'VkCommandBuffer' : 'VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT',
1903 'VkFence' : 'VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT',
1904 'VkDeviceMemory' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT',
1905 'VkBuffer' : 'VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT',
1906 'VkImage' : 'VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT',
1907 'VkSemaphore' : 'VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT',
1908 'VkEvent' : 'VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT',
1909 'VkQueryPool' : 'VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT',
1910 'VkBufferView' : 'VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT',
1911 'VkImageView' : 'VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT',
1912 'VkShaderModule' : 'VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT',
1913 'VkShader' : 'VK_DEBUG_REPORT_OBJECT_TYPE_SHADER',
1914 'VkPipelineCache' : 'VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT',
1915 'VkPipelineLayout' : 'VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT',
1916 'VkRenderPass' : 'VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT',
1917 'VkPipeline' : 'VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT',
1918 'VkDescriptorSetLayout' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT',
1919 'VkSampler' : 'VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT',
1920 'VkDescriptorPool' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT',
1921 'VkDescriptorSet' : 'VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT',
1922 'VkFramebuffer' : 'VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT',
1923 'VkCommandPool' : 'VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT',
Mike Stroyan313f7e62015-08-10 16:42:53 -06001924 }
1925 def generate_useObject(self, ty):
1926 obj_type = self.thread_check_object_types[ty]
Chia-I Wue2fc5522015-10-26 20:04:44 +08001927 key = "object"
1928 msg_object = "reinterpret_cast<uint64_t>(object)"
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001929 header_txt = []
1930 header_txt.append('%s' % self.lineinfo.get())
Michael Lentine13803dc2015-11-04 14:35:12 -08001931 header_txt.append('static void use%s(const void* dispatchable_object, %s object)' % (ty, ty))
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001932 header_txt.append('{')
1933 header_txt.append(' loader_platform_thread_id tid = loader_platform_get_thread_id();')
1934 header_txt.append(' loader_platform_thread_lock_mutex(&threadingLock);')
1935 header_txt.append(' if (%sObjectsInUse.find(%s) == %sObjectsInUse.end()) {' % (ty, key, ty))
1936 header_txt.append(' %sObjectsInUse[%s] = tid;' % (ty, key))
1937 header_txt.append(' } else {')
1938 header_txt.append(' if (%sObjectsInUse[%s] != tid) {' % (ty, key))
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001939 header_txt.append(' log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, %s, %s,' % (obj_type, msg_object))
Mike Stroyan313f7e62015-08-10 16:42:53 -06001940 header_txt.append(' /*location*/ 0, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING",')
1941 header_txt.append(' "THREADING ERROR : object of type %s is simultaneously used in thread %%ld and thread %%ld",' % (ty))
1942 header_txt.append(' %sObjectsInUse[%s], tid);' % (ty, key))
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001943 header_txt.append(' // Wait for thread-safe access to object')
1944 header_txt.append(' while (%sObjectsInUse.find(%s) != %sObjectsInUse.end()) {' % (ty, key, ty))
1945 header_txt.append(' loader_platform_thread_cond_wait(&threadingCond, &threadingLock);')
1946 header_txt.append(' }')
1947 header_txt.append(' %sObjectsInUse[%s] = tid;' % (ty, key))
1948 header_txt.append(' } else {')
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001949 header_txt.append(' log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, %s, %s,' % (obj_type, msg_object))
Mike Stroyan313f7e62015-08-10 16:42:53 -06001950 header_txt.append(' /*location*/ 0, THREADING_CHECKER_MULTIPLE_THREADS, "THREADING",')
1951 header_txt.append(' "THREADING ERROR : object of type %s is recursively used in thread %%ld",' % (ty))
1952 header_txt.append(' tid);')
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001953 header_txt.append(' }')
1954 header_txt.append(' }')
1955 header_txt.append(' loader_platform_thread_unlock_mutex(&threadingLock);')
1956 header_txt.append('}')
1957 return "\n".join(header_txt)
Mike Stroyan313f7e62015-08-10 16:42:53 -06001958 def generate_finishUsingObject(self, ty):
Chia-I Wue2fc5522015-10-26 20:04:44 +08001959 key = "object"
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001960 header_txt = []
1961 header_txt.append('%s' % self.lineinfo.get())
Michael Lentine13803dc2015-11-04 14:35:12 -08001962 header_txt.append('static void finishUsing%s(%s object)' % (ty, ty))
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001963 header_txt.append('{')
1964 header_txt.append(' // Object is no longer in use')
1965 header_txt.append(' loader_platform_thread_lock_mutex(&threadingLock);')
1966 header_txt.append(' %sObjectsInUse.erase(%s);' % (ty, key))
1967 header_txt.append(' loader_platform_thread_cond_broadcast(&threadingCond);')
1968 header_txt.append(' loader_platform_thread_unlock_mutex(&threadingLock);')
1969 header_txt.append('}')
1970 return "\n".join(header_txt)
Mike Stroyan3712d5c2015-04-02 11:59:05 -06001971 def generate_header(self):
1972 header_txt = []
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001973 header_txt.append('%s' % self.lineinfo.get())
Mike Stroyan3712d5c2015-04-02 11:59:05 -06001974 header_txt.append('#include <stdio.h>')
1975 header_txt.append('#include <stdlib.h>')
1976 header_txt.append('#include <string.h>')
1977 header_txt.append('#include <unordered_map>')
Tobin Ehlisb835d1b2015-07-03 10:34:49 -06001978 header_txt.append('#include "vk_loader_platform.h"')
David Pinedo9316d3b2015-11-06 12:54:48 -07001979 header_txt.append('#include "vulkan/vk_layer.h"')
Mike Stroyan3712d5c2015-04-02 11:59:05 -06001980 header_txt.append('#include "threading.h"')
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -06001981 header_txt.append('#include "vk_layer_config.h"')
Courtney Goeltzenleuchter3f9f7c42015-07-06 09:11:12 -06001982 header_txt.append('#include "vk_layer_extension_utils.h"')
Mike Stroyan3712d5c2015-04-02 11:59:05 -06001983 header_txt.append('#include "vk_enum_validate_helper.h"')
1984 header_txt.append('#include "vk_struct_validate_helper.h"')
Mike Stroyan313f7e62015-08-10 16:42:53 -06001985 header_txt.append('#include "vk_layer_table.h"')
1986 header_txt.append('#include "vk_layer_logging.h"')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05001987 header_txt.append('')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05001988 header_txt.append('')
1989 header_txt.append('static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(initOnce);')
1990 header_txt.append('')
Mike Stroyan3712d5c2015-04-02 11:59:05 -06001991 header_txt.append('using namespace std;')
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06001992 for ty in self.thread_check_dispatchable_objects:
1993 header_txt.append('static unordered_map<%s, loader_platform_thread_id> %sObjectsInUse;' % (ty, ty))
1994 for ty in self.thread_check_nondispatchable_objects:
Chia-I Wue2fc5522015-10-26 20:04:44 +08001995 header_txt.append('static unordered_map<%s, loader_platform_thread_id> %sObjectsInUse;' % (ty, ty))
Mike Stroyan3712d5c2015-04-02 11:59:05 -06001996 header_txt.append('static int threadingLockInitialized = 0;')
1997 header_txt.append('static loader_platform_thread_mutex threadingLock;')
Mike Stroyaned238bb2015-05-15 08:50:57 -06001998 header_txt.append('static loader_platform_thread_cond threadingCond;')
Tobin Ehlis08fafd02015-06-12 12:49:01 -06001999 header_txt.append('%s' % self.lineinfo.get())
Mike Stroyan313f7e62015-08-10 16:42:53 -06002000 for ty in self.thread_check_dispatchable_objects + self.thread_check_nondispatchable_objects:
2001 header_txt.append(self.generate_useObject(ty))
2002 header_txt.append(self.generate_finishUsingObject(ty))
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06002003 header_txt.append('%s' % self.lineinfo.get())
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002004 return "\n".join(header_txt)
2005
2006 def generate_intercept(self, proto, qual):
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002007 if proto.name in [ 'CreateDebugReportCallbackEXT' ]:
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002008 # use default version
2009 return None
2010 decl = proto.c_func(prefix="vk", attr="VKAPI")
2011 ret_val = ''
2012 stmt = ''
2013 funcs = []
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05002014 table = 'device'
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002015 if proto.ret != "void":
Jon Ashburnb0fbe912015-05-06 10:15:07 -06002016 ret_val = "%s result = " % proto.ret
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002017 stmt = " return result;\n"
Jon Ashburn95a77ba2015-05-15 15:09:35 -06002018 if proto_is_global(proto):
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05002019 table = 'instance'
Jon Ashburn71836d92015-05-12 17:23:55 -06002020
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002021 # Memory range calls are special in needed thread checking within structs
2022 if proto.name in ["FlushMappedMemoryRanges","InvalidateMappedMemoryRanges"]:
Mike Stroyan313f7e62015-08-10 16:42:53 -06002023 funcs.append('%s' % self.lineinfo.get())
2024 funcs.append('%s%s\n' % (qual, decl) +
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002025 '{\n'
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002026 ' for (uint32_t i=0; i<memoryRangeCount; i++) {\n'
Michael Lentine13803dc2015-11-04 14:35:12 -08002027 ' useVkDeviceMemory((const void *) %s, pMemoryRanges[i].memory);\n' % proto.params[0].name +
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002028 ' }\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002029 ' VkLayerDispatchTable *pDeviceTable = get_dispatch_table(Threading_%s_table_map, %s);\n' % (table, proto.params[0].name) +
2030 ' %s pDeviceTable->%s;\n' % (ret_val, proto.c_call()) +
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002031 ' for (uint32_t i=0; i<memoryRangeCount; i++) {\n'
Michael Lentine13803dc2015-11-04 14:35:12 -08002032 ' finishUsingVkDeviceMemory(pMemoryRanges[i].memory);\n'
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002033 ' }\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002034 '%s' % (stmt) +
2035 '}')
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002036 return "\n".join(funcs)
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002037 # All functions that do a Get are thread safe
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002038 if 'Get' in proto.name:
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002039 return None
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002040 # All WSI functions are thread safe
Ian Elliott7e40db92015-08-21 15:09:33 -06002041 if 'KHR' in proto.name:
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002042 return None
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002043 # Initialize in early calls
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -06002044 if proto.name == "CreateDevice":
2045 funcs.append('%s' % self.lineinfo.get())
Mike Stroyan313f7e62015-08-10 16:42:53 -06002046 funcs.append('%s%s\n' % (qual, decl) +
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -06002047 '{\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002048 ' VkLayerDispatchTable *pDeviceTable = get_dispatch_table(Threading_device_table_map, (void *) *pDevice);\n'
2049 ' VkResult result = pDeviceTable->%s;\n' % (proto.c_call()) +
2050 ' if (result == VK_SUCCESS) {\n'
2051 ' layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(%s), layer_data_map);\n' % proto.params[0].name +
2052 ' layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);\n'
2053 ' my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);\n'
2054 ' }\n'
2055 '\n'
2056 ' return result;'
2057 '}')
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -06002058 return "\n".join(funcs)
2059 elif proto.params[0].ty == "VkPhysicalDevice":
Mike Stroyan313f7e62015-08-10 16:42:53 -06002060 return None
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002061 # Functions changing command buffers need thread safe use of first parameter
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002062 if proto.params[0].ty == "VkCommandBuffer":
Tobin Ehlis08fafd02015-06-12 12:49:01 -06002063 funcs.append('%s' % self.lineinfo.get())
Mike Stroyan313f7e62015-08-10 16:42:53 -06002064 funcs.append('%s%s\n' % (qual, decl) +
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002065 '{\n'
Michael Lentine13803dc2015-11-04 14:35:12 -08002066 ' use%s((const void *) %s, %s);\n' % (proto.params[0].ty, proto.params[0].name, proto.params[0].name) +
Mike Stroyan313f7e62015-08-10 16:42:53 -06002067 ' VkLayerDispatchTable *pDeviceTable = get_dispatch_table(Threading_%s_table_map, %s);\n' % (table, proto.params[0].name) +
2068 ' %spDeviceTable->%s;\n' % (ret_val, proto.c_call()) +
Michael Lentine13803dc2015-11-04 14:35:12 -08002069 ' finishUsing%s(%s);\n' % (proto.params[0].ty, proto.params[0].name) +
Mike Stroyan313f7e62015-08-10 16:42:53 -06002070 '%s' % stmt +
2071 '}')
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002072 return "\n".join(funcs)
2073 # Non-Cmd functions that do a Wait are thread safe
2074 if 'Wait' in proto.name:
2075 return None
2076 # Watch use of certain types of objects passed as any parameter
2077 checked_params = []
2078 for param in proto.params:
Mike Stroyanbe2b5d82015-07-09 11:01:07 -06002079 if param.ty in self.thread_check_dispatchable_objects or param.ty in self.thread_check_nondispatchable_objects:
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002080 checked_params.append(param)
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05002081 if proto.name == "DestroyDevice":
Mike Stroyan313f7e62015-08-10 16:42:53 -06002082 funcs.append('%s%s\n' % (qual, decl) +
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05002083 '{\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -06002084 ' dispatch_key key = get_dispatch_key(device);\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002085 ' VkLayerDispatchTable *pDeviceTable = get_dispatch_table(Threading_%s_table_map, %s);\n' % (table, proto.params[0].name) +
2086 ' %spDeviceTable->%s;\n' % (ret_val, proto.c_call()) +
2087 ' Threading_device_table_map.erase(key);\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002088 '}\n')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05002089 return "\n".join(funcs);
2090 elif proto.name == "DestroyInstance":
Mike Stroyan313f7e62015-08-10 16:42:53 -06002091 funcs.append('%s%s\n' % (qual, decl) +
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05002092 '{\n'
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -06002093 ' dispatch_key key = get_dispatch_key(instance);\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002094 ' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(Threading_instance_table_map, %s);\n' % proto.params[0].name +
2095 ' %spInstanceTable->%s;\n' % (ret_val, proto.c_call()) +
Courtney Goeltzenleuchter0daf2282015-06-13 21:22:12 -06002096 ' destroy_instance_dispatch_table(key);\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002097 '\n'
2098 ' // Clean up logging callback, if any\n'
2099 ' layer_data *my_data = get_my_data_ptr(key, layer_data_map);\n'
2100 ' if (my_data->logging_callback) {\n'
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07002101 ' layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback, pAllocator);\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002102 ' }\n'
2103 '\n'
2104 ' layer_debug_report_destroy_instance(my_data->report_data);\n'
2105 ' layer_data_map.erase(pInstanceTable);\n'
2106 '\n'
2107 ' Threading_instance_table_map.erase(key);\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002108 '}\n')
Mark Lobodzinskifb5437a2015-05-22 14:15:36 -05002109 return "\n".join(funcs);
Courtney Goeltzenleuchterd02a9642015-06-08 14:58:39 -06002110 elif proto.name == "CreateInstance":
2111 funcs.append('%s%s\n'
2112 '{\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002113 ' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(Threading_instance_table_map, *pInstance);\n'
Chia-I Wuf7458c52015-10-26 21:10:41 +08002114 ' VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);\n'
Courtney Goeltzenleuchterd02a9642015-06-08 14:58:39 -06002115 '\n'
2116 ' if (result == VK_SUCCESS) {\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002117 ' layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);\n'
2118 ' my_data->report_data = debug_report_create_instance(\n'
2119 ' pInstanceTable,\n'
2120 ' *pInstance,\n'
Chia-I Wud50a7d72015-10-26 20:48:51 +08002121 ' pCreateInfo->enabledExtensionNameCount,\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002122 ' pCreateInfo->ppEnabledExtensionNames);\n'
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -07002123 ' initThreading(my_data, pAllocator);\n'
Courtney Goeltzenleuchterd02a9642015-06-08 14:58:39 -06002124 ' }\n'
2125 ' return result;\n'
Mike Stroyan313f7e62015-08-10 16:42:53 -06002126 '}\n' % (qual, decl))
Courtney Goeltzenleuchterd02a9642015-06-08 14:58:39 -06002127 return "\n".join(funcs);
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002128 if len(checked_params) == 0:
2129 return None
2130 # Surround call with useObject and finishUsingObject for each checked_param
Tobin Ehlis08fafd02015-06-12 12:49:01 -06002131 funcs.append('%s' % self.lineinfo.get())
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002132 funcs.append('%s%s' % (qual, decl))
2133 funcs.append('{')
2134 for param in checked_params:
Michael Lentine13803dc2015-11-04 14:35:12 -08002135 funcs.append(' use%s((const void *) %s, %s);' % (param.ty, proto.params[0].name, param.name))
Mike Stroyan313f7e62015-08-10 16:42:53 -06002136 funcs.append(' VkLayerDispatchTable *pDeviceTable = get_dispatch_table(Threading_%s_table_map, %s);' % (table, proto.params[0].name));
2137 funcs.append(' %spDeviceTable->%s;' % (ret_val, proto.c_call()))
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002138 for param in checked_params:
Michael Lentine13803dc2015-11-04 14:35:12 -08002139 funcs.append(' finishUsing%s(%s);' % (param.ty, param.name))
Mike Stroyan6ea73e42015-05-11 17:18:14 -06002140 funcs.append('%s'
2141 '}' % stmt)
2142 return "\n".join(funcs)
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002143
2144 def generate_body(self):
2145 self.layer_name = "Threading"
Mike Stroyan313f7e62015-08-10 16:42:53 -06002146 body = [self._generate_new_layer_initialization(True, lockname='threading', condname='threading'),
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002147 self._generate_dispatch_entrypoints("VK_LAYER_EXPORT"),
Courtney Goeltzenleuchter17274172015-06-01 14:52:57 -06002148 self._generate_layer_gpa_function(extensions=[],
Jon Ashburn3dc39382015-09-17 10:00:32 -06002149 instance_extensions=[('msg_callback_get_proc_addr', [])]),
Courtney Goeltzenleuchter17274172015-06-01 14:52:57 -06002150 self._gen_create_msg_callback(),
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07002151 self._gen_destroy_msg_callback(),
2152 self._gen_debug_report_msg()]
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002153 return "\n\n".join(body)
2154
Tobin Ehlis12076fc2014-10-22 09:06:33 -06002155def main():
2156 subcommands = {
2157 "layer-funcs" : LayerFuncsSubcommand,
Tobin Ehlisa363cfa2014-11-25 16:59:27 -07002158 "Generic" : GenericLayerSubcommand,
Tobin Ehlise78dbd82015-04-09 09:19:36 -06002159 "APIDump" : APIDumpSubcommand,
Tobin Ehlisa363cfa2014-11-25 16:59:27 -07002160 "ObjectTracker" : ObjectTrackerSubcommand,
Mike Stroyan3712d5c2015-04-02 11:59:05 -06002161 "Threading" : ThreadingSubcommand,
Tobin Ehlis12076fc2014-10-22 09:06:33 -06002162 }
2163
Tobin Ehlis14ff0852014-12-17 17:44:50 -07002164 if len(sys.argv) < 3 or sys.argv[1] not in subcommands or not os.path.exists(sys.argv[2]):
2165 print("Usage: %s <subcommand> <input_header> [options]" % sys.argv[0])
Tobin Ehlis12076fc2014-10-22 09:06:33 -06002166 print
Tobin Ehlis7e65d752015-01-15 17:51:52 -07002167 print("Available subcommands are: %s" % " ".join(subcommands))
Tobin Ehlis12076fc2014-10-22 09:06:33 -06002168 exit(1)
2169
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002170 hfp = vk_helper.HeaderFileParser(sys.argv[2])
Tobin Ehlis14ff0852014-12-17 17:44:50 -07002171 hfp.parse()
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002172 vk_helper.enum_val_dict = hfp.get_enum_val_dict()
2173 vk_helper.enum_type_dict = hfp.get_enum_type_dict()
2174 vk_helper.struct_dict = hfp.get_struct_dict()
2175 vk_helper.typedef_fwd_dict = hfp.get_typedef_fwd_dict()
2176 vk_helper.typedef_rev_dict = hfp.get_typedef_rev_dict()
2177 vk_helper.types_dict = hfp.get_types_dict()
Tobin Ehlis14ff0852014-12-17 17:44:50 -07002178
Tobin Ehlis12076fc2014-10-22 09:06:33 -06002179 subcmd = subcommands[sys.argv[1]](sys.argv[2:])
2180 subcmd.run()
2181
2182if __name__ == "__main__":
2183 main()