blob: 624e08d27ecf0cc58c4bf6f1dee378b2d2c1202c [file] [log] [blame]
Tobin Ehlis42586532014-11-14 13:01:02 -07001/*
Tobin Ehlis42586532014-11-14 13:01:02 -07002 *
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Michael Lentine64e2ebd2015-12-03 14:33:09 -08004 * Copyright (C) 2015 Google Inc.
Tobin Ehlis42586532014-11-14 13:01:02 -07005 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060023 *
24 * Author: Jon Ashburn <jon@lunarg.com>
25 * Author: Mark Lobodzinski <mark@lunarg.com>
26 * Author: Tobin Ehlis <tobin@lunarg.com>
Tobin Ehlis42586532014-11-14 13:01:02 -070027 */
28
David Pinedo9316d3b2015-11-06 12:54:48 -070029#include "vulkan/vk_layer.h"
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060030#include "vk_layer_extension_utils.h"
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060031#include "vk_enum_string_helper.h"
Mark Lobodzinskifae78852015-06-23 11:35:12 -060032
Tobin Ehlisca915872014-11-18 11:28:33 -070033// Object Tracker ERROR codes
34typedef enum _OBJECT_TRACK_ERROR
35{
Chia-I Wu09cf5f02015-01-05 14:33:42 +080036 OBJTRACK_NONE, // Used for INFO & other non-error messages
37 OBJTRACK_UNKNOWN_OBJECT, // Updating uses of object that's not in global object list
38 OBJTRACK_INTERNAL_ERROR, // Bug with data tracking within the layer
39 OBJTRACK_DESTROY_OBJECT_FAILED, // Couldn't find object to be destroyed
Chia-I Wu09cf5f02015-01-05 14:33:42 +080040 OBJTRACK_OBJECT_LEAK, // OBJECT was not correctly freed/destroyed
41 OBJTRACK_OBJCOUNT_MAX_EXCEEDED, // Request for Object data in excess of max obj count
Tobin Ehlis803cc492015-06-08 17:36:28 -060042 OBJTRACK_INVALID_OBJECT, // Object used that has never been created
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -070043 OBJTRACK_DESCRIPTOR_POOL_MISMATCH, // Descriptor Pools specified incorrectly
44 OBJTRACK_COMMAND_POOL_MISMATCH, // Command Pools specified incorrectly
Tobin Ehlisca915872014-11-18 11:28:33 -070045} OBJECT_TRACK_ERROR;
46
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070047// Object Status -- used to track state of individual objects
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050048typedef VkFlags ObjectStatusFlags;
49typedef enum _ObjectStatusFlagBits
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070050{
Mark Lobodzinski40370872015-02-03 10:06:31 -060051 OBJSTATUS_NONE = 0x00000000, // No status is set
52 OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted
53 OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound
54 OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound
55 OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound
56 OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound
Mark Lobodzinski4988dea2015-02-03 11:52:26 -060057 OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050058} ObjectStatusFlagBits;
Chia-I Wuf8693382015-04-16 22:02:10 +080059
Tobin Ehlis42586532014-11-14 13:01:02 -070060typedef struct _OBJTRACK_NODE {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060061 uint64_t vkObj; // Object handle
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -070062 VkDebugReportObjectTypeLUNARG objType; // Object type identifier
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060063 ObjectStatusFlags status; // Object state
64 uint64_t parentObj; // Parent object
Tobin Ehlis42586532014-11-14 13:01:02 -070065} OBJTRACK_NODE;
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060066
Tobin Ehlis42586532014-11-14 13:01:02 -070067// prototype for extension functions
Mark Lobodzinskifae78852015-06-23 11:35:12 -060068uint64_t objTrackGetObjectCount(VkDevice device);
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -070069uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDebugReportObjectTypeLUNARG type);
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060070
Tobin Ehlisca915872014-11-18 11:28:33 -070071// Func ptr typedefs
Mark Lobodzinskifae78852015-06-23 11:35:12 -060072typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -070073typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDebugReportObjectTypeLUNARG);
Mark Lobodzinskifae78852015-06-23 11:35:12 -060074
Cody Northrop55443ef2015-09-28 15:09:32 -060075struct layer_data {
Mark Lobodzinskifae78852015-06-23 11:35:12 -060076 debug_report_data *report_data;
77 //TODO: put instance data here
78 VkDbgMsgCallback logging_callback;
Ian Elliott1064fe32015-07-06 14:31:32 -060079 bool wsi_enabled;
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060080 bool objtrack_extensions_enabled;
Cody Northrop55443ef2015-09-28 15:09:32 -060081
82 layer_data() :
83 report_data(nullptr),
Michael Lentine13803dc2015-11-04 14:35:12 -080084 logging_callback(VK_NULL_HANDLE),
Cody Northrop55443ef2015-09-28 15:09:32 -060085 wsi_enabled(false),
86 objtrack_extensions_enabled(false)
87 {};
88};
Mark Lobodzinskifae78852015-06-23 11:35:12 -060089
Jon Ashburn3dc39382015-09-17 10:00:32 -060090struct instExts {
91 bool wsi_enabled;
92};
93
94static std::unordered_map<void *, struct instExts> instanceExtMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -060095static std::unordered_map<void*, layer_data *> layer_data_map;
96static device_table_map ObjectTracker_device_table_map;
97static instance_table_map ObjectTracker_instance_table_map;
98
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060099// We need additionally validate image usage using a separate map
100// of swapchain-created images
Michael Lentine13803dc2015-11-04 14:35:12 -0800101static unordered_map<uint64_t, OBJTRACK_NODE*> swapchainImageMap;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600102
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600103static long long unsigned int object_track_index = 0;
104static int objLockInitialized = 0;
105static loader_platform_thread_mutex objLock;
106
107// Objects stored in a global map w/ struct containing basic info
Tony Barboura05dbaa2015-07-09 17:31:46 -0600108// unordered_map<const void*, OBJTRACK_NODE*> objMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600109
Tony Barboura05dbaa2015-07-09 17:31:46 -0600110#define NUM_OBJECT_TYPES VK_OBJECT_TYPE_NUM
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600111
112static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
113static uint64_t numTotalObjs = 0;
Cody Northropd0802882015-08-03 17:04:53 -0600114static VkQueueFamilyProperties *queueInfo = NULL;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600115static uint32_t queueCount = 0;
116
117template layer_data *get_my_data_ptr<layer_data>(
118 void *data_key, std::unordered_map<void *, layer_data *> &data_map);
119
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700120static inline const char* string_VkDebugReportObjectTypeLUNARG(VkDebugReportObjectTypeLUNARG input_value)
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600121{
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700122 switch ((VkDebugReportObjectTypeLUNARG)input_value)
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600123 {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800124 case VK_OBJECT_TYPE_COMMAND_POOL:
125 return "VK_OBJECT_TYPE_COMMAND_POOL";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600126 case VK_OBJECT_TYPE_BUFFER:
127 return "VK_OBJECT_TYPE_BUFFER";
128 case VK_OBJECT_TYPE_BUFFER_VIEW:
129 return "VK_OBJECT_TYPE_BUFFER_VIEW";
130 case VK_OBJECT_TYPE_ATTACHMENT_VIEW:
131 return "VK_OBJECT_TYPE_ATTACHMENT_VIEW";
132 case VK_OBJECT_TYPE_COMMAND_BUFFER:
133 return "VK_OBJECT_TYPE_COMMAND_BUFFER";
134 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
135 return "VK_OBJECT_TYPE_DESCRIPTOR_POOL";
136 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
137 return "VK_OBJECT_TYPE_DESCRIPTOR_SET";
138 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
139 return "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT";
140 case VK_OBJECT_TYPE_DEVICE:
141 return "VK_OBJECT_TYPE_DEVICE";
142 case VK_OBJECT_TYPE_DEVICE_MEMORY:
143 return "VK_OBJECT_TYPE_DEVICE_MEMORY";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600144 case VK_OBJECT_TYPE_EVENT:
145 return "VK_OBJECT_TYPE_EVENT";
146 case VK_OBJECT_TYPE_FENCE:
147 return "VK_OBJECT_TYPE_FENCE";
148 case VK_OBJECT_TYPE_FRAMEBUFFER:
149 return "VK_OBJECT_TYPE_FRAMEBUFFER";
150 case VK_OBJECT_TYPE_IMAGE:
151 return "VK_OBJECT_TYPE_IMAGE";
152 case VK_OBJECT_TYPE_IMAGE_VIEW:
153 return "VK_OBJECT_TYPE_IMAGE_VIEW";
154 case VK_OBJECT_TYPE_INSTANCE:
155 return "VK_OBJECT_TYPE_INSTANCE";
156 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
157 return "VK_OBJECT_TYPE_PHYSICAL_DEVICE";
158 case VK_OBJECT_TYPE_PIPELINE:
159 return "VK_OBJECT_TYPE_PIPELINE";
160 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
161 return "VK_OBJECT_TYPE_PIPELINE_LAYOUT";
162 case VK_OBJECT_TYPE_PIPELINE_CACHE:
163 return "VK_OBJECT_TYPE_PIPELINE_CACHE";
164 case VK_OBJECT_TYPE_QUERY_POOL:
165 return "VK_OBJECT_TYPE_QUERY_POOL";
166 case VK_OBJECT_TYPE_QUEUE:
167 return "VK_OBJECT_TYPE_QUEUE";
168 case VK_OBJECT_TYPE_RENDER_PASS:
169 return "VK_OBJECT_TYPE_RENDER_PASS";
170 case VK_OBJECT_TYPE_SAMPLER:
171 return "VK_OBJECT_TYPE_SAMPLER";
172 case VK_OBJECT_TYPE_SEMAPHORE:
173 return "VK_OBJECT_TYPE_SEMAPHORE";
174 case VK_OBJECT_TYPE_SHADER:
175 return "VK_OBJECT_TYPE_SHADER";
176 case VK_OBJECT_TYPE_SHADER_MODULE:
177 return "VK_OBJECT_TYPE_SHADER_MODULE";
Ian Elliott7e40db92015-08-21 15:09:33 -0600178 case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
179 return "VK_OBJECT_TYPE_SWAPCHAIN_KHR";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600180 default:
181 return "Unhandled VkObjectType";
182 }
183}
184
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600185//
186// Internal Object Tracker Functions
187//
188
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600189static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
190{
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600191 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600192 VkLayerDispatchTable *pDisp = get_dispatch_table(ObjectTracker_device_table_map, device);
193 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
Jon Ashburn8acd2332015-09-16 18:08:32 -0600194 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
195 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
196 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
197 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
198 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
Ian Elliott1064fe32015-07-06 14:31:32 -0600199 my_device_data->wsi_enabled = false;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800200 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700201 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliott1064fe32015-07-06 14:31:32 -0600202 my_device_data->wsi_enabled = true;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600203
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600204 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0)
205 my_device_data->objtrack_extensions_enabled = true;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600206 }
207}
208
Jon Ashburn3dc39382015-09-17 10:00:32 -0600209static void createInstanceRegisterExtensions(const VkInstanceCreateInfo* pCreateInfo, VkInstance instance)
210{
211 uint32_t i;
212 VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(ObjectTracker_instance_table_map, instance);
213 PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
214 pDisp->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
Ian Elliott05846062015-11-20 14:13:17 -0700215 pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
216 pDisp->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
217 pDisp->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
Mark Lobodzinskie86e1382015-11-24 15:50:44 -0700218
219#if VK_USE_PLATFORM_WIN32_KHR
220 pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) gpa(instance, "vkCreateWin32SurfaceKHR");
221 pDisp->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700222#endif // VK_USE_PLATFORM_WIN32_KHR
223#ifdef VK_USE_PLATFORM_XCB_KHR
Mark Lobodzinskie86e1382015-11-24 15:50:44 -0700224 pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) gpa(instance, "vkCreateXcbSurfaceKHR");
225 pDisp->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700226#endif // VK_USE_PLATFORM_XCB_KHR
227#ifdef VK_USE_PLATFORM_XLIB_KHR
228 pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR) gpa(instance, "vkCreateXlibSurfaceKHR");
229 pDisp->GetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
230#endif // VK_USE_PLATFORM_XLIB_KHR
231#ifdef VK_USE_PLATFORM_MIR_KHR
232 pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR) gpa(instance, "vkCreateMirSurfaceKHR");
233 pDisp->GetPhysicalDeviceMirPresentationSupportKHR = (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
234#endif // VK_USE_PLATFORM_MIR_KHR
235#ifdef VK_USE_PLATFORM_WAYLAND_KHR
236 pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR) gpa(instance, "vkCreateWaylandSurfaceKHR");
237 pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
238#endif // VK_USE_PLATFORM_WAYLAND_KHR
239#ifdef VK_USE_PLATFORM_ANDROID_KHR
240 pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR) gpa(instance, "vkCreateAndroidSurfaceKHR");
241#endif // VK_USE_PLATFORM_ANDROID_KHR
Mark Lobodzinskie86e1382015-11-24 15:50:44 -0700242
Jon Ashburn3dc39382015-09-17 10:00:32 -0600243 instanceExtMap[pDisp].wsi_enabled = false;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800244 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700245 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
Jon Ashburn3dc39382015-09-17 10:00:32 -0600246 instanceExtMap[pDisp].wsi_enabled = true;
247
248 }
249}
250
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600251// Indicate device or instance dispatch table type
252typedef enum _DispTableType
253{
254 DISP_TBL_TYPE_INSTANCE,
255 DISP_TBL_TYPE_DEVICE,
256} DispTableType;
257
Tony Barboura05dbaa2015-07-09 17:31:46 -0600258debug_report_data *mdd(const void* object)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600259{
260 dispatch_key key = get_dispatch_key(object);
261 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600262 return my_data->report_data;
263}
264
265debug_report_data *mid(VkInstance object)
266{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600267 dispatch_key key = get_dispatch_key(object);
268 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600269 return my_data->report_data;
270}
271
272// For each Queue's doubly linked-list of mem refs
273typedef struct _OT_MEM_INFO {
274 VkDeviceMemory mem;
275 struct _OT_MEM_INFO *pNextMI;
276 struct _OT_MEM_INFO *pPrevMI;
277
278} OT_MEM_INFO;
279
280// Track Queue information
281typedef struct _OT_QUEUE_INFO {
282 OT_MEM_INFO *pMemRefList;
283 struct _OT_QUEUE_INFO *pNextQI;
284 uint32_t queueNodeIndex;
285 VkQueue queue;
286 uint32_t refCount;
287} OT_QUEUE_INFO;
288
289// Global list of QueueInfo structures, one per queue
290static OT_QUEUE_INFO *g_pQueueInfo = NULL;
291
292// Convert an object type enum to an object type array index
293static uint32_t
294objTypeToIndex(
295 uint32_t objType)
296{
297 uint32_t index = objType;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600298 return index;
299}
300
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600301// Add new queue to head of global queue list
302static void
303addQueueInfo(
304 uint32_t queueNodeIndex,
305 VkQueue queue)
306{
307 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
308
309 if (pQueueInfo != NULL) {
310 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
311 pQueueInfo->queue = queue;
312 pQueueInfo->queueNodeIndex = queueNodeIndex;
313 pQueueInfo->pNextQI = g_pQueueInfo;
314 g_pQueueInfo = pQueueInfo;
315 }
316 else {
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700317 log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<uint64_t>(queue), 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK",
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600318 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
319 }
320}
321
322// Destroy memRef lists and free all memory
323static void
324destroyQueueMemRefLists(void)
325{
326 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
327 OT_QUEUE_INFO *pDelQueueInfo = NULL;
328 while (pQueueInfo != NULL) {
329 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
330 while (pMemInfo != NULL) {
331 OT_MEM_INFO *pDelMemInfo = pMemInfo;
332 pMemInfo = pMemInfo->pNextMI;
333 delete pDelMemInfo;
334 }
335 pDelQueueInfo = pQueueInfo;
336 pQueueInfo = pQueueInfo->pNextQI;
337 delete pDelQueueInfo;
338 }
339 g_pQueueInfo = pQueueInfo;
340}
341
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600342static void
343setGpuQueueInfoState(
Tony Barbour59a47322015-06-24 16:06:58 -0600344 uint32_t count,
345 void *pData)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600346{
Tony Barbour59a47322015-06-24 16:06:58 -0600347 queueCount = count;
Cody Northropd0802882015-08-03 17:04:53 -0600348 queueInfo = (VkQueueFamilyProperties*)realloc((void*)queueInfo, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600349 if (queueInfo != NULL) {
Cody Northropd0802882015-08-03 17:04:53 -0600350 memcpy(queueInfo, pData, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600351 }
352}
353
354// Check Queue type flags for selected queue operations
355static void
356validateQueueFlags(
357 VkQueue queue,
358 const char *function)
359{
360 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
361 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
362 pQueueInfo = pQueueInfo->pNextQI;
363 }
364 if (pQueueInfo != NULL) {
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800365 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700366 log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<uint64_t>(queue), 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800367 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600368 } else {
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700369 log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<uint64_t>(queue), 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800370 "Attempting %s on a possibly non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not known", function);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600371 }
372 }
373}
374
Tony Barboura05dbaa2015-07-09 17:31:46 -0600375/* TODO: Port to new type safety */
376#if 0
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600377// Check object status for selected flag state
Courtney Goeltzenleuchtercd2a0992015-07-09 11:44:38 -0600378static VkBool32
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600379validate_status(
380 VkObject dispatchable_object,
381 VkObject vkObj,
382 VkObjectType objType,
383 ObjectStatusFlags status_mask,
384 ObjectStatusFlags status_flag,
385 VkFlags msg_flags,
386 OBJECT_TRACK_ERROR error_code,
387 const char *fail_msg)
388{
389 if (objMap.find(vkObj) != objMap.end()) {
390 OBJTRACK_NODE* pNode = objMap[vkObj];
391 if ((pNode->status & status_mask) != status_flag) {
392 char str[1024];
393 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
394 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600395 reinterpret_cast<uint64_t>(vkObj), fail_msg);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600396 return VK_FALSE;
397 }
398 return VK_TRUE;
399 }
400 else {
401 // If we do not find it print an error
402 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
403 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600404 reinterpret_cast<uint64_t>(vkObj), string_VkObjectType(objType));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600405 return VK_FALSE;
406 }
407}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600408#endif
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600409
410#include "vk_dispatch_table_helper.h"
411static void
412initObjectTracker(
413 layer_data *my_data)
414{
415 uint32_t report_flags = 0;
416 uint32_t debug_action = 0;
417 FILE *log_output = NULL;
418 const char *option_str;
419 // initialize ObjectTracker options
420 report_flags = getLayerOptionFlags("ObjectTrackerReportFlags", 0);
421 getLayerOptionEnum("ObjectTrackerDebugAction", (uint32_t *) &debug_action);
422
423 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
424 {
425 option_str = getLayerOption("ObjectTrackerLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600426 log_output = getLayerLogOutput(option_str, "ObjectTracker");
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700427 layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &(my_data->logging_callback));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600428 }
429
430 if (!objLockInitialized)
431 {
432 // TODO/TBD: Need to delete this mutex sometime. How??? One
433 // suggestion is to call this during vkCreateInstance(), and then we
434 // can clean it up during vkDestroyInstance(). However, that requires
435 // that the layer have per-instance locks. We need to come back and
436 // address this soon.
437 loader_platform_thread_create_mutex(&objLock);
438 objLockInitialized = 1;
439 }
440}
441
Tony Barboura05dbaa2015-07-09 17:31:46 -0600442//
443// Forward declares of generated routines
444//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600445
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700446static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeLUNARG objType);
447static void create_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeLUNARG objType);
448static void create_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeLUNARG objType);
449static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeLUNARG objType);
Michael Lentine13803dc2015-11-04 14:35:12 -0800450static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object);
451static VkBool32 validate_image(VkCommandBuffer dispatchable_object, VkImage object);
452static VkBool32 validate_command_buffer(VkQueue dispatchable_object, VkCommandBuffer object);
453static VkBool32 validate_descriptor_set(VkCommandBuffer dispatchable_object, VkDescriptorSet object);
454static VkBool32 validate_instance(VkInstance dispatchable_object, VkInstance object);
455static VkBool32 validate_device(VkDevice dispatchable_object, VkDevice object);
456static VkBool32 validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
457static VkBool32 validate_descriptor_set_layout(VkDevice dispatchable_object, VkDescriptorSetLayout object);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700458static VkBool32 validate_command_pool(VkDevice dispatchable_object, VkCommandPool object);
459static void destroy_command_pool(VkDevice dispatchable_object, VkCommandPool object);
460static void destroy_command_buffer(VkCommandBuffer dispatchable_object, VkCommandBuffer object);
461static void destroy_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
462static void destroy_descriptor_set(VkDevice dispatchable_object, VkDescriptorSet object);
Michael Lentine13803dc2015-11-04 14:35:12 -0800463static void destroy_instance(VkInstance dispatchable_object, VkInstance object);
464static void destroy_device_memory(VkDevice dispatchable_object, VkDeviceMemory object);
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700465static VkBool32 set_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeLUNARG objType, ObjectStatusFlags status_flag);
466static VkBool32 reset_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeLUNARG objType, ObjectStatusFlags status_flag);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600467#if 0
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700468static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDebugReportObjectTypeLUNARG objType,
Tony Barboura05dbaa2015-07-09 17:31:46 -0600469 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
470 const char *fail_msg);
471#endif
Michael Lentine13803dc2015-11-04 14:35:12 -0800472extern unordered_map<uint64_t, OBJTRACK_NODE*> VkPhysicalDeviceMap;
473extern unordered_map<uint64_t, OBJTRACK_NODE*> VkImageMap;
474extern unordered_map<uint64_t, OBJTRACK_NODE*> VkQueueMap;
475extern unordered_map<uint64_t, OBJTRACK_NODE*> VkDescriptorSetMap;
476extern unordered_map<uint64_t, OBJTRACK_NODE*> VkBufferMap;
477extern unordered_map<uint64_t, OBJTRACK_NODE*> VkFenceMap;
478extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSemaphoreMap;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700479extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandPoolMap;
Michael Lentine13803dc2015-11-04 14:35:12 -0800480extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandBufferMap;
481extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSwapchainKHRMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600482
Michael Lentine13803dc2015-11-04 14:35:12 -0800483static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600484{
Michael Lentine13803dc2015-11-04 14:35:12 -0800485 if ((VkImageMap.find(reinterpret_cast<uint64_t>(object)) == VkImageMap.end()) &&
486 (swapchainImageMap.find(reinterpret_cast<uint64_t>(object)) == swapchainImageMap.end())) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700487 return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800488 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600489 }
490 return VK_FALSE;
491}
492
Michael Lentine13803dc2015-11-04 14:35:12 -0800493static VkBool32 validate_image(VkCommandBuffer dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600494{
Michael Lentine13803dc2015-11-04 14:35:12 -0800495 if ((VkImageMap.find(reinterpret_cast<uint64_t>(object)) == VkImageMap.end()) &&
496 (swapchainImageMap.find(reinterpret_cast<uint64_t>(object)) == swapchainImageMap.end())) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700497 return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800498 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600499 }
500 return VK_FALSE;
501}
502
Michael Lentine13803dc2015-11-04 14:35:12 -0800503static VkBool32 validate_command_buffer(VkQueue dispatchable_object, VkCommandBuffer object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600504{
Michael Lentine13803dc2015-11-04 14:35:12 -0800505 if (VkCommandBufferMap.find(reinterpret_cast<uint64_t>(object)) == VkCommandBufferMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700506 return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, reinterpret_cast<uint64_t>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800507 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600508 }
509 return VK_FALSE;
510}
511
Michael Lentine13803dc2015-11-04 14:35:12 -0800512static VkBool32 validate_descriptor_set(VkCommandBuffer dispatchable_object, VkDescriptorSet object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600513{
Michael Lentine13803dc2015-11-04 14:35:12 -0800514 if (VkDescriptorSetMap.find(reinterpret_cast<uint64_t>(object)) == VkDescriptorSetMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700515 return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800516 "Invalid VkDescriptorSet Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600517 }
518 return VK_FALSE;
519}
520
Michael Lentine13803dc2015-11-04 14:35:12 -0800521static VkBool32 validate_buffer(VkQueue dispatchable_object, VkBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600522{
Michael Lentine13803dc2015-11-04 14:35:12 -0800523 if (VkBufferMap.find(reinterpret_cast<uint64_t>(object)) != VkBufferMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700524 return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800525 "Invalid VkBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600526 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600527 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600528}
529
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700530static VkBool32 set_status(VkQueue dispatchable_object, VkFence object, VkDebugReportObjectTypeLUNARG objType, ObjectStatusFlags status_flag)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600531{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600532 VkBool32 skipCall = VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600533 if (object != VK_NULL_HANDLE) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800534 if (VkFenceMap.find(reinterpret_cast<uint64_t>(object)) != VkFenceMap.end()) {
535 OBJTRACK_NODE* pNode = VkFenceMap[reinterpret_cast<uint64_t>(object)];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600536 pNode->status |= status_flag;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600537 }
538 else {
539 // If we do not find it print an error
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700540 skipCall |= log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, (uint64_t) object, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barboura05dbaa2015-07-09 17:31:46 -0600541 "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700542 reinterpret_cast<uint64_t>(object), string_VkDebugReportObjectTypeLUNARG(objType));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600543 }
544 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600545 return skipCall;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600546}
547
Michael Lentine13803dc2015-11-04 14:35:12 -0800548static VkBool32 validate_semaphore(VkQueue dispatchable_object, VkSemaphore object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600549{
Michael Lentine13803dc2015-11-04 14:35:12 -0800550 if (VkSemaphoreMap.find(reinterpret_cast<uint64_t>(object)) == VkSemaphoreMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700551 return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800552 "Invalid VkSemaphore Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600553 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600554 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600555}
556
Michael Lentine13803dc2015-11-04 14:35:12 -0800557static VkBool32 validate_command_buffer(VkDevice dispatchable_object, VkCommandBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600558{
Michael Lentine13803dc2015-11-04 14:35:12 -0800559 if (VkCommandBufferMap.find(reinterpret_cast<uint64_t>(object)) == VkCommandBufferMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700560 return log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, reinterpret_cast<uint64_t>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800561 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600562 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600563 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600564}
565
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700566static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeLUNARG objType)
Tobin Ehlisec598302015-09-15 15:02:17 -0600567{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700568 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700569 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Tobin Ehlisec598302015-09-15 15:02:17 -0600570 reinterpret_cast<uint64_t>(vkObj));
571
572 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
573 pNewObjNode->objType = objType;
574 pNewObjNode->status = OBJSTATUS_NONE;
575 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800576 VkPhysicalDeviceMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600577 uint32_t objIndex = objTypeToIndex(objType);
578 numObjs[objIndex]++;
579 numTotalObjs++;
580}
581
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700582static void create_surface_khr(VkInstance instance, VkSurfaceKHR surface, VkDebugReportObjectTypeLUNARG objType)
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700583{
584 // TODO: Add tracking of surface objects
585}
586
587static void destroy_surface_khr(VkInstance instance, VkSurfaceKHR surface)
588{
589 // TODO: Add tracking of surface objects
590}
591
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700592static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer vkObj, VkDebugReportObjectTypeLUNARG objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600593{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700594 log_msg(mdd(device), VK_DEBUG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700595 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600596 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600597
598 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700599 pNewObjNode->objType = objType;
600 pNewObjNode->status = OBJSTATUS_NONE;
601 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
602 pNewObjNode->parentObj = (uint64_t) commandPool;
Michael Lentine13803dc2015-11-04 14:35:12 -0800603 VkCommandBufferMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600604 uint32_t objIndex = objTypeToIndex(objType);
605 numObjs[objIndex]++;
606 numTotalObjs++;
607}
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700608
Michael Lentinefc6aa762015-11-20 12:11:42 -0800609static void free_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700610{
611 uint64_t object_handle = reinterpret_cast<uint64_t>(commandBuffer);
612 if (VkCommandBufferMap.find(object_handle) != VkCommandBufferMap.end()) {
613 OBJTRACK_NODE* pNode = VkCommandBufferMap[(uint64_t)commandBuffer];
614
615 if (pNode->parentObj != reinterpret_cast<uint64_t>(commandPool)) {
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700616 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT, pNode->objType, object_handle, 0, OBJTRACK_COMMAND_POOL_MISMATCH, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700617 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
618 reinterpret_cast<uint64_t>(commandBuffer), pNode->parentObj, reinterpret_cast<uint64_t>(commandPool));
619 } else {
620
621 uint32_t objIndex = objTypeToIndex(pNode->objType);
622 assert(numTotalObjs > 0);
623 numTotalObjs--;
624 assert(numObjs[objIndex] > 0);
625 numObjs[objIndex]--;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700626 log_msg(mdd(device), VK_DEBUG_REPORT_INFO_BIT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700627 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700628 string_VkDebugReportObjectTypeLUNARG(pNode->objType), reinterpret_cast<uint64_t>(commandBuffer), numTotalObjs, numObjs[objIndex],
629 string_VkDebugReportObjectTypeLUNARG(pNode->objType));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700630 delete pNode;
631 VkCommandBufferMap.erase(object_handle);
632 }
633 } else {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700634 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700635 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
636 object_handle);
637 }
638}
639
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700640static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet vkObj, VkDebugReportObjectTypeLUNARG objType)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700641{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700642 log_msg(mdd(device), VK_DEBUG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700643 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700644 reinterpret_cast<uint64_t>(vkObj));
645
646 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
647 pNewObjNode->objType = objType;
648 pNewObjNode->status = OBJSTATUS_NONE;
649 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
650 pNewObjNode->parentObj = (uint64_t) descriptorPool;
651 VkDescriptorSetMap[(uint64_t)vkObj] = pNewObjNode;
652 uint32_t objIndex = objTypeToIndex(objType);
653 numObjs[objIndex]++;
654 numTotalObjs++;
655}
656
Michael Lentinefc6aa762015-11-20 12:11:42 -0800657static void free_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet descriptorSet)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700658{
659 uint64_t object_handle = reinterpret_cast<uint64_t>(descriptorSet);
660 if (VkDescriptorSetMap.find(object_handle) != VkDescriptorSetMap.end()) {
661 OBJTRACK_NODE* pNode = VkDescriptorSetMap[(uint64_t)descriptorSet];
662
663 if (pNode->parentObj != reinterpret_cast<uint64_t>(descriptorPool)) {
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700664 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT, pNode->objType, object_handle, 0, OBJTRACK_DESCRIPTOR_POOL_MISMATCH, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700665 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
666 reinterpret_cast<uint64_t>(descriptorSet), pNode->parentObj, reinterpret_cast<uint64_t>(descriptorPool));
667 } else {
668 uint32_t objIndex = objTypeToIndex(pNode->objType);
669 assert(numTotalObjs > 0);
670 numTotalObjs--;
671 assert(numObjs[objIndex] > 0);
672 numObjs[objIndex]--;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700673 log_msg(mdd(device), VK_DEBUG_REPORT_INFO_BIT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700674 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700675 string_VkDebugReportObjectTypeLUNARG(pNode->objType), reinterpret_cast<uint64_t>(descriptorSet), numTotalObjs, numObjs[objIndex],
676 string_VkDebugReportObjectTypeLUNARG(pNode->objType));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700677 delete pNode;
678 VkDescriptorSetMap.erase(object_handle);
679 }
680 } else {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700681 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700682 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
683 object_handle);
684 }
685}
686
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700687static void create_swapchain_khr(VkDevice dispatchable_object, VkSwapchainKHR vkObj, VkDebugReportObjectTypeLUNARG objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600688{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700689 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFO_BIT, objType, (uint64_t) vkObj, 0, OBJTRACK_NONE, "OBJTRACK",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700690 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Michael Lentine13803dc2015-11-04 14:35:12 -0800691 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600692
693 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
694 pNewObjNode->objType = objType;
695 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800696 pNewObjNode->vkObj = (uint64_t) vkObj;
Michael Lentine13803dc2015-11-04 14:35:12 -0800697 VkSwapchainKHRMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600698 uint32_t objIndex = objTypeToIndex(objType);
699 numObjs[objIndex]++;
700 numTotalObjs++;
701}
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700702static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeLUNARG objType)
Tobin Ehlisec598302015-09-15 15:02:17 -0600703{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700704 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700705 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Tobin Ehlisec598302015-09-15 15:02:17 -0600706 reinterpret_cast<uint64_t>(vkObj));
707
708 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
709 pNewObjNode->objType = objType;
710 pNewObjNode->status = OBJSTATUS_NONE;
711 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800712 VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600713 uint32_t objIndex = objTypeToIndex(objType);
714 numObjs[objIndex]++;
715 numTotalObjs++;
716}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600717static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain)
718{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700719 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFO_BIT, VK_OBJECT_TYPE_IMAGE, (uint64_t) vkObj, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600720 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, "SwapchainImage",
Michael Lentine13803dc2015-11-04 14:35:12 -0800721 reinterpret_cast<uint64_t>(vkObj));
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600722
723 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
724 pNewObjNode->objType = VK_OBJECT_TYPE_IMAGE;
725 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800726 pNewObjNode->vkObj = (uint64_t) vkObj;
727 pNewObjNode->parentObj = (uint64_t) swapchain;
Michael Lentine13803dc2015-11-04 14:35:12 -0800728 swapchainImageMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600729}
730
Michael Lentine13803dc2015-11-04 14:35:12 -0800731static void destroy_swapchain(VkDevice dispatchable_object, VkSwapchainKHR object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600732{
Michael Lentine13803dc2015-11-04 14:35:12 -0800733 if (VkSwapchainKHRMap.find(reinterpret_cast<uint64_t>(object)) != VkSwapchainKHRMap.end()) {
734 OBJTRACK_NODE* pNode = VkSwapchainKHRMap[reinterpret_cast<uint64_t>(object)];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600735 uint32_t objIndex = objTypeToIndex(pNode->objType);
736 assert(numTotalObjs > 0);
737 numTotalObjs--;
738 assert(numObjs[objIndex] > 0);
739 numObjs[objIndex]--;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700740 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFO_BIT, pNode->objType, (uint64_t) object, 0, OBJTRACK_NONE, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800741 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700742 string_VkDebugReportObjectTypeLUNARG(pNode->objType), (uint64_t) object, numTotalObjs, numObjs[objIndex],
743 string_VkDebugReportObjectTypeLUNARG(pNode->objType));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600744 delete pNode;
Michael Lentine13803dc2015-11-04 14:35:12 -0800745 VkSwapchainKHRMap.erase(reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600746 } else {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700747 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, (uint64_t) object, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barboura05dbaa2015-07-09 17:31:46 -0600748 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
Michael Lentine13803dc2015-11-04 14:35:12 -0800749 reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600750 }
751}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600752//
753// Non-auto-generated API functions called by generated code
754//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600755VkResult
756explicit_CreateInstance(
757 const VkInstanceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800758 const VkAllocationCallbacks * pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600759 VkInstance * pInstance)
760{
David Pinedoc0fa1ab2015-07-31 10:46:25 -0600761
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600762 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, *pInstance);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800763 VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600764
765 if (result == VK_SUCCESS) {
766 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
767 my_data->report_data = debug_report_create_instance(
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600768 pInstanceTable,
769 *pInstance,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800770 pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600771 pCreateInfo->ppEnabledExtensionNames);
Jon Ashburn3dc39382015-09-17 10:00:32 -0600772 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600773
774 initObjectTracker(my_data);
Michael Lentine13803dc2015-11-04 14:35:12 -0800775 create_instance(*pInstance, *pInstance, VK_OBJECT_TYPE_INSTANCE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600776 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600777 return result;
778}
779
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600780void
Cody Northropd0802882015-08-03 17:04:53 -0600781explicit_GetPhysicalDeviceQueueFamilyProperties(
Tony Barbour59a47322015-06-24 16:06:58 -0600782 VkPhysicalDevice gpu,
Cody Northropd0802882015-08-03 17:04:53 -0600783 uint32_t* pCount,
784 VkQueueFamilyProperties* pProperties)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600785{
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600786 get_dispatch_table(ObjectTracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600787
788 loader_platform_thread_lock_mutex(&objLock);
Cody Northropd0802882015-08-03 17:04:53 -0600789 if (pProperties != NULL)
790 setGpuQueueInfoState(*pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600791 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600792}
793
794VkResult
795explicit_CreateDevice(
796 VkPhysicalDevice gpu,
797 const VkDeviceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800798 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600799 VkDevice *pDevice)
800{
801 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600802// VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, gpu);
803 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800804 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600805 if (result == VK_SUCCESS) {
806 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
807 //// VkLayerDispatchTable *pTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
808 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
809 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Michael Lentine13803dc2015-11-04 14:35:12 -0800810 create_device(*pDevice, *pDevice, VK_OBJECT_TYPE_DEVICE);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600811 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600812 }
813
814 loader_platform_thread_unlock_mutex(&objLock);
815 return result;
816}
817
Tobin Ehlisec598302015-09-15 15:02:17 -0600818VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
819{
820 VkBool32 skipCall = VK_FALSE;
821 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800822 skipCall |= validate_instance(instance, instance);
Tobin Ehlisec598302015-09-15 15:02:17 -0600823 loader_platform_thread_unlock_mutex(&objLock);
824 if (skipCall)
825 return VK_ERROR_VALIDATION_FAILED;
826 VkResult result = get_dispatch_table(ObjectTracker_instance_table_map, instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
827 loader_platform_thread_lock_mutex(&objLock);
828 if (result == VK_SUCCESS) {
829 if (pPhysicalDevices) {
830 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800831 create_physical_device(instance, pPhysicalDevices[i], VK_OBJECT_TYPE_PHYSICAL_DEVICE);
Tobin Ehlisec598302015-09-15 15:02:17 -0600832 }
833 }
834 }
835 loader_platform_thread_unlock_mutex(&objLock);
836 return result;
837}
838
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600839void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600840explicit_GetDeviceQueue(
841 VkDevice device,
842 uint32_t queueNodeIndex,
843 uint32_t queueIndex,
844 VkQueue *pQueue)
845{
846 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800847 validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600848 loader_platform_thread_unlock_mutex(&objLock);
849
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600850 get_dispatch_table(ObjectTracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600851
852 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600853 addQueueInfo(queueNodeIndex, *pQueue);
Michael Lentine13803dc2015-11-04 14:35:12 -0800854 create_queue(device, *pQueue, VK_OBJECT_TYPE_QUEUE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600855 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600856}
857
858VkResult
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600859explicit_MapMemory(
860 VkDevice device,
861 VkDeviceMemory mem,
862 VkDeviceSize offset,
863 VkDeviceSize size,
864 VkFlags flags,
865 void **ppData)
866{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600867 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600868 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800869 skipCall |= set_device_memory_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
870 skipCall |= validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600871 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600872 if (skipCall == VK_TRUE)
873 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600874
875 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
876
877 return result;
878}
879
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600880void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600881explicit_UnmapMemory(
882 VkDevice device,
883 VkDeviceMemory mem)
884{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600885 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600886 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800887 skipCall |= reset_device_memory_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
888 skipCall |= validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600889 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600890 if (skipCall == VK_TRUE)
891 return;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600892
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600893 get_dispatch_table(ObjectTracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600894}
895
896VkResult
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800897explicit_QueueBindSparse(
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600898 VkQueue queue,
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800899 uint32_t bindInfoCount,
900 const VkBindSparseInfo* pBindInfo,
901 VkFence fence)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600902{
903 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800904 validateQueueFlags(queue, "QueueBindSparse");
905
906 for (uint32_t i = 0; i < bindInfoCount; i++) {
907 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800908 validate_buffer(queue, pBindInfo[i].pBufferBinds[j].buffer);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800909 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800910 validate_image(queue, pBindInfo[i].pImageOpaqueBinds[j].image);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800911 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800912 validate_image(queue, pBindInfo[i].pImageBinds[j].image);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800913 }
914
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600915 loader_platform_thread_unlock_mutex(&objLock);
916
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800917 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600918 return result;
919}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600920
921VkResult
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700922explicit_AllocateCommandBuffers(
923 VkDevice device,
924 const VkCommandBufferAllocateInfo *pAllocateInfo,
925 VkCommandBuffer* pCommandBuffers)
926{
927 VkBool32 skipCall = VK_FALSE;
928 loader_platform_thread_lock_mutex(&objLock);
929 skipCall |= validate_device(device, device);
930 skipCall |= validate_command_pool(device, pAllocateInfo->commandPool);
931 loader_platform_thread_unlock_mutex(&objLock);
932
933 if (skipCall) {
934 return VK_ERROR_VALIDATION_FAILED;
935 }
936
937 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateCommandBuffers(
938 device, pAllocateInfo, pCommandBuffers);
939
940 loader_platform_thread_lock_mutex(&objLock);
941 for (uint32_t i = 0; i < pAllocateInfo->bufferCount; i++) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800942 alloc_command_buffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], VK_OBJECT_TYPE_COMMAND_BUFFER);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700943 }
944 loader_platform_thread_unlock_mutex(&objLock);
945
946 return result;
947}
948
949VkResult
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800950explicit_AllocateDescriptorSets(
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700951 VkDevice device,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800952 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700953 VkDescriptorSet *pDescriptorSets)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600954{
Tobin Ehlisec598302015-09-15 15:02:17 -0600955 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600956 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800957 skipCall |= validate_device(device, device);
958 skipCall |= validate_descriptor_pool(device, pAllocateInfo->descriptorPool);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800959 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800960 skipCall |= validate_descriptor_set_layout(device, pAllocateInfo->pSetLayouts[i]);
Tobin Ehlisec598302015-09-15 15:02:17 -0600961 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600962 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600963 if (skipCall)
964 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600965
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800966 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateDescriptorSets(
967 device, pAllocateInfo, pDescriptorSets);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600968
969 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800970 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800971 alloc_descriptor_set(device, pAllocateInfo->descriptorPool, pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600972 }
973 loader_platform_thread_unlock_mutex(&objLock);
974
975 return result;
976}
977
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700978void
979explicit_FreeCommandBuffers(
980 VkDevice device,
981 VkCommandPool commandPool,
982 uint32_t commandBufferCount,
983 const VkCommandBuffer *pCommandBuffers)
984{
985 loader_platform_thread_lock_mutex(&objLock);
986 validate_command_pool(device, commandPool);
987 validate_device(device, device);
988 loader_platform_thread_unlock_mutex(&objLock);
989
990 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeCommandBuffers(device,
991 commandPool, commandBufferCount, pCommandBuffers);
992
993 loader_platform_thread_lock_mutex(&objLock);
994 for (uint32_t i = 0; i < commandBufferCount; i++)
995 {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800996 free_command_buffer(device, commandPool, *pCommandBuffers);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700997 pCommandBuffers++;
998 }
999 loader_platform_thread_unlock_mutex(&objLock);
1000}
1001
Ian Elliott05846062015-11-20 14:13:17 -07001002void
Ian Elliott7e40db92015-08-21 15:09:33 -06001003explicit_DestroySwapchainKHR(
Ian Elliott05846062015-11-20 14:13:17 -07001004 VkDevice device,
1005 VkSwapchainKHR swapchain,
1006 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001007{
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001008 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001009 // A swapchain's images are implicitly deleted when the swapchain is deleted.
1010 // Remove this swapchain's images from our map of such images.
Michael Lentine13803dc2015-11-04 14:35:12 -08001011 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = swapchainImageMap.begin();
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001012 while (itr != swapchainImageMap.end()) {
1013 OBJTRACK_NODE* pNode = (*itr).second;
Michael Lentine13803dc2015-11-04 14:35:12 -08001014 if (pNode->parentObj == reinterpret_cast<uint64_t>(swapchain)) {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001015 swapchainImageMap.erase(itr++);
1016 } else {
1017 ++itr;
1018 }
1019 }
Michael Lentine13803dc2015-11-04 14:35:12 -08001020 destroy_swapchain(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001021 loader_platform_thread_unlock_mutex(&objLock);
1022
Ian Elliott05846062015-11-20 14:13:17 -07001023 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001024}
1025
Mark Lobodzinski2141f652015-09-07 13:59:43 -06001026void
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001027explicit_FreeMemory(
1028 VkDevice device,
Chia-I Wuf7458c52015-10-26 21:10:41 +08001029 VkDeviceMemory mem,
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001030 const VkAllocationCallbacks* pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001031{
1032 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001033 validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001034 loader_platform_thread_unlock_mutex(&objLock);
1035
Chia-I Wuf7458c52015-10-26 21:10:41 +08001036 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001037
1038 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001039 destroy_device_memory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001040 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001041}
Tony Barboura05dbaa2015-07-09 17:31:46 -06001042
Tony Barbour770f80d2015-07-20 10:52:13 -06001043VkResult
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001044explicit_FreeDescriptorSets(
1045 VkDevice device,
1046 VkDescriptorPool descriptorPool,
1047 uint32_t count,
1048 const VkDescriptorSet *pDescriptorSets)
Tony Barbour770f80d2015-07-20 10:52:13 -06001049{
1050 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001051 validate_descriptor_pool(device, descriptorPool);
1052 validate_device(device, device);
Tony Barbour770f80d2015-07-20 10:52:13 -06001053 loader_platform_thread_unlock_mutex(&objLock);
1054 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
1055
1056 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter7ebf1212015-07-23 11:25:17 -06001057 for (uint32_t i=0; i<count; i++)
Tony Barbour770f80d2015-07-20 10:52:13 -06001058 {
Michael Lentinefc6aa762015-11-20 12:11:42 -08001059 free_descriptor_set(device, descriptorPool, *pDescriptorSets++);
Tony Barbour770f80d2015-07-20 10:52:13 -06001060 }
1061 loader_platform_thread_unlock_mutex(&objLock);
1062 return result;
1063}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001064
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001065void
1066explicit_DestroyDescriptorPool(
1067 VkDevice device,
1068 VkDescriptorPool descriptorPool,
1069 const VkAllocationCallbacks *pAllocator)
1070{
1071 VkBool32 skipCall = VK_FALSE;
1072 loader_platform_thread_lock_mutex(&objLock);
1073 skipCall |= validate_device(device, device);
1074 skipCall |= validate_descriptor_pool(device, descriptorPool);
1075 loader_platform_thread_unlock_mutex(&objLock);
1076 if (skipCall) {
1077 return;
1078 }
1079 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
1080 // Remove this pool's descriptor sets from our descriptorSet map.
1081 loader_platform_thread_lock_mutex(&objLock);
1082 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkDescriptorSetMap.begin();
1083 while (itr != VkDescriptorSetMap.end()) {
1084 OBJTRACK_NODE* pNode = (*itr).second;
Mark Lobodzinskib29731a2015-11-18 11:01:02 -07001085 auto del_itr = itr++;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001086 if (pNode->parentObj == reinterpret_cast<uint64_t>(descriptorPool)) {
Mark Lobodzinskib29731a2015-11-18 11:01:02 -07001087 destroy_descriptor_set(device, reinterpret_cast<VkDescriptorSet>((*del_itr).first));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001088 }
1089 }
1090 destroy_descriptor_pool(device, descriptorPool);
1091 loader_platform_thread_unlock_mutex(&objLock);
1092 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
1093}
1094
1095void
1096explicit_DestroyCommandPool(
1097 VkDevice device,
1098 VkCommandPool commandPool,
1099 const VkAllocationCallbacks *pAllocator)
1100{
1101 VkBool32 skipCall = VK_FALSE;
1102 loader_platform_thread_lock_mutex(&objLock);
1103 skipCall |= validate_device(device, device);
1104 skipCall |= validate_command_pool(device, commandPool);
1105 loader_platform_thread_unlock_mutex(&objLock);
1106 if (skipCall) {
1107 return;
1108 }
1109 loader_platform_thread_lock_mutex(&objLock);
1110 // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
1111 // Remove this pool's cmdBuffers from our cmd buffer map.
1112 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkCommandBufferMap.begin();
1113 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator del_itr;
1114 while (itr != VkCommandBufferMap.end()) {
1115 OBJTRACK_NODE* pNode = (*itr).second;
1116 del_itr = itr++;
1117 if (pNode->parentObj == reinterpret_cast<uint64_t>(commandPool)) {
1118 destroy_command_buffer(reinterpret_cast<VkCommandBuffer>((*del_itr).first),
1119 reinterpret_cast<VkCommandBuffer>((*del_itr).first));
1120 }
1121 }
1122 destroy_command_pool(device, commandPool);
1123 loader_platform_thread_unlock_mutex(&objLock);
1124 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
1125}
1126
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001127VkResult
1128explicit_GetSwapchainImagesKHR(
1129 VkDevice device,
1130 VkSwapchainKHR swapchain,
1131 uint32_t *pCount,
1132 VkImage *pSwapchainImages)
1133{
1134 VkBool32 skipCall = VK_FALSE;
1135 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001136 skipCall |= validate_device(device, device);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001137 loader_platform_thread_unlock_mutex(&objLock);
1138 if (skipCall)
1139 return VK_ERROR_VALIDATION_FAILED;
1140
1141 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
1142
1143 if (pSwapchainImages != NULL) {
1144 loader_platform_thread_lock_mutex(&objLock);
1145 for (uint32_t i = 0; i < *pCount; i++) {
1146 create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
1147 }
1148 loader_platform_thread_unlock_mutex(&objLock);
1149 }
1150 return result;
1151}
1152