blob: 08f36c7a691082f7f80dae0d71a9457e398e04b7 [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
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -070078 VkDebugReportCallbackLUNARG 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(
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700413 layer_data *my_data,
414 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600415{
416 uint32_t report_flags = 0;
417 uint32_t debug_action = 0;
418 FILE *log_output = NULL;
419 const char *option_str;
420 // initialize ObjectTracker options
421 report_flags = getLayerOptionFlags("ObjectTrackerReportFlags", 0);
422 getLayerOptionEnum("ObjectTrackerDebugAction", (uint32_t *) &debug_action);
423
424 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
425 {
426 option_str = getLayerOption("ObjectTrackerLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600427 log_output = getLayerLogOutput(option_str, "ObjectTracker");
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700428 VkDebugReportCallbackCreateInfoLUNARG dbgInfo;
429 memset(&dbgInfo, 0, sizeof(dbgInfo));
430 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_LUNARG;
431 dbgInfo.pfnCallback = log_callback;
432 dbgInfo.pUserData = log_output;
433 dbgInfo.flags = report_flags;
434 layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &my_data->logging_callback);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600435 }
436
437 if (!objLockInitialized)
438 {
439 // TODO/TBD: Need to delete this mutex sometime. How??? One
440 // suggestion is to call this during vkCreateInstance(), and then we
441 // can clean it up during vkDestroyInstance(). However, that requires
442 // that the layer have per-instance locks. We need to come back and
443 // address this soon.
444 loader_platform_thread_create_mutex(&objLock);
445 objLockInitialized = 1;
446 }
447}
448
Tony Barboura05dbaa2015-07-09 17:31:46 -0600449//
450// Forward declares of generated routines
451//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600452
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700453static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeLUNARG objType);
454static void create_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeLUNARG objType);
455static void create_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeLUNARG objType);
456static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeLUNARG objType);
Michael Lentine13803dc2015-11-04 14:35:12 -0800457static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object);
458static VkBool32 validate_image(VkCommandBuffer dispatchable_object, VkImage object);
459static VkBool32 validate_command_buffer(VkQueue dispatchable_object, VkCommandBuffer object);
460static VkBool32 validate_descriptor_set(VkCommandBuffer dispatchable_object, VkDescriptorSet object);
461static VkBool32 validate_instance(VkInstance dispatchable_object, VkInstance object);
462static VkBool32 validate_device(VkDevice dispatchable_object, VkDevice object);
463static VkBool32 validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
464static VkBool32 validate_descriptor_set_layout(VkDevice dispatchable_object, VkDescriptorSetLayout object);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700465static VkBool32 validate_command_pool(VkDevice dispatchable_object, VkCommandPool object);
466static void destroy_command_pool(VkDevice dispatchable_object, VkCommandPool object);
467static void destroy_command_buffer(VkCommandBuffer dispatchable_object, VkCommandBuffer object);
468static void destroy_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
469static void destroy_descriptor_set(VkDevice dispatchable_object, VkDescriptorSet object);
Michael Lentine13803dc2015-11-04 14:35:12 -0800470static void destroy_instance(VkInstance dispatchable_object, VkInstance object);
471static void destroy_device_memory(VkDevice dispatchable_object, VkDeviceMemory object);
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700472static VkBool32 set_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeLUNARG objType, ObjectStatusFlags status_flag);
473static VkBool32 reset_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeLUNARG objType, ObjectStatusFlags status_flag);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600474#if 0
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700475static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDebugReportObjectTypeLUNARG objType,
Tony Barboura05dbaa2015-07-09 17:31:46 -0600476 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
477 const char *fail_msg);
478#endif
Michael Lentine13803dc2015-11-04 14:35:12 -0800479extern unordered_map<uint64_t, OBJTRACK_NODE*> VkPhysicalDeviceMap;
480extern unordered_map<uint64_t, OBJTRACK_NODE*> VkImageMap;
481extern unordered_map<uint64_t, OBJTRACK_NODE*> VkQueueMap;
482extern unordered_map<uint64_t, OBJTRACK_NODE*> VkDescriptorSetMap;
483extern unordered_map<uint64_t, OBJTRACK_NODE*> VkBufferMap;
484extern unordered_map<uint64_t, OBJTRACK_NODE*> VkFenceMap;
485extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSemaphoreMap;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700486extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandPoolMap;
Michael Lentine13803dc2015-11-04 14:35:12 -0800487extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandBufferMap;
488extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSwapchainKHRMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600489
Michael Lentine13803dc2015-11-04 14:35:12 -0800490static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600491{
Michael Lentine13803dc2015-11-04 14:35:12 -0800492 if ((VkImageMap.find(reinterpret_cast<uint64_t>(object)) == VkImageMap.end()) &&
493 (swapchainImageMap.find(reinterpret_cast<uint64_t>(object)) == swapchainImageMap.end())) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700494 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 -0800495 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600496 }
497 return VK_FALSE;
498}
499
Michael Lentine13803dc2015-11-04 14:35:12 -0800500static VkBool32 validate_image(VkCommandBuffer dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600501{
Michael Lentine13803dc2015-11-04 14:35:12 -0800502 if ((VkImageMap.find(reinterpret_cast<uint64_t>(object)) == VkImageMap.end()) &&
503 (swapchainImageMap.find(reinterpret_cast<uint64_t>(object)) == swapchainImageMap.end())) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700504 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 -0800505 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600506 }
507 return VK_FALSE;
508}
509
Michael Lentine13803dc2015-11-04 14:35:12 -0800510static VkBool32 validate_command_buffer(VkQueue dispatchable_object, VkCommandBuffer object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600511{
Michael Lentine13803dc2015-11-04 14:35:12 -0800512 if (VkCommandBufferMap.find(reinterpret_cast<uint64_t>(object)) == VkCommandBufferMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700513 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 -0800514 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600515 }
516 return VK_FALSE;
517}
518
Michael Lentine13803dc2015-11-04 14:35:12 -0800519static VkBool32 validate_descriptor_set(VkCommandBuffer dispatchable_object, VkDescriptorSet object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600520{
Michael Lentine13803dc2015-11-04 14:35:12 -0800521 if (VkDescriptorSetMap.find(reinterpret_cast<uint64_t>(object)) == VkDescriptorSetMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700522 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 -0800523 "Invalid VkDescriptorSet Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600524 }
525 return VK_FALSE;
526}
527
Michael Lentine13803dc2015-11-04 14:35:12 -0800528static VkBool32 validate_buffer(VkQueue dispatchable_object, VkBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600529{
Michael Lentine13803dc2015-11-04 14:35:12 -0800530 if (VkBufferMap.find(reinterpret_cast<uint64_t>(object)) != VkBufferMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700531 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 -0800532 "Invalid VkBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600533 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600534 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600535}
536
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700537static VkBool32 set_status(VkQueue dispatchable_object, VkFence object, VkDebugReportObjectTypeLUNARG objType, ObjectStatusFlags status_flag)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600538{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600539 VkBool32 skipCall = VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600540 if (object != VK_NULL_HANDLE) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800541 if (VkFenceMap.find(reinterpret_cast<uint64_t>(object)) != VkFenceMap.end()) {
542 OBJTRACK_NODE* pNode = VkFenceMap[reinterpret_cast<uint64_t>(object)];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600543 pNode->status |= status_flag;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600544 }
545 else {
546 // If we do not find it print an error
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700547 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 -0600548 "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700549 reinterpret_cast<uint64_t>(object), string_VkDebugReportObjectTypeLUNARG(objType));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600550 }
551 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600552 return skipCall;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600553}
554
Michael Lentine13803dc2015-11-04 14:35:12 -0800555static VkBool32 validate_semaphore(VkQueue dispatchable_object, VkSemaphore object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600556{
Michael Lentine13803dc2015-11-04 14:35:12 -0800557 if (VkSemaphoreMap.find(reinterpret_cast<uint64_t>(object)) == VkSemaphoreMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700558 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 -0800559 "Invalid VkSemaphore Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600560 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600561 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600562}
563
Michael Lentine13803dc2015-11-04 14:35:12 -0800564static VkBool32 validate_command_buffer(VkDevice dispatchable_object, VkCommandBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600565{
Michael Lentine13803dc2015-11-04 14:35:12 -0800566 if (VkCommandBufferMap.find(reinterpret_cast<uint64_t>(object)) == VkCommandBufferMap.end()) {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700567 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 -0800568 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600569 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600570 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600571}
572
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700573static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeLUNARG objType)
Tobin Ehlisec598302015-09-15 15:02:17 -0600574{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700575 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 -0700576 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Tobin Ehlisec598302015-09-15 15:02:17 -0600577 reinterpret_cast<uint64_t>(vkObj));
578
579 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
580 pNewObjNode->objType = objType;
581 pNewObjNode->status = OBJSTATUS_NONE;
582 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800583 VkPhysicalDeviceMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600584 uint32_t objIndex = objTypeToIndex(objType);
585 numObjs[objIndex]++;
586 numTotalObjs++;
587}
588
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700589static void create_surface_khr(VkInstance instance, VkSurfaceKHR surface, VkDebugReportObjectTypeLUNARG objType)
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700590{
591 // TODO: Add tracking of surface objects
592}
593
594static void destroy_surface_khr(VkInstance instance, VkSurfaceKHR surface)
595{
596 // TODO: Add tracking of surface objects
597}
598
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700599static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer vkObj, VkDebugReportObjectTypeLUNARG objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600600{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700601 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 -0700602 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600603 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600604
605 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700606 pNewObjNode->objType = objType;
607 pNewObjNode->status = OBJSTATUS_NONE;
608 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
609 pNewObjNode->parentObj = (uint64_t) commandPool;
Michael Lentine13803dc2015-11-04 14:35:12 -0800610 VkCommandBufferMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600611 uint32_t objIndex = objTypeToIndex(objType);
612 numObjs[objIndex]++;
613 numTotalObjs++;
614}
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700615
Michael Lentinefc6aa762015-11-20 12:11:42 -0800616static void free_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700617{
618 uint64_t object_handle = reinterpret_cast<uint64_t>(commandBuffer);
619 if (VkCommandBufferMap.find(object_handle) != VkCommandBufferMap.end()) {
620 OBJTRACK_NODE* pNode = VkCommandBufferMap[(uint64_t)commandBuffer];
621
622 if (pNode->parentObj != reinterpret_cast<uint64_t>(commandPool)) {
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700623 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 -0700624 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
625 reinterpret_cast<uint64_t>(commandBuffer), pNode->parentObj, reinterpret_cast<uint64_t>(commandPool));
626 } else {
627
628 uint32_t objIndex = objTypeToIndex(pNode->objType);
629 assert(numTotalObjs > 0);
630 numTotalObjs--;
631 assert(numObjs[objIndex] > 0);
632 numObjs[objIndex]--;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700633 log_msg(mdd(device), VK_DEBUG_REPORT_INFO_BIT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700634 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700635 string_VkDebugReportObjectTypeLUNARG(pNode->objType), reinterpret_cast<uint64_t>(commandBuffer), numTotalObjs, numObjs[objIndex],
636 string_VkDebugReportObjectTypeLUNARG(pNode->objType));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700637 delete pNode;
638 VkCommandBufferMap.erase(object_handle);
639 }
640 } else {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700641 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700642 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
643 object_handle);
644 }
645}
646
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700647static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet vkObj, VkDebugReportObjectTypeLUNARG objType)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700648{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700649 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 -0700650 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700651 reinterpret_cast<uint64_t>(vkObj));
652
653 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
654 pNewObjNode->objType = objType;
655 pNewObjNode->status = OBJSTATUS_NONE;
656 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
657 pNewObjNode->parentObj = (uint64_t) descriptorPool;
658 VkDescriptorSetMap[(uint64_t)vkObj] = pNewObjNode;
659 uint32_t objIndex = objTypeToIndex(objType);
660 numObjs[objIndex]++;
661 numTotalObjs++;
662}
663
Michael Lentinefc6aa762015-11-20 12:11:42 -0800664static void free_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet descriptorSet)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700665{
666 uint64_t object_handle = reinterpret_cast<uint64_t>(descriptorSet);
667 if (VkDescriptorSetMap.find(object_handle) != VkDescriptorSetMap.end()) {
668 OBJTRACK_NODE* pNode = VkDescriptorSetMap[(uint64_t)descriptorSet];
669
670 if (pNode->parentObj != reinterpret_cast<uint64_t>(descriptorPool)) {
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700671 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 -0700672 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
673 reinterpret_cast<uint64_t>(descriptorSet), pNode->parentObj, reinterpret_cast<uint64_t>(descriptorPool));
674 } else {
675 uint32_t objIndex = objTypeToIndex(pNode->objType);
676 assert(numTotalObjs > 0);
677 numTotalObjs--;
678 assert(numObjs[objIndex] > 0);
679 numObjs[objIndex]--;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700680 log_msg(mdd(device), VK_DEBUG_REPORT_INFO_BIT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700681 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700682 string_VkDebugReportObjectTypeLUNARG(pNode->objType), reinterpret_cast<uint64_t>(descriptorSet), numTotalObjs, numObjs[objIndex],
683 string_VkDebugReportObjectTypeLUNARG(pNode->objType));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700684 delete pNode;
685 VkDescriptorSetMap.erase(object_handle);
686 }
687 } else {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700688 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT, (VkDebugReportObjectTypeLUNARG) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700689 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
690 object_handle);
691 }
692}
693
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700694static void create_swapchain_khr(VkDevice dispatchable_object, VkSwapchainKHR vkObj, VkDebugReportObjectTypeLUNARG objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600695{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700696 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 -0700697 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Michael Lentine13803dc2015-11-04 14:35:12 -0800698 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600699
700 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
701 pNewObjNode->objType = objType;
702 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800703 pNewObjNode->vkObj = (uint64_t) vkObj;
Michael Lentine13803dc2015-11-04 14:35:12 -0800704 VkSwapchainKHRMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600705 uint32_t objIndex = objTypeToIndex(objType);
706 numObjs[objIndex]++;
707 numTotalObjs++;
708}
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700709static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeLUNARG objType)
Tobin Ehlisec598302015-09-15 15:02:17 -0600710{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700711 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 -0700712 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeLUNARG(objType),
Tobin Ehlisec598302015-09-15 15:02:17 -0600713 reinterpret_cast<uint64_t>(vkObj));
714
715 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
716 pNewObjNode->objType = objType;
717 pNewObjNode->status = OBJSTATUS_NONE;
718 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800719 VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600720 uint32_t objIndex = objTypeToIndex(objType);
721 numObjs[objIndex]++;
722 numTotalObjs++;
723}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600724static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain)
725{
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700726 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 -0600727 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, "SwapchainImage",
Michael Lentine13803dc2015-11-04 14:35:12 -0800728 reinterpret_cast<uint64_t>(vkObj));
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600729
730 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
731 pNewObjNode->objType = VK_OBJECT_TYPE_IMAGE;
732 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800733 pNewObjNode->vkObj = (uint64_t) vkObj;
734 pNewObjNode->parentObj = (uint64_t) swapchain;
Michael Lentine13803dc2015-11-04 14:35:12 -0800735 swapchainImageMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600736}
737
Michael Lentine13803dc2015-11-04 14:35:12 -0800738static void destroy_swapchain(VkDevice dispatchable_object, VkSwapchainKHR object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600739{
Michael Lentine13803dc2015-11-04 14:35:12 -0800740 if (VkSwapchainKHRMap.find(reinterpret_cast<uint64_t>(object)) != VkSwapchainKHRMap.end()) {
741 OBJTRACK_NODE* pNode = VkSwapchainKHRMap[reinterpret_cast<uint64_t>(object)];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600742 uint32_t objIndex = objTypeToIndex(pNode->objType);
743 assert(numTotalObjs > 0);
744 numTotalObjs--;
745 assert(numObjs[objIndex] > 0);
746 numObjs[objIndex]--;
Courtney Goeltzenleuchterfd4830c2015-11-25 10:30:56 -0700747 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 -0800748 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700749 string_VkDebugReportObjectTypeLUNARG(pNode->objType), (uint64_t) object, numTotalObjs, numObjs[objIndex],
750 string_VkDebugReportObjectTypeLUNARG(pNode->objType));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600751 delete pNode;
Michael Lentine13803dc2015-11-04 14:35:12 -0800752 VkSwapchainKHRMap.erase(reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600753 } else {
Courtney Goeltzenleuchterb19042e2015-11-25 11:38:54 -0700754 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 -0600755 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
Michael Lentine13803dc2015-11-04 14:35:12 -0800756 reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600757 }
758}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600759//
760// Non-auto-generated API functions called by generated code
761//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600762VkResult
763explicit_CreateInstance(
764 const VkInstanceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800765 const VkAllocationCallbacks * pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600766 VkInstance * pInstance)
767{
David Pinedoc0fa1ab2015-07-31 10:46:25 -0600768
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600769 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, *pInstance);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800770 VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600771
772 if (result == VK_SUCCESS) {
773 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
774 my_data->report_data = debug_report_create_instance(
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600775 pInstanceTable,
776 *pInstance,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800777 pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600778 pCreateInfo->ppEnabledExtensionNames);
Jon Ashburn3dc39382015-09-17 10:00:32 -0600779 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600780
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700781 initObjectTracker(my_data, pAllocator);
Michael Lentine13803dc2015-11-04 14:35:12 -0800782 create_instance(*pInstance, *pInstance, VK_OBJECT_TYPE_INSTANCE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600783 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600784 return result;
785}
786
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600787void
Cody Northropd0802882015-08-03 17:04:53 -0600788explicit_GetPhysicalDeviceQueueFamilyProperties(
Tony Barbour59a47322015-06-24 16:06:58 -0600789 VkPhysicalDevice gpu,
Cody Northropd0802882015-08-03 17:04:53 -0600790 uint32_t* pCount,
791 VkQueueFamilyProperties* pProperties)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600792{
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600793 get_dispatch_table(ObjectTracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600794
795 loader_platform_thread_lock_mutex(&objLock);
Cody Northropd0802882015-08-03 17:04:53 -0600796 if (pProperties != NULL)
797 setGpuQueueInfoState(*pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600798 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600799}
800
801VkResult
802explicit_CreateDevice(
803 VkPhysicalDevice gpu,
804 const VkDeviceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800805 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600806 VkDevice *pDevice)
807{
808 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600809// VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, gpu);
810 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800811 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600812 if (result == VK_SUCCESS) {
813 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
814 //// VkLayerDispatchTable *pTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
815 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
816 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Michael Lentine13803dc2015-11-04 14:35:12 -0800817 create_device(*pDevice, *pDevice, VK_OBJECT_TYPE_DEVICE);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600818 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600819 }
820
821 loader_platform_thread_unlock_mutex(&objLock);
822 return result;
823}
824
Tobin Ehlisec598302015-09-15 15:02:17 -0600825VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
826{
827 VkBool32 skipCall = VK_FALSE;
828 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800829 skipCall |= validate_instance(instance, instance);
Tobin Ehlisec598302015-09-15 15:02:17 -0600830 loader_platform_thread_unlock_mutex(&objLock);
831 if (skipCall)
832 return VK_ERROR_VALIDATION_FAILED;
833 VkResult result = get_dispatch_table(ObjectTracker_instance_table_map, instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
834 loader_platform_thread_lock_mutex(&objLock);
835 if (result == VK_SUCCESS) {
836 if (pPhysicalDevices) {
837 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800838 create_physical_device(instance, pPhysicalDevices[i], VK_OBJECT_TYPE_PHYSICAL_DEVICE);
Tobin Ehlisec598302015-09-15 15:02:17 -0600839 }
840 }
841 }
842 loader_platform_thread_unlock_mutex(&objLock);
843 return result;
844}
845
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600846void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600847explicit_GetDeviceQueue(
848 VkDevice device,
849 uint32_t queueNodeIndex,
850 uint32_t queueIndex,
851 VkQueue *pQueue)
852{
853 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800854 validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600855 loader_platform_thread_unlock_mutex(&objLock);
856
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600857 get_dispatch_table(ObjectTracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600858
859 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600860 addQueueInfo(queueNodeIndex, *pQueue);
Michael Lentine13803dc2015-11-04 14:35:12 -0800861 create_queue(device, *pQueue, VK_OBJECT_TYPE_QUEUE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600862 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600863}
864
865VkResult
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600866explicit_MapMemory(
867 VkDevice device,
868 VkDeviceMemory mem,
869 VkDeviceSize offset,
870 VkDeviceSize size,
871 VkFlags flags,
872 void **ppData)
873{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600874 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600875 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800876 skipCall |= set_device_memory_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
877 skipCall |= validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600878 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600879 if (skipCall == VK_TRUE)
880 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600881
882 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
883
884 return result;
885}
886
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600887void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600888explicit_UnmapMemory(
889 VkDevice device,
890 VkDeviceMemory mem)
891{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600892 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600893 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800894 skipCall |= reset_device_memory_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
895 skipCall |= validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600896 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600897 if (skipCall == VK_TRUE)
898 return;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600899
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600900 get_dispatch_table(ObjectTracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600901}
902
903VkResult
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800904explicit_QueueBindSparse(
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600905 VkQueue queue,
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800906 uint32_t bindInfoCount,
907 const VkBindSparseInfo* pBindInfo,
908 VkFence fence)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600909{
910 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800911 validateQueueFlags(queue, "QueueBindSparse");
912
913 for (uint32_t i = 0; i < bindInfoCount; i++) {
914 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800915 validate_buffer(queue, pBindInfo[i].pBufferBinds[j].buffer);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800916 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800917 validate_image(queue, pBindInfo[i].pImageOpaqueBinds[j].image);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800918 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800919 validate_image(queue, pBindInfo[i].pImageBinds[j].image);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800920 }
921
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600922 loader_platform_thread_unlock_mutex(&objLock);
923
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800924 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600925 return result;
926}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600927
928VkResult
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700929explicit_AllocateCommandBuffers(
930 VkDevice device,
931 const VkCommandBufferAllocateInfo *pAllocateInfo,
932 VkCommandBuffer* pCommandBuffers)
933{
934 VkBool32 skipCall = VK_FALSE;
935 loader_platform_thread_lock_mutex(&objLock);
936 skipCall |= validate_device(device, device);
937 skipCall |= validate_command_pool(device, pAllocateInfo->commandPool);
938 loader_platform_thread_unlock_mutex(&objLock);
939
940 if (skipCall) {
941 return VK_ERROR_VALIDATION_FAILED;
942 }
943
944 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateCommandBuffers(
945 device, pAllocateInfo, pCommandBuffers);
946
947 loader_platform_thread_lock_mutex(&objLock);
948 for (uint32_t i = 0; i < pAllocateInfo->bufferCount; i++) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800949 alloc_command_buffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], VK_OBJECT_TYPE_COMMAND_BUFFER);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700950 }
951 loader_platform_thread_unlock_mutex(&objLock);
952
953 return result;
954}
955
956VkResult
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800957explicit_AllocateDescriptorSets(
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700958 VkDevice device,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800959 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700960 VkDescriptorSet *pDescriptorSets)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600961{
Tobin Ehlisec598302015-09-15 15:02:17 -0600962 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600963 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800964 skipCall |= validate_device(device, device);
965 skipCall |= validate_descriptor_pool(device, pAllocateInfo->descriptorPool);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800966 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800967 skipCall |= validate_descriptor_set_layout(device, pAllocateInfo->pSetLayouts[i]);
Tobin Ehlisec598302015-09-15 15:02:17 -0600968 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600969 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600970 if (skipCall)
971 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600972
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800973 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateDescriptorSets(
974 device, pAllocateInfo, pDescriptorSets);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600975
976 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800977 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800978 alloc_descriptor_set(device, pAllocateInfo->descriptorPool, pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600979 }
980 loader_platform_thread_unlock_mutex(&objLock);
981
982 return result;
983}
984
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700985void
986explicit_FreeCommandBuffers(
987 VkDevice device,
988 VkCommandPool commandPool,
989 uint32_t commandBufferCount,
990 const VkCommandBuffer *pCommandBuffers)
991{
992 loader_platform_thread_lock_mutex(&objLock);
993 validate_command_pool(device, commandPool);
994 validate_device(device, device);
995 loader_platform_thread_unlock_mutex(&objLock);
996
997 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeCommandBuffers(device,
998 commandPool, commandBufferCount, pCommandBuffers);
999
1000 loader_platform_thread_lock_mutex(&objLock);
1001 for (uint32_t i = 0; i < commandBufferCount; i++)
1002 {
Michael Lentinefc6aa762015-11-20 12:11:42 -08001003 free_command_buffer(device, commandPool, *pCommandBuffers);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001004 pCommandBuffers++;
1005 }
1006 loader_platform_thread_unlock_mutex(&objLock);
1007}
1008
Ian Elliott05846062015-11-20 14:13:17 -07001009void
Ian Elliott7e40db92015-08-21 15:09:33 -06001010explicit_DestroySwapchainKHR(
Ian Elliott05846062015-11-20 14:13:17 -07001011 VkDevice device,
1012 VkSwapchainKHR swapchain,
1013 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001014{
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001015 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001016 // A swapchain's images are implicitly deleted when the swapchain is deleted.
1017 // Remove this swapchain's images from our map of such images.
Michael Lentine13803dc2015-11-04 14:35:12 -08001018 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = swapchainImageMap.begin();
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001019 while (itr != swapchainImageMap.end()) {
1020 OBJTRACK_NODE* pNode = (*itr).second;
Michael Lentine13803dc2015-11-04 14:35:12 -08001021 if (pNode->parentObj == reinterpret_cast<uint64_t>(swapchain)) {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001022 swapchainImageMap.erase(itr++);
1023 } else {
1024 ++itr;
1025 }
1026 }
Michael Lentine13803dc2015-11-04 14:35:12 -08001027 destroy_swapchain(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001028 loader_platform_thread_unlock_mutex(&objLock);
1029
Ian Elliott05846062015-11-20 14:13:17 -07001030 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001031}
1032
Mark Lobodzinski2141f652015-09-07 13:59:43 -06001033void
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001034explicit_FreeMemory(
1035 VkDevice device,
Chia-I Wuf7458c52015-10-26 21:10:41 +08001036 VkDeviceMemory mem,
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001037 const VkAllocationCallbacks* pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001038{
1039 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001040 validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001041 loader_platform_thread_unlock_mutex(&objLock);
1042
Chia-I Wuf7458c52015-10-26 21:10:41 +08001043 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001044
1045 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001046 destroy_device_memory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001047 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001048}
Tony Barboura05dbaa2015-07-09 17:31:46 -06001049
Tony Barbour770f80d2015-07-20 10:52:13 -06001050VkResult
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001051explicit_FreeDescriptorSets(
1052 VkDevice device,
1053 VkDescriptorPool descriptorPool,
1054 uint32_t count,
1055 const VkDescriptorSet *pDescriptorSets)
Tony Barbour770f80d2015-07-20 10:52:13 -06001056{
1057 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001058 validate_descriptor_pool(device, descriptorPool);
1059 validate_device(device, device);
Tony Barbour770f80d2015-07-20 10:52:13 -06001060 loader_platform_thread_unlock_mutex(&objLock);
1061 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
1062
1063 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter7ebf1212015-07-23 11:25:17 -06001064 for (uint32_t i=0; i<count; i++)
Tony Barbour770f80d2015-07-20 10:52:13 -06001065 {
Michael Lentinefc6aa762015-11-20 12:11:42 -08001066 free_descriptor_set(device, descriptorPool, *pDescriptorSets++);
Tony Barbour770f80d2015-07-20 10:52:13 -06001067 }
1068 loader_platform_thread_unlock_mutex(&objLock);
1069 return result;
1070}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001071
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001072void
1073explicit_DestroyDescriptorPool(
1074 VkDevice device,
1075 VkDescriptorPool descriptorPool,
1076 const VkAllocationCallbacks *pAllocator)
1077{
1078 VkBool32 skipCall = VK_FALSE;
1079 loader_platform_thread_lock_mutex(&objLock);
1080 skipCall |= validate_device(device, device);
1081 skipCall |= validate_descriptor_pool(device, descriptorPool);
1082 loader_platform_thread_unlock_mutex(&objLock);
1083 if (skipCall) {
1084 return;
1085 }
1086 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
1087 // Remove this pool's descriptor sets from our descriptorSet map.
1088 loader_platform_thread_lock_mutex(&objLock);
1089 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkDescriptorSetMap.begin();
1090 while (itr != VkDescriptorSetMap.end()) {
1091 OBJTRACK_NODE* pNode = (*itr).second;
Mark Lobodzinskib29731a2015-11-18 11:01:02 -07001092 auto del_itr = itr++;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001093 if (pNode->parentObj == reinterpret_cast<uint64_t>(descriptorPool)) {
Mark Lobodzinskib29731a2015-11-18 11:01:02 -07001094 destroy_descriptor_set(device, reinterpret_cast<VkDescriptorSet>((*del_itr).first));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001095 }
1096 }
1097 destroy_descriptor_pool(device, descriptorPool);
1098 loader_platform_thread_unlock_mutex(&objLock);
1099 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
1100}
1101
1102void
1103explicit_DestroyCommandPool(
1104 VkDevice device,
1105 VkCommandPool commandPool,
1106 const VkAllocationCallbacks *pAllocator)
1107{
1108 VkBool32 skipCall = VK_FALSE;
1109 loader_platform_thread_lock_mutex(&objLock);
1110 skipCall |= validate_device(device, device);
1111 skipCall |= validate_command_pool(device, commandPool);
1112 loader_platform_thread_unlock_mutex(&objLock);
1113 if (skipCall) {
1114 return;
1115 }
1116 loader_platform_thread_lock_mutex(&objLock);
1117 // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
1118 // Remove this pool's cmdBuffers from our cmd buffer map.
1119 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkCommandBufferMap.begin();
1120 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator del_itr;
1121 while (itr != VkCommandBufferMap.end()) {
1122 OBJTRACK_NODE* pNode = (*itr).second;
1123 del_itr = itr++;
1124 if (pNode->parentObj == reinterpret_cast<uint64_t>(commandPool)) {
1125 destroy_command_buffer(reinterpret_cast<VkCommandBuffer>((*del_itr).first),
1126 reinterpret_cast<VkCommandBuffer>((*del_itr).first));
1127 }
1128 }
1129 destroy_command_pool(device, commandPool);
1130 loader_platform_thread_unlock_mutex(&objLock);
1131 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
1132}
1133
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001134VkResult
1135explicit_GetSwapchainImagesKHR(
1136 VkDevice device,
1137 VkSwapchainKHR swapchain,
1138 uint32_t *pCount,
1139 VkImage *pSwapchainImages)
1140{
1141 VkBool32 skipCall = VK_FALSE;
1142 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001143 skipCall |= validate_device(device, device);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001144 loader_platform_thread_unlock_mutex(&objLock);
1145 if (skipCall)
1146 return VK_ERROR_VALIDATION_FAILED;
1147
1148 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
1149
1150 if (pSwapchainImages != NULL) {
1151 loader_platform_thread_lock_mutex(&objLock);
1152 for (uint32_t i = 0; i < *pCount; i++) {
1153 create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
1154 }
1155 loader_platform_thread_unlock_mutex(&objLock);
1156 }
1157 return result;
1158}
1159