blob: 6debcb97db42148bc0aee4ad7cb127968cb8bcd4 [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
62 VkDbgObjectType objType; // Object type identifier
63 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);
Tony Barboura05dbaa2015-07-09 17:31:46 -060069uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDbgObjectType 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);
Tony Barboura05dbaa2015-07-09 17:31:46 -060073typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDbgObjectType);
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
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600120static inline const char* string_VkDbgObjectType(VkDbgObjectType input_value)
121{
122 switch ((VkDbgObjectType)input_value)
123 {
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");
Michael Lentine64e2ebd2015-12-03 14:33:09 -0800222#elif VK_USE_PLATFORM_XCB_KHR
Mark Lobodzinskie86e1382015-11-24 15:50:44 -0700223 pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) gpa(instance, "vkCreateXcbSurfaceKHR");
224 pDisp->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
225#endif
226
Jon Ashburn3dc39382015-09-17 10:00:32 -0600227 instanceExtMap[pDisp].wsi_enabled = false;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800228 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700229 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
Jon Ashburn3dc39382015-09-17 10:00:32 -0600230 instanceExtMap[pDisp].wsi_enabled = true;
231
232 }
233}
234
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600235// Indicate device or instance dispatch table type
236typedef enum _DispTableType
237{
238 DISP_TBL_TYPE_INSTANCE,
239 DISP_TBL_TYPE_DEVICE,
240} DispTableType;
241
Tony Barboura05dbaa2015-07-09 17:31:46 -0600242debug_report_data *mdd(const void* object)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600243{
244 dispatch_key key = get_dispatch_key(object);
245 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600246 return my_data->report_data;
247}
248
249debug_report_data *mid(VkInstance object)
250{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600251 dispatch_key key = get_dispatch_key(object);
252 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600253 return my_data->report_data;
254}
255
256// For each Queue's doubly linked-list of mem refs
257typedef struct _OT_MEM_INFO {
258 VkDeviceMemory mem;
259 struct _OT_MEM_INFO *pNextMI;
260 struct _OT_MEM_INFO *pPrevMI;
261
262} OT_MEM_INFO;
263
264// Track Queue information
265typedef struct _OT_QUEUE_INFO {
266 OT_MEM_INFO *pMemRefList;
267 struct _OT_QUEUE_INFO *pNextQI;
268 uint32_t queueNodeIndex;
269 VkQueue queue;
270 uint32_t refCount;
271} OT_QUEUE_INFO;
272
273// Global list of QueueInfo structures, one per queue
274static OT_QUEUE_INFO *g_pQueueInfo = NULL;
275
276// Convert an object type enum to an object type array index
277static uint32_t
278objTypeToIndex(
279 uint32_t objType)
280{
281 uint32_t index = objType;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600282 return index;
283}
284
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600285// Add new queue to head of global queue list
286static void
287addQueueInfo(
288 uint32_t queueNodeIndex,
289 VkQueue queue)
290{
291 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
292
293 if (pQueueInfo != NULL) {
294 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
295 pQueueInfo->queue = queue;
296 pQueueInfo->queueNodeIndex = queueNodeIndex;
297 pQueueInfo->pNextQI = g_pQueueInfo;
298 g_pQueueInfo = pQueueInfo;
299 }
300 else {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600301 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<uint64_t>(queue), 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK",
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600302 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
303 }
304}
305
306// Destroy memRef lists and free all memory
307static void
308destroyQueueMemRefLists(void)
309{
310 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
311 OT_QUEUE_INFO *pDelQueueInfo = NULL;
312 while (pQueueInfo != NULL) {
313 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
314 while (pMemInfo != NULL) {
315 OT_MEM_INFO *pDelMemInfo = pMemInfo;
316 pMemInfo = pMemInfo->pNextMI;
317 delete pDelMemInfo;
318 }
319 pDelQueueInfo = pQueueInfo;
320 pQueueInfo = pQueueInfo->pNextQI;
321 delete pDelQueueInfo;
322 }
323 g_pQueueInfo = pQueueInfo;
324}
325
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600326static void
327setGpuQueueInfoState(
Tony Barbour59a47322015-06-24 16:06:58 -0600328 uint32_t count,
329 void *pData)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600330{
Tony Barbour59a47322015-06-24 16:06:58 -0600331 queueCount = count;
Cody Northropd0802882015-08-03 17:04:53 -0600332 queueInfo = (VkQueueFamilyProperties*)realloc((void*)queueInfo, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600333 if (queueInfo != NULL) {
Cody Northropd0802882015-08-03 17:04:53 -0600334 memcpy(queueInfo, pData, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600335 }
336}
337
338// Check Queue type flags for selected queue operations
339static void
340validateQueueFlags(
341 VkQueue queue,
342 const char *function)
343{
344 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
345 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
346 pQueueInfo = pQueueInfo->pNextQI;
347 }
348 if (pQueueInfo != NULL) {
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800349 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600350 log_msg(mdd(queue), VK_DBG_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 +0800351 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600352 } else {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600353 log_msg(mdd(queue), VK_DBG_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 +0800354 "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 -0600355 }
356 }
357}
358
Tony Barboura05dbaa2015-07-09 17:31:46 -0600359/* TODO: Port to new type safety */
360#if 0
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600361// Check object status for selected flag state
Courtney Goeltzenleuchtercd2a0992015-07-09 11:44:38 -0600362static VkBool32
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600363validate_status(
364 VkObject dispatchable_object,
365 VkObject vkObj,
366 VkObjectType objType,
367 ObjectStatusFlags status_mask,
368 ObjectStatusFlags status_flag,
369 VkFlags msg_flags,
370 OBJECT_TRACK_ERROR error_code,
371 const char *fail_msg)
372{
373 if (objMap.find(vkObj) != objMap.end()) {
374 OBJTRACK_NODE* pNode = objMap[vkObj];
375 if ((pNode->status & status_mask) != status_flag) {
376 char str[1024];
377 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
378 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600379 reinterpret_cast<uint64_t>(vkObj), fail_msg);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600380 return VK_FALSE;
381 }
382 return VK_TRUE;
383 }
384 else {
385 // If we do not find it print an error
386 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
387 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600388 reinterpret_cast<uint64_t>(vkObj), string_VkObjectType(objType));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600389 return VK_FALSE;
390 }
391}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600392#endif
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600393
394#include "vk_dispatch_table_helper.h"
395static void
396initObjectTracker(
397 layer_data *my_data)
398{
399 uint32_t report_flags = 0;
400 uint32_t debug_action = 0;
401 FILE *log_output = NULL;
402 const char *option_str;
403 // initialize ObjectTracker options
404 report_flags = getLayerOptionFlags("ObjectTrackerReportFlags", 0);
405 getLayerOptionEnum("ObjectTrackerDebugAction", (uint32_t *) &debug_action);
406
407 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
408 {
409 option_str = getLayerOption("ObjectTrackerLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600410 log_output = getLayerLogOutput(option_str, "ObjectTracker");
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700411 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 -0600412 }
413
414 if (!objLockInitialized)
415 {
416 // TODO/TBD: Need to delete this mutex sometime. How??? One
417 // suggestion is to call this during vkCreateInstance(), and then we
418 // can clean it up during vkDestroyInstance(). However, that requires
419 // that the layer have per-instance locks. We need to come back and
420 // address this soon.
421 loader_platform_thread_create_mutex(&objLock);
422 objLockInitialized = 1;
423 }
424}
425
Tony Barboura05dbaa2015-07-09 17:31:46 -0600426//
427// Forward declares of generated routines
428//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600429
Michael Lentine13803dc2015-11-04 14:35:12 -0800430static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDbgObjectType objType);
431static void create_instance(VkInstance dispatchable_object, VkInstance object, VkDbgObjectType objType);
432static void create_device(VkDevice dispatchable_object, VkDevice object, VkDbgObjectType objType);
Michael Lentine13803dc2015-11-04 14:35:12 -0800433static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectType objType);
434static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object);
435static VkBool32 validate_image(VkCommandBuffer dispatchable_object, VkImage object);
436static VkBool32 validate_command_buffer(VkQueue dispatchable_object, VkCommandBuffer object);
437static VkBool32 validate_descriptor_set(VkCommandBuffer dispatchable_object, VkDescriptorSet object);
438static VkBool32 validate_instance(VkInstance dispatchable_object, VkInstance object);
439static VkBool32 validate_device(VkDevice dispatchable_object, VkDevice object);
440static VkBool32 validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
441static VkBool32 validate_descriptor_set_layout(VkDevice dispatchable_object, VkDescriptorSetLayout object);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700442static VkBool32 validate_command_pool(VkDevice dispatchable_object, VkCommandPool object);
443static void destroy_command_pool(VkDevice dispatchable_object, VkCommandPool object);
444static void destroy_command_buffer(VkCommandBuffer dispatchable_object, VkCommandBuffer object);
445static void destroy_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
446static void destroy_descriptor_set(VkDevice dispatchable_object, VkDescriptorSet object);
Michael Lentine13803dc2015-11-04 14:35:12 -0800447static void destroy_instance(VkInstance dispatchable_object, VkInstance object);
448static void destroy_device_memory(VkDevice dispatchable_object, VkDeviceMemory object);
Michael Lentine13803dc2015-11-04 14:35:12 -0800449static VkBool32 set_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
450static VkBool32 reset_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600451#if 0
452static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDbgObjectType objType,
453 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
454 const char *fail_msg);
455#endif
Michael Lentine13803dc2015-11-04 14:35:12 -0800456extern unordered_map<uint64_t, OBJTRACK_NODE*> VkPhysicalDeviceMap;
457extern unordered_map<uint64_t, OBJTRACK_NODE*> VkImageMap;
458extern unordered_map<uint64_t, OBJTRACK_NODE*> VkQueueMap;
459extern unordered_map<uint64_t, OBJTRACK_NODE*> VkDescriptorSetMap;
460extern unordered_map<uint64_t, OBJTRACK_NODE*> VkBufferMap;
461extern unordered_map<uint64_t, OBJTRACK_NODE*> VkFenceMap;
462extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSemaphoreMap;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700463extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandPoolMap;
Michael Lentine13803dc2015-11-04 14:35:12 -0800464extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandBufferMap;
465extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSwapchainKHRMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600466
Michael Lentine13803dc2015-11-04 14:35:12 -0800467static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600468{
Michael Lentine13803dc2015-11-04 14:35:12 -0800469 if ((VkImageMap.find(reinterpret_cast<uint64_t>(object)) == VkImageMap.end()) &&
470 (swapchainImageMap.find(reinterpret_cast<uint64_t>(object)) == swapchainImageMap.end())) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800471 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800472 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600473 }
474 return VK_FALSE;
475}
476
Michael Lentine13803dc2015-11-04 14:35:12 -0800477static VkBool32 validate_image(VkCommandBuffer dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600478{
Michael Lentine13803dc2015-11-04 14:35:12 -0800479 if ((VkImageMap.find(reinterpret_cast<uint64_t>(object)) == VkImageMap.end()) &&
480 (swapchainImageMap.find(reinterpret_cast<uint64_t>(object)) == swapchainImageMap.end())) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800481 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800482 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600483 }
484 return VK_FALSE;
485}
486
Michael Lentine13803dc2015-11-04 14:35:12 -0800487static VkBool32 validate_command_buffer(VkQueue dispatchable_object, VkCommandBuffer object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600488{
Michael Lentine13803dc2015-11-04 14:35:12 -0800489 if (VkCommandBufferMap.find(reinterpret_cast<uint64_t>(object)) == VkCommandBufferMap.end()) {
Tobin Ehlisec598302015-09-15 15:02:17 -0600490 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, reinterpret_cast<uint64_t>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800491 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600492 }
493 return VK_FALSE;
494}
495
Michael Lentine13803dc2015-11-04 14:35:12 -0800496static VkBool32 validate_descriptor_set(VkCommandBuffer dispatchable_object, VkDescriptorSet object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600497{
Michael Lentine13803dc2015-11-04 14:35:12 -0800498 if (VkDescriptorSetMap.find(reinterpret_cast<uint64_t>(object)) == VkDescriptorSetMap.end()) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800499 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800500 "Invalid VkDescriptorSet Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600501 }
502 return VK_FALSE;
503}
504
Michael Lentine13803dc2015-11-04 14:35:12 -0800505static VkBool32 validate_buffer(VkQueue dispatchable_object, VkBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600506{
Michael Lentine13803dc2015-11-04 14:35:12 -0800507 if (VkBufferMap.find(reinterpret_cast<uint64_t>(object)) != VkBufferMap.end()) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800508 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800509 "Invalid VkBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600510 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600511 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600512}
513
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600514static VkBool32 set_status(VkQueue dispatchable_object, VkFence object, VkDbgObjectType objType, ObjectStatusFlags status_flag)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600515{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600516 VkBool32 skipCall = VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600517 if (object != VK_NULL_HANDLE) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800518 if (VkFenceMap.find(reinterpret_cast<uint64_t>(object)) != VkFenceMap.end()) {
519 OBJTRACK_NODE* pNode = VkFenceMap[reinterpret_cast<uint64_t>(object)];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600520 pNode->status |= status_flag;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600521 }
522 else {
523 // If we do not find it print an error
Chia-I Wue2fc5522015-10-26 20:04:44 +0800524 skipCall |= log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barboura05dbaa2015-07-09 17:31:46 -0600525 "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Michael Lentine13803dc2015-11-04 14:35:12 -0800526 reinterpret_cast<uint64_t>(object), string_VkDbgObjectType(objType));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600527 }
528 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600529 return skipCall;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600530}
531
Michael Lentine13803dc2015-11-04 14:35:12 -0800532static VkBool32 validate_semaphore(VkQueue dispatchable_object, VkSemaphore object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600533{
Michael Lentine13803dc2015-11-04 14:35:12 -0800534 if (VkSemaphoreMap.find(reinterpret_cast<uint64_t>(object)) == VkSemaphoreMap.end()) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800535 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800536 "Invalid VkSemaphore Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600537 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600538 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600539}
540
Michael Lentine13803dc2015-11-04 14:35:12 -0800541static VkBool32 validate_command_buffer(VkDevice dispatchable_object, VkCommandBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600542{
Michael Lentine13803dc2015-11-04 14:35:12 -0800543 if (VkCommandBufferMap.find(reinterpret_cast<uint64_t>(object)) == VkCommandBufferMap.end()) {
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600544 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, reinterpret_cast<uint64_t>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800545 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600546 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600547 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600548}
549
Michael Lentine13803dc2015-11-04 14:35:12 -0800550static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDbgObjectType objType)
Tobin Ehlisec598302015-09-15 15:02:17 -0600551{
552 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
553 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
554 reinterpret_cast<uint64_t>(vkObj));
555
556 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
557 pNewObjNode->objType = objType;
558 pNewObjNode->status = OBJSTATUS_NONE;
559 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800560 VkPhysicalDeviceMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600561 uint32_t objIndex = objTypeToIndex(objType);
562 numObjs[objIndex]++;
563 numTotalObjs++;
564}
565
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700566static void create_surface_khr(VkInstance instance, VkSurfaceKHR surface, VkDbgObjectType objType)
567{
568 // TODO: Add tracking of surface objects
569}
570
571static void destroy_surface_khr(VkInstance instance, VkSurfaceKHR surface)
572{
573 // TODO: Add tracking of surface objects
574}
575
Michael Lentinefc6aa762015-11-20 12:11:42 -0800576static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer vkObj, VkDbgObjectType objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600577{
Michael Lentinefc6aa762015-11-20 12:11:42 -0800578 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barboura05dbaa2015-07-09 17:31:46 -0600579 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600580 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600581
582 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700583 pNewObjNode->objType = objType;
584 pNewObjNode->status = OBJSTATUS_NONE;
585 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
586 pNewObjNode->parentObj = (uint64_t) commandPool;
Michael Lentine13803dc2015-11-04 14:35:12 -0800587 VkCommandBufferMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600588 uint32_t objIndex = objTypeToIndex(objType);
589 numObjs[objIndex]++;
590 numTotalObjs++;
591}
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700592
Michael Lentinefc6aa762015-11-20 12:11:42 -0800593static void free_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700594{
595 uint64_t object_handle = reinterpret_cast<uint64_t>(commandBuffer);
596 if (VkCommandBufferMap.find(object_handle) != VkCommandBufferMap.end()) {
597 OBJTRACK_NODE* pNode = VkCommandBufferMap[(uint64_t)commandBuffer];
598
599 if (pNode->parentObj != reinterpret_cast<uint64_t>(commandPool)) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800600 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, pNode->objType, object_handle, 0, OBJTRACK_COMMAND_POOL_MISMATCH, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700601 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
602 reinterpret_cast<uint64_t>(commandBuffer), pNode->parentObj, reinterpret_cast<uint64_t>(commandPool));
603 } else {
604
605 uint32_t objIndex = objTypeToIndex(pNode->objType);
606 assert(numTotalObjs > 0);
607 numTotalObjs--;
608 assert(numObjs[objIndex] > 0);
609 numObjs[objIndex]--;
Michael Lentinefc6aa762015-11-20 12:11:42 -0800610 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700611 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
612 string_VkDbgObjectType(pNode->objType), reinterpret_cast<uint64_t>(commandBuffer), numTotalObjs, numObjs[objIndex],
613 string_VkDbgObjectType(pNode->objType));
614 delete pNode;
615 VkCommandBufferMap.erase(object_handle);
616 }
617 } else {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800618 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700619 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
620 object_handle);
621 }
622}
623
Michael Lentinefc6aa762015-11-20 12:11:42 -0800624static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet vkObj, VkDbgObjectType objType)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700625{
Michael Lentinefc6aa762015-11-20 12:11:42 -0800626 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700627 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
628 reinterpret_cast<uint64_t>(vkObj));
629
630 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
631 pNewObjNode->objType = objType;
632 pNewObjNode->status = OBJSTATUS_NONE;
633 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
634 pNewObjNode->parentObj = (uint64_t) descriptorPool;
635 VkDescriptorSetMap[(uint64_t)vkObj] = pNewObjNode;
636 uint32_t objIndex = objTypeToIndex(objType);
637 numObjs[objIndex]++;
638 numTotalObjs++;
639}
640
Michael Lentinefc6aa762015-11-20 12:11:42 -0800641static void free_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet descriptorSet)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700642{
643 uint64_t object_handle = reinterpret_cast<uint64_t>(descriptorSet);
644 if (VkDescriptorSetMap.find(object_handle) != VkDescriptorSetMap.end()) {
645 OBJTRACK_NODE* pNode = VkDescriptorSetMap[(uint64_t)descriptorSet];
646
647 if (pNode->parentObj != reinterpret_cast<uint64_t>(descriptorPool)) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800648 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, pNode->objType, object_handle, 0, OBJTRACK_DESCRIPTOR_POOL_MISMATCH, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700649 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
650 reinterpret_cast<uint64_t>(descriptorSet), pNode->parentObj, reinterpret_cast<uint64_t>(descriptorPool));
651 } else {
652 uint32_t objIndex = objTypeToIndex(pNode->objType);
653 assert(numTotalObjs > 0);
654 numTotalObjs--;
655 assert(numObjs[objIndex] > 0);
656 numObjs[objIndex]--;
Michael Lentinefc6aa762015-11-20 12:11:42 -0800657 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700658 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
659 string_VkDbgObjectType(pNode->objType), reinterpret_cast<uint64_t>(descriptorSet), numTotalObjs, numObjs[objIndex],
660 string_VkDbgObjectType(pNode->objType));
661 delete pNode;
662 VkDescriptorSetMap.erase(object_handle);
663 }
664 } else {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800665 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700666 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
667 object_handle);
668 }
669}
670
Michael Lentine13803dc2015-11-04 14:35:12 -0800671static void create_swapchain_khr(VkDevice dispatchable_object, VkSwapchainKHR vkObj, VkDbgObjectType objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600672{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800673 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, (uint64_t) vkObj, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barboura05dbaa2015-07-09 17:31:46 -0600674 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Michael Lentine13803dc2015-11-04 14:35:12 -0800675 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600676
677 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
678 pNewObjNode->objType = objType;
679 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800680 pNewObjNode->vkObj = (uint64_t) vkObj;
Michael Lentine13803dc2015-11-04 14:35:12 -0800681 VkSwapchainKHRMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600682 uint32_t objIndex = objTypeToIndex(objType);
683 numObjs[objIndex]++;
684 numTotalObjs++;
685}
Michael Lentine13803dc2015-11-04 14:35:12 -0800686static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectType objType)
Tobin Ehlisec598302015-09-15 15:02:17 -0600687{
688 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
689 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
690 reinterpret_cast<uint64_t>(vkObj));
691
692 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
693 pNewObjNode->objType = objType;
694 pNewObjNode->status = OBJSTATUS_NONE;
695 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800696 VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600697 uint32_t objIndex = objTypeToIndex(objType);
698 numObjs[objIndex]++;
699 numTotalObjs++;
700}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600701static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain)
702{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800703 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_IMAGE, (uint64_t) vkObj, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600704 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, "SwapchainImage",
Michael Lentine13803dc2015-11-04 14:35:12 -0800705 reinterpret_cast<uint64_t>(vkObj));
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600706
707 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
708 pNewObjNode->objType = VK_OBJECT_TYPE_IMAGE;
709 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800710 pNewObjNode->vkObj = (uint64_t) vkObj;
711 pNewObjNode->parentObj = (uint64_t) swapchain;
Michael Lentine13803dc2015-11-04 14:35:12 -0800712 swapchainImageMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600713}
714
Michael Lentine13803dc2015-11-04 14:35:12 -0800715static void destroy_swapchain(VkDevice dispatchable_object, VkSwapchainKHR object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600716{
Michael Lentine13803dc2015-11-04 14:35:12 -0800717 if (VkSwapchainKHRMap.find(reinterpret_cast<uint64_t>(object)) != VkSwapchainKHRMap.end()) {
718 OBJTRACK_NODE* pNode = VkSwapchainKHRMap[reinterpret_cast<uint64_t>(object)];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600719 uint32_t objIndex = objTypeToIndex(pNode->objType);
720 assert(numTotalObjs > 0);
721 numTotalObjs--;
722 assert(numObjs[objIndex] > 0);
723 numObjs[objIndex]--;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800724 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, pNode->objType, (uint64_t) object, 0, OBJTRACK_NONE, "OBJTRACK",
Michael Lentine010f4692015-11-03 16:19:46 -0800725 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800726 string_VkDbgObjectType(pNode->objType), (uint64_t) object, numTotalObjs, numObjs[objIndex],
Tony Barboura05dbaa2015-07-09 17:31:46 -0600727 string_VkDbgObjectType(pNode->objType));
728 delete pNode;
Michael Lentine13803dc2015-11-04 14:35:12 -0800729 VkSwapchainKHRMap.erase(reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600730 } else {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800731 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barboura05dbaa2015-07-09 17:31:46 -0600732 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
Michael Lentine13803dc2015-11-04 14:35:12 -0800733 reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600734 }
735}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600736//
737// Non-auto-generated API functions called by generated code
738//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600739VkResult
740explicit_CreateInstance(
741 const VkInstanceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800742 const VkAllocationCallbacks * pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600743 VkInstance * pInstance)
744{
David Pinedoc0fa1ab2015-07-31 10:46:25 -0600745
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600746 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, *pInstance);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800747 VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600748
749 if (result == VK_SUCCESS) {
750 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
751 my_data->report_data = debug_report_create_instance(
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600752 pInstanceTable,
753 *pInstance,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800754 pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600755 pCreateInfo->ppEnabledExtensionNames);
Jon Ashburn3dc39382015-09-17 10:00:32 -0600756 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600757
758 initObjectTracker(my_data);
Michael Lentine13803dc2015-11-04 14:35:12 -0800759 create_instance(*pInstance, *pInstance, VK_OBJECT_TYPE_INSTANCE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600760 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600761 return result;
762}
763
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600764void
Cody Northropd0802882015-08-03 17:04:53 -0600765explicit_GetPhysicalDeviceQueueFamilyProperties(
Tony Barbour59a47322015-06-24 16:06:58 -0600766 VkPhysicalDevice gpu,
Cody Northropd0802882015-08-03 17:04:53 -0600767 uint32_t* pCount,
768 VkQueueFamilyProperties* pProperties)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600769{
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600770 get_dispatch_table(ObjectTracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600771
772 loader_platform_thread_lock_mutex(&objLock);
Cody Northropd0802882015-08-03 17:04:53 -0600773 if (pProperties != NULL)
774 setGpuQueueInfoState(*pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600775 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600776}
777
778VkResult
779explicit_CreateDevice(
780 VkPhysicalDevice gpu,
781 const VkDeviceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800782 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600783 VkDevice *pDevice)
784{
785 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600786// VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, gpu);
787 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800788 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600789 if (result == VK_SUCCESS) {
790 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
791 //// VkLayerDispatchTable *pTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
792 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
793 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Michael Lentine13803dc2015-11-04 14:35:12 -0800794 create_device(*pDevice, *pDevice, VK_OBJECT_TYPE_DEVICE);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600795 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600796 }
797
798 loader_platform_thread_unlock_mutex(&objLock);
799 return result;
800}
801
Tobin Ehlisec598302015-09-15 15:02:17 -0600802VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
803{
804 VkBool32 skipCall = VK_FALSE;
805 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800806 skipCall |= validate_instance(instance, instance);
Tobin Ehlisec598302015-09-15 15:02:17 -0600807 loader_platform_thread_unlock_mutex(&objLock);
808 if (skipCall)
809 return VK_ERROR_VALIDATION_FAILED;
810 VkResult result = get_dispatch_table(ObjectTracker_instance_table_map, instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
811 loader_platform_thread_lock_mutex(&objLock);
812 if (result == VK_SUCCESS) {
813 if (pPhysicalDevices) {
814 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800815 create_physical_device(instance, pPhysicalDevices[i], VK_OBJECT_TYPE_PHYSICAL_DEVICE);
Tobin Ehlisec598302015-09-15 15:02:17 -0600816 }
817 }
818 }
819 loader_platform_thread_unlock_mutex(&objLock);
820 return result;
821}
822
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600823void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600824explicit_GetDeviceQueue(
825 VkDevice device,
826 uint32_t queueNodeIndex,
827 uint32_t queueIndex,
828 VkQueue *pQueue)
829{
830 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800831 validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600832 loader_platform_thread_unlock_mutex(&objLock);
833
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600834 get_dispatch_table(ObjectTracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600835
836 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600837 addQueueInfo(queueNodeIndex, *pQueue);
Michael Lentine13803dc2015-11-04 14:35:12 -0800838 create_queue(device, *pQueue, VK_OBJECT_TYPE_QUEUE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600839 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600840}
841
842VkResult
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600843explicit_MapMemory(
844 VkDevice device,
845 VkDeviceMemory mem,
846 VkDeviceSize offset,
847 VkDeviceSize size,
848 VkFlags flags,
849 void **ppData)
850{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600851 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600852 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800853 skipCall |= set_device_memory_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
854 skipCall |= validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600855 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600856 if (skipCall == VK_TRUE)
857 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600858
859 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
860
861 return result;
862}
863
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600864void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600865explicit_UnmapMemory(
866 VkDevice device,
867 VkDeviceMemory mem)
868{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600869 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600870 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800871 skipCall |= reset_device_memory_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
872 skipCall |= validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600873 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600874 if (skipCall == VK_TRUE)
875 return;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600876
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600877 get_dispatch_table(ObjectTracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600878}
879
880VkResult
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800881explicit_QueueBindSparse(
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600882 VkQueue queue,
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800883 uint32_t bindInfoCount,
884 const VkBindSparseInfo* pBindInfo,
885 VkFence fence)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600886{
887 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800888 validateQueueFlags(queue, "QueueBindSparse");
889
890 for (uint32_t i = 0; i < bindInfoCount; i++) {
891 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800892 validate_buffer(queue, pBindInfo[i].pBufferBinds[j].buffer);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800893 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800894 validate_image(queue, pBindInfo[i].pImageOpaqueBinds[j].image);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800895 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800896 validate_image(queue, pBindInfo[i].pImageBinds[j].image);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800897 }
898
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600899 loader_platform_thread_unlock_mutex(&objLock);
900
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800901 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600902 return result;
903}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600904
905VkResult
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700906explicit_AllocateCommandBuffers(
907 VkDevice device,
908 const VkCommandBufferAllocateInfo *pAllocateInfo,
909 VkCommandBuffer* pCommandBuffers)
910{
911 VkBool32 skipCall = VK_FALSE;
912 loader_platform_thread_lock_mutex(&objLock);
913 skipCall |= validate_device(device, device);
914 skipCall |= validate_command_pool(device, pAllocateInfo->commandPool);
915 loader_platform_thread_unlock_mutex(&objLock);
916
917 if (skipCall) {
918 return VK_ERROR_VALIDATION_FAILED;
919 }
920
921 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateCommandBuffers(
922 device, pAllocateInfo, pCommandBuffers);
923
924 loader_platform_thread_lock_mutex(&objLock);
925 for (uint32_t i = 0; i < pAllocateInfo->bufferCount; i++) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800926 alloc_command_buffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], VK_OBJECT_TYPE_COMMAND_BUFFER);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700927 }
928 loader_platform_thread_unlock_mutex(&objLock);
929
930 return result;
931}
932
933VkResult
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800934explicit_AllocateDescriptorSets(
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700935 VkDevice device,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800936 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700937 VkDescriptorSet *pDescriptorSets)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600938{
Tobin Ehlisec598302015-09-15 15:02:17 -0600939 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600940 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800941 skipCall |= validate_device(device, device);
942 skipCall |= validate_descriptor_pool(device, pAllocateInfo->descriptorPool);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800943 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800944 skipCall |= validate_descriptor_set_layout(device, pAllocateInfo->pSetLayouts[i]);
Tobin Ehlisec598302015-09-15 15:02:17 -0600945 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600946 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600947 if (skipCall)
948 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600949
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800950 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateDescriptorSets(
951 device, pAllocateInfo, pDescriptorSets);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600952
953 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800954 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800955 alloc_descriptor_set(device, pAllocateInfo->descriptorPool, pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600956 }
957 loader_platform_thread_unlock_mutex(&objLock);
958
959 return result;
960}
961
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700962void
963explicit_FreeCommandBuffers(
964 VkDevice device,
965 VkCommandPool commandPool,
966 uint32_t commandBufferCount,
967 const VkCommandBuffer *pCommandBuffers)
968{
969 loader_platform_thread_lock_mutex(&objLock);
970 validate_command_pool(device, commandPool);
971 validate_device(device, device);
972 loader_platform_thread_unlock_mutex(&objLock);
973
974 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeCommandBuffers(device,
975 commandPool, commandBufferCount, pCommandBuffers);
976
977 loader_platform_thread_lock_mutex(&objLock);
978 for (uint32_t i = 0; i < commandBufferCount; i++)
979 {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800980 free_command_buffer(device, commandPool, *pCommandBuffers);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700981 pCommandBuffers++;
982 }
983 loader_platform_thread_unlock_mutex(&objLock);
984}
985
Ian Elliott05846062015-11-20 14:13:17 -0700986void
Ian Elliott7e40db92015-08-21 15:09:33 -0600987explicit_DestroySwapchainKHR(
Ian Elliott05846062015-11-20 14:13:17 -0700988 VkDevice device,
989 VkSwapchainKHR swapchain,
990 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600991{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600992 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600993 // A swapchain's images are implicitly deleted when the swapchain is deleted.
994 // Remove this swapchain's images from our map of such images.
Michael Lentine13803dc2015-11-04 14:35:12 -0800995 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = swapchainImageMap.begin();
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600996 while (itr != swapchainImageMap.end()) {
997 OBJTRACK_NODE* pNode = (*itr).second;
Michael Lentine13803dc2015-11-04 14:35:12 -0800998 if (pNode->parentObj == reinterpret_cast<uint64_t>(swapchain)) {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600999 swapchainImageMap.erase(itr++);
1000 } else {
1001 ++itr;
1002 }
1003 }
Michael Lentine13803dc2015-11-04 14:35:12 -08001004 destroy_swapchain(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001005 loader_platform_thread_unlock_mutex(&objLock);
1006
Ian Elliott05846062015-11-20 14:13:17 -07001007 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001008}
1009
Mark Lobodzinski2141f652015-09-07 13:59:43 -06001010void
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001011explicit_FreeMemory(
1012 VkDevice device,
Chia-I Wuf7458c52015-10-26 21:10:41 +08001013 VkDeviceMemory mem,
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001014 const VkAllocationCallbacks* pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001015{
1016 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001017 validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001018 loader_platform_thread_unlock_mutex(&objLock);
1019
Chia-I Wuf7458c52015-10-26 21:10:41 +08001020 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001021
1022 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001023 destroy_device_memory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001024 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001025}
Tony Barboura05dbaa2015-07-09 17:31:46 -06001026
Tony Barbour770f80d2015-07-20 10:52:13 -06001027VkResult
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001028explicit_FreeDescriptorSets(
1029 VkDevice device,
1030 VkDescriptorPool descriptorPool,
1031 uint32_t count,
1032 const VkDescriptorSet *pDescriptorSets)
Tony Barbour770f80d2015-07-20 10:52:13 -06001033{
1034 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001035 validate_descriptor_pool(device, descriptorPool);
1036 validate_device(device, device);
Tony Barbour770f80d2015-07-20 10:52:13 -06001037 loader_platform_thread_unlock_mutex(&objLock);
1038 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
1039
1040 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter7ebf1212015-07-23 11:25:17 -06001041 for (uint32_t i=0; i<count; i++)
Tony Barbour770f80d2015-07-20 10:52:13 -06001042 {
Michael Lentinefc6aa762015-11-20 12:11:42 -08001043 free_descriptor_set(device, descriptorPool, *pDescriptorSets++);
Tony Barbour770f80d2015-07-20 10:52:13 -06001044 }
1045 loader_platform_thread_unlock_mutex(&objLock);
1046 return result;
1047}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001048
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001049void
1050explicit_DestroyDescriptorPool(
1051 VkDevice device,
1052 VkDescriptorPool descriptorPool,
1053 const VkAllocationCallbacks *pAllocator)
1054{
1055 VkBool32 skipCall = VK_FALSE;
1056 loader_platform_thread_lock_mutex(&objLock);
1057 skipCall |= validate_device(device, device);
1058 skipCall |= validate_descriptor_pool(device, descriptorPool);
1059 loader_platform_thread_unlock_mutex(&objLock);
1060 if (skipCall) {
1061 return;
1062 }
1063 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
1064 // Remove this pool's descriptor sets from our descriptorSet map.
1065 loader_platform_thread_lock_mutex(&objLock);
1066 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkDescriptorSetMap.begin();
1067 while (itr != VkDescriptorSetMap.end()) {
1068 OBJTRACK_NODE* pNode = (*itr).second;
Mark Lobodzinskib29731a2015-11-18 11:01:02 -07001069 auto del_itr = itr++;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001070 if (pNode->parentObj == reinterpret_cast<uint64_t>(descriptorPool)) {
Mark Lobodzinskib29731a2015-11-18 11:01:02 -07001071 destroy_descriptor_set(device, reinterpret_cast<VkDescriptorSet>((*del_itr).first));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001072 }
1073 }
1074 destroy_descriptor_pool(device, descriptorPool);
1075 loader_platform_thread_unlock_mutex(&objLock);
1076 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
1077}
1078
1079void
1080explicit_DestroyCommandPool(
1081 VkDevice device,
1082 VkCommandPool commandPool,
1083 const VkAllocationCallbacks *pAllocator)
1084{
1085 VkBool32 skipCall = VK_FALSE;
1086 loader_platform_thread_lock_mutex(&objLock);
1087 skipCall |= validate_device(device, device);
1088 skipCall |= validate_command_pool(device, commandPool);
1089 loader_platform_thread_unlock_mutex(&objLock);
1090 if (skipCall) {
1091 return;
1092 }
1093 loader_platform_thread_lock_mutex(&objLock);
1094 // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
1095 // Remove this pool's cmdBuffers from our cmd buffer map.
1096 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkCommandBufferMap.begin();
1097 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator del_itr;
1098 while (itr != VkCommandBufferMap.end()) {
1099 OBJTRACK_NODE* pNode = (*itr).second;
1100 del_itr = itr++;
1101 if (pNode->parentObj == reinterpret_cast<uint64_t>(commandPool)) {
1102 destroy_command_buffer(reinterpret_cast<VkCommandBuffer>((*del_itr).first),
1103 reinterpret_cast<VkCommandBuffer>((*del_itr).first));
1104 }
1105 }
1106 destroy_command_pool(device, commandPool);
1107 loader_platform_thread_unlock_mutex(&objLock);
1108 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
1109}
1110
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001111VkResult
1112explicit_GetSwapchainImagesKHR(
1113 VkDevice device,
1114 VkSwapchainKHR swapchain,
1115 uint32_t *pCount,
1116 VkImage *pSwapchainImages)
1117{
1118 VkBool32 skipCall = VK_FALSE;
1119 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001120 skipCall |= validate_device(device, device);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001121 loader_platform_thread_unlock_mutex(&objLock);
1122 if (skipCall)
1123 return VK_ERROR_VALIDATION_FAILED;
1124
1125 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
1126
1127 if (pSwapchainImages != NULL) {
1128 loader_platform_thread_lock_mutex(&objLock);
1129 for (uint32_t i = 0; i < *pCount; i++) {
1130 create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
1131 }
1132 loader_platform_thread_unlock_mutex(&objLock);
1133 }
1134 return result;
1135}
1136