blob: 43089178eab9b8132e882893a5bb61a713105aaa [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
Tobin Ehlis42586532014-11-14 13:01:02 -07004 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060022 *
23 * Author: Jon Ashburn <jon@lunarg.com>
24 * Author: Mark Lobodzinski <mark@lunarg.com>
25 * Author: Tobin Ehlis <tobin@lunarg.com>
Tobin Ehlis42586532014-11-14 13:01:02 -070026 */
27
David Pinedo9316d3b2015-11-06 12:54:48 -070028#include "vulkan/vk_layer.h"
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060029#include "vk_layer_extension_utils.h"
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060030#include "vk_enum_string_helper.h"
Mark Lobodzinskifae78852015-06-23 11:35:12 -060031
Tobin Ehlisca915872014-11-18 11:28:33 -070032// Object Tracker ERROR codes
33typedef enum _OBJECT_TRACK_ERROR
34{
Chia-I Wu09cf5f02015-01-05 14:33:42 +080035 OBJTRACK_NONE, // Used for INFO & other non-error messages
36 OBJTRACK_UNKNOWN_OBJECT, // Updating uses of object that's not in global object list
37 OBJTRACK_INTERNAL_ERROR, // Bug with data tracking within the layer
38 OBJTRACK_DESTROY_OBJECT_FAILED, // Couldn't find object to be destroyed
Chia-I Wu09cf5f02015-01-05 14:33:42 +080039 OBJTRACK_OBJECT_LEAK, // OBJECT was not correctly freed/destroyed
40 OBJTRACK_OBJCOUNT_MAX_EXCEEDED, // Request for Object data in excess of max obj count
Tobin Ehlis803cc492015-06-08 17:36:28 -060041 OBJTRACK_INVALID_OBJECT, // Object used that has never been created
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -070042 OBJTRACK_DESCRIPTOR_POOL_MISMATCH, // Descriptor Pools specified incorrectly
43 OBJTRACK_COMMAND_POOL_MISMATCH, // Command Pools specified incorrectly
Tobin Ehlisca915872014-11-18 11:28:33 -070044} OBJECT_TRACK_ERROR;
45
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070046// Object Status -- used to track state of individual objects
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050047typedef VkFlags ObjectStatusFlags;
48typedef enum _ObjectStatusFlagBits
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070049{
Mark Lobodzinski40370872015-02-03 10:06:31 -060050 OBJSTATUS_NONE = 0x00000000, // No status is set
51 OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted
52 OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound
53 OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound
54 OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound
55 OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound
Mark Lobodzinski4988dea2015-02-03 11:52:26 -060056 OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050057} ObjectStatusFlagBits;
Chia-I Wuf8693382015-04-16 22:02:10 +080058
Tobin Ehlis42586532014-11-14 13:01:02 -070059typedef struct _OBJTRACK_NODE {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060060 uint64_t vkObj; // Object handle
61 VkDbgObjectType objType; // Object type identifier
62 ObjectStatusFlags status; // Object state
63 uint64_t parentObj; // Parent object
Tobin Ehlis42586532014-11-14 13:01:02 -070064} OBJTRACK_NODE;
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060065
Tobin Ehlis42586532014-11-14 13:01:02 -070066// prototype for extension functions
Mark Lobodzinskifae78852015-06-23 11:35:12 -060067uint64_t objTrackGetObjectCount(VkDevice device);
Tony Barboura05dbaa2015-07-09 17:31:46 -060068uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDbgObjectType type);
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060069
Tobin Ehlisca915872014-11-18 11:28:33 -070070// Func ptr typedefs
Mark Lobodzinskifae78852015-06-23 11:35:12 -060071typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
Tony Barboura05dbaa2015-07-09 17:31:46 -060072typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDbgObjectType);
Mark Lobodzinskifae78852015-06-23 11:35:12 -060073
Cody Northrop55443ef2015-09-28 15:09:32 -060074struct layer_data {
Mark Lobodzinskifae78852015-06-23 11:35:12 -060075 debug_report_data *report_data;
76 //TODO: put instance data here
77 VkDbgMsgCallback logging_callback;
Ian Elliott1064fe32015-07-06 14:31:32 -060078 bool wsi_enabled;
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060079 bool objtrack_extensions_enabled;
Cody Northrop55443ef2015-09-28 15:09:32 -060080
81 layer_data() :
82 report_data(nullptr),
Michael Lentine13803dc2015-11-04 14:35:12 -080083 logging_callback(VK_NULL_HANDLE),
Cody Northrop55443ef2015-09-28 15:09:32 -060084 wsi_enabled(false),
85 objtrack_extensions_enabled(false)
86 {};
87};
Mark Lobodzinskifae78852015-06-23 11:35:12 -060088
Jon Ashburn3dc39382015-09-17 10:00:32 -060089struct instExts {
90 bool wsi_enabled;
91};
92
93static std::unordered_map<void *, struct instExts> instanceExtMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -060094static std::unordered_map<void*, layer_data *> layer_data_map;
95static device_table_map ObjectTracker_device_table_map;
96static instance_table_map ObjectTracker_instance_table_map;
97
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060098// We need additionally validate image usage using a separate map
99// of swapchain-created images
Michael Lentine13803dc2015-11-04 14:35:12 -0800100static unordered_map<uint64_t, OBJTRACK_NODE*> swapchainImageMap;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600101
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600102static long long unsigned int object_track_index = 0;
103static int objLockInitialized = 0;
104static loader_platform_thread_mutex objLock;
105
106// Objects stored in a global map w/ struct containing basic info
Tony Barboura05dbaa2015-07-09 17:31:46 -0600107// unordered_map<const void*, OBJTRACK_NODE*> objMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600108
Tony Barboura05dbaa2015-07-09 17:31:46 -0600109#define NUM_OBJECT_TYPES VK_OBJECT_TYPE_NUM
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600110
111static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
112static uint64_t numTotalObjs = 0;
Cody Northropd0802882015-08-03 17:04:53 -0600113static VkQueueFamilyProperties *queueInfo = NULL;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600114static uint32_t queueCount = 0;
115
116template layer_data *get_my_data_ptr<layer_data>(
117 void *data_key, std::unordered_map<void *, layer_data *> &data_map);
118
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600119static inline const char* string_VkDbgObjectType(VkDbgObjectType input_value)
120{
121 switch ((VkDbgObjectType)input_value)
122 {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800123 case VK_OBJECT_TYPE_COMMAND_POOL:
124 return "VK_OBJECT_TYPE_COMMAND_POOL";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600125 case VK_OBJECT_TYPE_BUFFER:
126 return "VK_OBJECT_TYPE_BUFFER";
127 case VK_OBJECT_TYPE_BUFFER_VIEW:
128 return "VK_OBJECT_TYPE_BUFFER_VIEW";
129 case VK_OBJECT_TYPE_ATTACHMENT_VIEW:
130 return "VK_OBJECT_TYPE_ATTACHMENT_VIEW";
131 case VK_OBJECT_TYPE_COMMAND_BUFFER:
132 return "VK_OBJECT_TYPE_COMMAND_BUFFER";
133 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
134 return "VK_OBJECT_TYPE_DESCRIPTOR_POOL";
135 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
136 return "VK_OBJECT_TYPE_DESCRIPTOR_SET";
137 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
138 return "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT";
139 case VK_OBJECT_TYPE_DEVICE:
140 return "VK_OBJECT_TYPE_DEVICE";
141 case VK_OBJECT_TYPE_DEVICE_MEMORY:
142 return "VK_OBJECT_TYPE_DEVICE_MEMORY";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600143 case VK_OBJECT_TYPE_EVENT:
144 return "VK_OBJECT_TYPE_EVENT";
145 case VK_OBJECT_TYPE_FENCE:
146 return "VK_OBJECT_TYPE_FENCE";
147 case VK_OBJECT_TYPE_FRAMEBUFFER:
148 return "VK_OBJECT_TYPE_FRAMEBUFFER";
149 case VK_OBJECT_TYPE_IMAGE:
150 return "VK_OBJECT_TYPE_IMAGE";
151 case VK_OBJECT_TYPE_IMAGE_VIEW:
152 return "VK_OBJECT_TYPE_IMAGE_VIEW";
153 case VK_OBJECT_TYPE_INSTANCE:
154 return "VK_OBJECT_TYPE_INSTANCE";
155 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
156 return "VK_OBJECT_TYPE_PHYSICAL_DEVICE";
157 case VK_OBJECT_TYPE_PIPELINE:
158 return "VK_OBJECT_TYPE_PIPELINE";
159 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
160 return "VK_OBJECT_TYPE_PIPELINE_LAYOUT";
161 case VK_OBJECT_TYPE_PIPELINE_CACHE:
162 return "VK_OBJECT_TYPE_PIPELINE_CACHE";
163 case VK_OBJECT_TYPE_QUERY_POOL:
164 return "VK_OBJECT_TYPE_QUERY_POOL";
165 case VK_OBJECT_TYPE_QUEUE:
166 return "VK_OBJECT_TYPE_QUEUE";
167 case VK_OBJECT_TYPE_RENDER_PASS:
168 return "VK_OBJECT_TYPE_RENDER_PASS";
169 case VK_OBJECT_TYPE_SAMPLER:
170 return "VK_OBJECT_TYPE_SAMPLER";
171 case VK_OBJECT_TYPE_SEMAPHORE:
172 return "VK_OBJECT_TYPE_SEMAPHORE";
173 case VK_OBJECT_TYPE_SHADER:
174 return "VK_OBJECT_TYPE_SHADER";
175 case VK_OBJECT_TYPE_SHADER_MODULE:
176 return "VK_OBJECT_TYPE_SHADER_MODULE";
Ian Elliott7e40db92015-08-21 15:09:33 -0600177 case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
178 return "VK_OBJECT_TYPE_SWAPCHAIN_KHR";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600179 default:
180 return "Unhandled VkObjectType";
181 }
182}
183
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600184//
185// Internal Object Tracker Functions
186//
187
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600188static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
189{
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600190 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600191 VkLayerDispatchTable *pDisp = get_dispatch_table(ObjectTracker_device_table_map, device);
192 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
Jon Ashburn8acd2332015-09-16 18:08:32 -0600193 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
194 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
195 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
196 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
197 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
Ian Elliott1064fe32015-07-06 14:31:32 -0600198 my_device_data->wsi_enabled = false;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800199 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700200 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliott1064fe32015-07-06 14:31:32 -0600201 my_device_data->wsi_enabled = true;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600202
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600203 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0)
204 my_device_data->objtrack_extensions_enabled = true;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600205 }
206}
207
Jon Ashburn3dc39382015-09-17 10:00:32 -0600208static void createInstanceRegisterExtensions(const VkInstanceCreateInfo* pCreateInfo, VkInstance instance)
209{
210 uint32_t i;
211 VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(ObjectTracker_instance_table_map, instance);
212 PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
213 pDisp->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
Ian Elliott05846062015-11-20 14:13:17 -0700214 pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
215 pDisp->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
216 pDisp->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
Mark Lobodzinskie86e1382015-11-24 15:50:44 -0700217
218#if VK_USE_PLATFORM_WIN32_KHR
219 pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) gpa(instance, "vkCreateWin32SurfaceKHR");
220 pDisp->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
221#else // VK_USE_PLATFORM_XCB_KHR
222 pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) gpa(instance, "vkCreateXcbSurfaceKHR");
223 pDisp->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
224#endif
225
Jon Ashburn3dc39382015-09-17 10:00:32 -0600226 instanceExtMap[pDisp].wsi_enabled = false;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800227 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700228 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
Jon Ashburn3dc39382015-09-17 10:00:32 -0600229 instanceExtMap[pDisp].wsi_enabled = true;
230
231 }
232}
233
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600234// Indicate device or instance dispatch table type
235typedef enum _DispTableType
236{
237 DISP_TBL_TYPE_INSTANCE,
238 DISP_TBL_TYPE_DEVICE,
239} DispTableType;
240
Tony Barboura05dbaa2015-07-09 17:31:46 -0600241debug_report_data *mdd(const void* object)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600242{
243 dispatch_key key = get_dispatch_key(object);
244 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600245 return my_data->report_data;
246}
247
248debug_report_data *mid(VkInstance object)
249{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600250 dispatch_key key = get_dispatch_key(object);
251 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600252 return my_data->report_data;
253}
254
255// For each Queue's doubly linked-list of mem refs
256typedef struct _OT_MEM_INFO {
257 VkDeviceMemory mem;
258 struct _OT_MEM_INFO *pNextMI;
259 struct _OT_MEM_INFO *pPrevMI;
260
261} OT_MEM_INFO;
262
263// Track Queue information
264typedef struct _OT_QUEUE_INFO {
265 OT_MEM_INFO *pMemRefList;
266 struct _OT_QUEUE_INFO *pNextQI;
267 uint32_t queueNodeIndex;
268 VkQueue queue;
269 uint32_t refCount;
270} OT_QUEUE_INFO;
271
272// Global list of QueueInfo structures, one per queue
273static OT_QUEUE_INFO *g_pQueueInfo = NULL;
274
275// Convert an object type enum to an object type array index
276static uint32_t
277objTypeToIndex(
278 uint32_t objType)
279{
280 uint32_t index = objType;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600281 return index;
282}
283
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600284// Add new queue to head of global queue list
285static void
286addQueueInfo(
287 uint32_t queueNodeIndex,
288 VkQueue queue)
289{
290 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
291
292 if (pQueueInfo != NULL) {
293 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
294 pQueueInfo->queue = queue;
295 pQueueInfo->queueNodeIndex = queueNodeIndex;
296 pQueueInfo->pNextQI = g_pQueueInfo;
297 g_pQueueInfo = pQueueInfo;
298 }
299 else {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600300 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 -0600301 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
302 }
303}
304
305// Destroy memRef lists and free all memory
306static void
307destroyQueueMemRefLists(void)
308{
309 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
310 OT_QUEUE_INFO *pDelQueueInfo = NULL;
311 while (pQueueInfo != NULL) {
312 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
313 while (pMemInfo != NULL) {
314 OT_MEM_INFO *pDelMemInfo = pMemInfo;
315 pMemInfo = pMemInfo->pNextMI;
316 delete pDelMemInfo;
317 }
318 pDelQueueInfo = pQueueInfo;
319 pQueueInfo = pQueueInfo->pNextQI;
320 delete pDelQueueInfo;
321 }
322 g_pQueueInfo = pQueueInfo;
323}
324
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600325static void
326setGpuQueueInfoState(
Tony Barbour59a47322015-06-24 16:06:58 -0600327 uint32_t count,
328 void *pData)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600329{
Tony Barbour59a47322015-06-24 16:06:58 -0600330 queueCount = count;
Cody Northropd0802882015-08-03 17:04:53 -0600331 queueInfo = (VkQueueFamilyProperties*)realloc((void*)queueInfo, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600332 if (queueInfo != NULL) {
Cody Northropd0802882015-08-03 17:04:53 -0600333 memcpy(queueInfo, pData, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600334 }
335}
336
337// Check Queue type flags for selected queue operations
338static void
339validateQueueFlags(
340 VkQueue queue,
341 const char *function)
342{
343 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
344 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
345 pQueueInfo = pQueueInfo->pNextQI;
346 }
347 if (pQueueInfo != NULL) {
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800348 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600349 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 +0800350 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600351 } else {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600352 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 +0800353 "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 -0600354 }
355 }
356}
357
Tony Barboura05dbaa2015-07-09 17:31:46 -0600358/* TODO: Port to new type safety */
359#if 0
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600360// Check object status for selected flag state
Courtney Goeltzenleuchtercd2a0992015-07-09 11:44:38 -0600361static VkBool32
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600362validate_status(
363 VkObject dispatchable_object,
364 VkObject vkObj,
365 VkObjectType objType,
366 ObjectStatusFlags status_mask,
367 ObjectStatusFlags status_flag,
368 VkFlags msg_flags,
369 OBJECT_TRACK_ERROR error_code,
370 const char *fail_msg)
371{
372 if (objMap.find(vkObj) != objMap.end()) {
373 OBJTRACK_NODE* pNode = objMap[vkObj];
374 if ((pNode->status & status_mask) != status_flag) {
375 char str[1024];
376 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
377 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600378 reinterpret_cast<uint64_t>(vkObj), fail_msg);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600379 return VK_FALSE;
380 }
381 return VK_TRUE;
382 }
383 else {
384 // If we do not find it print an error
385 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
386 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600387 reinterpret_cast<uint64_t>(vkObj), string_VkObjectType(objType));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600388 return VK_FALSE;
389 }
390}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600391#endif
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600392
393#include "vk_dispatch_table_helper.h"
394static void
395initObjectTracker(
396 layer_data *my_data)
397{
398 uint32_t report_flags = 0;
399 uint32_t debug_action = 0;
400 FILE *log_output = NULL;
401 const char *option_str;
402 // initialize ObjectTracker options
403 report_flags = getLayerOptionFlags("ObjectTrackerReportFlags", 0);
404 getLayerOptionEnum("ObjectTrackerDebugAction", (uint32_t *) &debug_action);
405
406 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
407 {
408 option_str = getLayerOption("ObjectTrackerLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600409 log_output = getLayerLogOutput(option_str, "ObjectTracker");
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700410 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 -0600411 }
412
413 if (!objLockInitialized)
414 {
415 // TODO/TBD: Need to delete this mutex sometime. How??? One
416 // suggestion is to call this during vkCreateInstance(), and then we
417 // can clean it up during vkDestroyInstance(). However, that requires
418 // that the layer have per-instance locks. We need to come back and
419 // address this soon.
420 loader_platform_thread_create_mutex(&objLock);
421 objLockInitialized = 1;
422 }
423}
424
Tony Barboura05dbaa2015-07-09 17:31:46 -0600425//
426// Forward declares of generated routines
427//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600428
Michael Lentine13803dc2015-11-04 14:35:12 -0800429static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDbgObjectType objType);
430static void create_instance(VkInstance dispatchable_object, VkInstance object, VkDbgObjectType objType);
431static void create_device(VkDevice dispatchable_object, VkDevice object, VkDbgObjectType objType);
Michael Lentine13803dc2015-11-04 14:35:12 -0800432static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectType objType);
433static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object);
434static VkBool32 validate_image(VkCommandBuffer dispatchable_object, VkImage object);
435static VkBool32 validate_command_buffer(VkQueue dispatchable_object, VkCommandBuffer object);
436static VkBool32 validate_descriptor_set(VkCommandBuffer dispatchable_object, VkDescriptorSet object);
437static VkBool32 validate_instance(VkInstance dispatchable_object, VkInstance object);
438static VkBool32 validate_device(VkDevice dispatchable_object, VkDevice object);
439static VkBool32 validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
440static VkBool32 validate_descriptor_set_layout(VkDevice dispatchable_object, VkDescriptorSetLayout object);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700441static VkBool32 validate_command_pool(VkDevice dispatchable_object, VkCommandPool object);
442static void destroy_command_pool(VkDevice dispatchable_object, VkCommandPool object);
443static void destroy_command_buffer(VkCommandBuffer dispatchable_object, VkCommandBuffer object);
444static void destroy_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
445static void destroy_descriptor_set(VkDevice dispatchable_object, VkDescriptorSet object);
Michael Lentine13803dc2015-11-04 14:35:12 -0800446static void destroy_instance(VkInstance dispatchable_object, VkInstance object);
447static void destroy_device_memory(VkDevice dispatchable_object, VkDeviceMemory object);
Michael Lentine13803dc2015-11-04 14:35:12 -0800448static VkBool32 set_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
449static VkBool32 reset_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600450#if 0
451static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDbgObjectType objType,
452 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
453 const char *fail_msg);
454#endif
Michael Lentine13803dc2015-11-04 14:35:12 -0800455extern unordered_map<uint64_t, OBJTRACK_NODE*> VkPhysicalDeviceMap;
456extern unordered_map<uint64_t, OBJTRACK_NODE*> VkImageMap;
457extern unordered_map<uint64_t, OBJTRACK_NODE*> VkQueueMap;
458extern unordered_map<uint64_t, OBJTRACK_NODE*> VkDescriptorSetMap;
459extern unordered_map<uint64_t, OBJTRACK_NODE*> VkBufferMap;
460extern unordered_map<uint64_t, OBJTRACK_NODE*> VkFenceMap;
461extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSemaphoreMap;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700462extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandPoolMap;
Michael Lentine13803dc2015-11-04 14:35:12 -0800463extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandBufferMap;
464extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSwapchainKHRMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600465
Michael Lentine13803dc2015-11-04 14:35:12 -0800466static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600467{
Michael Lentine13803dc2015-11-04 14:35:12 -0800468 if ((VkImageMap.find(reinterpret_cast<uint64_t>(object)) == VkImageMap.end()) &&
469 (swapchainImageMap.find(reinterpret_cast<uint64_t>(object)) == swapchainImageMap.end())) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800470 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 -0800471 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600472 }
473 return VK_FALSE;
474}
475
Michael Lentine13803dc2015-11-04 14:35:12 -0800476static VkBool32 validate_image(VkCommandBuffer dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600477{
Michael Lentine13803dc2015-11-04 14:35:12 -0800478 if ((VkImageMap.find(reinterpret_cast<uint64_t>(object)) == VkImageMap.end()) &&
479 (swapchainImageMap.find(reinterpret_cast<uint64_t>(object)) == swapchainImageMap.end())) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800480 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 -0800481 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600482 }
483 return VK_FALSE;
484}
485
Michael Lentine13803dc2015-11-04 14:35:12 -0800486static VkBool32 validate_command_buffer(VkQueue dispatchable_object, VkCommandBuffer object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600487{
Michael Lentine13803dc2015-11-04 14:35:12 -0800488 if (VkCommandBufferMap.find(reinterpret_cast<uint64_t>(object)) == VkCommandBufferMap.end()) {
Tobin Ehlisec598302015-09-15 15:02:17 -0600489 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 -0800490 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600491 }
492 return VK_FALSE;
493}
494
Michael Lentine13803dc2015-11-04 14:35:12 -0800495static VkBool32 validate_descriptor_set(VkCommandBuffer dispatchable_object, VkDescriptorSet object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600496{
Michael Lentine13803dc2015-11-04 14:35:12 -0800497 if (VkDescriptorSetMap.find(reinterpret_cast<uint64_t>(object)) == VkDescriptorSetMap.end()) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800498 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 -0800499 "Invalid VkDescriptorSet Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600500 }
501 return VK_FALSE;
502}
503
Michael Lentine13803dc2015-11-04 14:35:12 -0800504static VkBool32 validate_buffer(VkQueue dispatchable_object, VkBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600505{
Michael Lentine13803dc2015-11-04 14:35:12 -0800506 if (VkBufferMap.find(reinterpret_cast<uint64_t>(object)) != VkBufferMap.end()) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800507 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 -0800508 "Invalid VkBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600509 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600510 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600511}
512
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600513static VkBool32 set_status(VkQueue dispatchable_object, VkFence object, VkDbgObjectType objType, ObjectStatusFlags status_flag)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600514{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600515 VkBool32 skipCall = VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600516 if (object != VK_NULL_HANDLE) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800517 if (VkFenceMap.find(reinterpret_cast<uint64_t>(object)) != VkFenceMap.end()) {
518 OBJTRACK_NODE* pNode = VkFenceMap[reinterpret_cast<uint64_t>(object)];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600519 pNode->status |= status_flag;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600520 }
521 else {
522 // If we do not find it print an error
Chia-I Wue2fc5522015-10-26 20:04:44 +0800523 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 -0600524 "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Michael Lentine13803dc2015-11-04 14:35:12 -0800525 reinterpret_cast<uint64_t>(object), string_VkDbgObjectType(objType));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600526 }
527 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600528 return skipCall;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600529}
530
Michael Lentine13803dc2015-11-04 14:35:12 -0800531static VkBool32 validate_semaphore(VkQueue dispatchable_object, VkSemaphore object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600532{
Michael Lentine13803dc2015-11-04 14:35:12 -0800533 if (VkSemaphoreMap.find(reinterpret_cast<uint64_t>(object)) == VkSemaphoreMap.end()) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800534 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 -0800535 "Invalid VkSemaphore Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600536 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600537 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600538}
539
Michael Lentine13803dc2015-11-04 14:35:12 -0800540static VkBool32 validate_command_buffer(VkDevice dispatchable_object, VkCommandBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600541{
Michael Lentine13803dc2015-11-04 14:35:12 -0800542 if (VkCommandBufferMap.find(reinterpret_cast<uint64_t>(object)) == VkCommandBufferMap.end()) {
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600543 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 -0800544 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600545 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600546 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600547}
548
Michael Lentine13803dc2015-11-04 14:35:12 -0800549static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDbgObjectType objType)
Tobin Ehlisec598302015-09-15 15:02:17 -0600550{
551 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
552 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
553 reinterpret_cast<uint64_t>(vkObj));
554
555 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
556 pNewObjNode->objType = objType;
557 pNewObjNode->status = OBJSTATUS_NONE;
558 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800559 VkPhysicalDeviceMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600560 uint32_t objIndex = objTypeToIndex(objType);
561 numObjs[objIndex]++;
562 numTotalObjs++;
563}
564
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700565static void create_surface_khr(VkInstance instance, VkSurfaceKHR surface, VkDbgObjectType objType)
566{
567 // TODO: Add tracking of surface objects
568}
569
570static void destroy_surface_khr(VkInstance instance, VkSurfaceKHR surface)
571{
572 // TODO: Add tracking of surface objects
573}
574
Michael Lentinefc6aa762015-11-20 12:11:42 -0800575static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer vkObj, VkDbgObjectType objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600576{
Michael Lentinefc6aa762015-11-20 12:11:42 -0800577 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 -0600578 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600579 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600580
581 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700582 pNewObjNode->objType = objType;
583 pNewObjNode->status = OBJSTATUS_NONE;
584 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
585 pNewObjNode->parentObj = (uint64_t) commandPool;
Michael Lentine13803dc2015-11-04 14:35:12 -0800586 VkCommandBufferMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600587 uint32_t objIndex = objTypeToIndex(objType);
588 numObjs[objIndex]++;
589 numTotalObjs++;
590}
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700591
Michael Lentinefc6aa762015-11-20 12:11:42 -0800592static void free_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700593{
594 uint64_t object_handle = reinterpret_cast<uint64_t>(commandBuffer);
595 if (VkCommandBufferMap.find(object_handle) != VkCommandBufferMap.end()) {
596 OBJTRACK_NODE* pNode = VkCommandBufferMap[(uint64_t)commandBuffer];
597
598 if (pNode->parentObj != reinterpret_cast<uint64_t>(commandPool)) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800599 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 -0700600 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
601 reinterpret_cast<uint64_t>(commandBuffer), pNode->parentObj, reinterpret_cast<uint64_t>(commandPool));
602 } else {
603
604 uint32_t objIndex = objTypeToIndex(pNode->objType);
605 assert(numTotalObjs > 0);
606 numTotalObjs--;
607 assert(numObjs[objIndex] > 0);
608 numObjs[objIndex]--;
Michael Lentinefc6aa762015-11-20 12:11:42 -0800609 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700610 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
611 string_VkDbgObjectType(pNode->objType), reinterpret_cast<uint64_t>(commandBuffer), numTotalObjs, numObjs[objIndex],
612 string_VkDbgObjectType(pNode->objType));
613 delete pNode;
614 VkCommandBufferMap.erase(object_handle);
615 }
616 } else {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800617 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700618 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
619 object_handle);
620 }
621}
622
Michael Lentinefc6aa762015-11-20 12:11:42 -0800623static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet vkObj, VkDbgObjectType objType)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700624{
Michael Lentinefc6aa762015-11-20 12:11:42 -0800625 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 -0700626 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
627 reinterpret_cast<uint64_t>(vkObj));
628
629 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
630 pNewObjNode->objType = objType;
631 pNewObjNode->status = OBJSTATUS_NONE;
632 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
633 pNewObjNode->parentObj = (uint64_t) descriptorPool;
634 VkDescriptorSetMap[(uint64_t)vkObj] = pNewObjNode;
635 uint32_t objIndex = objTypeToIndex(objType);
636 numObjs[objIndex]++;
637 numTotalObjs++;
638}
639
Michael Lentinefc6aa762015-11-20 12:11:42 -0800640static void free_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet descriptorSet)
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700641{
642 uint64_t object_handle = reinterpret_cast<uint64_t>(descriptorSet);
643 if (VkDescriptorSetMap.find(object_handle) != VkDescriptorSetMap.end()) {
644 OBJTRACK_NODE* pNode = VkDescriptorSetMap[(uint64_t)descriptorSet];
645
646 if (pNode->parentObj != reinterpret_cast<uint64_t>(descriptorPool)) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800647 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 -0700648 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
649 reinterpret_cast<uint64_t>(descriptorSet), pNode->parentObj, reinterpret_cast<uint64_t>(descriptorPool));
650 } else {
651 uint32_t objIndex = objTypeToIndex(pNode->objType);
652 assert(numTotalObjs > 0);
653 numTotalObjs--;
654 assert(numObjs[objIndex] > 0);
655 numObjs[objIndex]--;
Michael Lentinefc6aa762015-11-20 12:11:42 -0800656 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, pNode->objType, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700657 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
658 string_VkDbgObjectType(pNode->objType), reinterpret_cast<uint64_t>(descriptorSet), numTotalObjs, numObjs[objIndex],
659 string_VkDbgObjectType(pNode->objType));
660 delete pNode;
661 VkDescriptorSetMap.erase(object_handle);
662 }
663 } else {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800664 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object_handle, 0, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700665 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
666 object_handle);
667 }
668}
669
Michael Lentine13803dc2015-11-04 14:35:12 -0800670static void create_swapchain_khr(VkDevice dispatchable_object, VkSwapchainKHR vkObj, VkDbgObjectType objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600671{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800672 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 -0600673 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Michael Lentine13803dc2015-11-04 14:35:12 -0800674 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600675
676 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
677 pNewObjNode->objType = objType;
678 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800679 pNewObjNode->vkObj = (uint64_t) vkObj;
Michael Lentine13803dc2015-11-04 14:35:12 -0800680 VkSwapchainKHRMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600681 uint32_t objIndex = objTypeToIndex(objType);
682 numObjs[objIndex]++;
683 numTotalObjs++;
684}
Michael Lentine13803dc2015-11-04 14:35:12 -0800685static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectType objType)
Tobin Ehlisec598302015-09-15 15:02:17 -0600686{
687 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
688 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
689 reinterpret_cast<uint64_t>(vkObj));
690
691 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
692 pNewObjNode->objType = objType;
693 pNewObjNode->status = OBJSTATUS_NONE;
694 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800695 VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600696 uint32_t objIndex = objTypeToIndex(objType);
697 numObjs[objIndex]++;
698 numTotalObjs++;
699}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600700static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain)
701{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800702 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 -0600703 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, "SwapchainImage",
Michael Lentine13803dc2015-11-04 14:35:12 -0800704 reinterpret_cast<uint64_t>(vkObj));
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600705
706 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
707 pNewObjNode->objType = VK_OBJECT_TYPE_IMAGE;
708 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800709 pNewObjNode->vkObj = (uint64_t) vkObj;
710 pNewObjNode->parentObj = (uint64_t) swapchain;
Michael Lentine13803dc2015-11-04 14:35:12 -0800711 swapchainImageMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600712}
713
Michael Lentine13803dc2015-11-04 14:35:12 -0800714static void destroy_swapchain(VkDevice dispatchable_object, VkSwapchainKHR object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600715{
Michael Lentine13803dc2015-11-04 14:35:12 -0800716 if (VkSwapchainKHRMap.find(reinterpret_cast<uint64_t>(object)) != VkSwapchainKHRMap.end()) {
717 OBJTRACK_NODE* pNode = VkSwapchainKHRMap[reinterpret_cast<uint64_t>(object)];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600718 uint32_t objIndex = objTypeToIndex(pNode->objType);
719 assert(numTotalObjs > 0);
720 numTotalObjs--;
721 assert(numObjs[objIndex] > 0);
722 numObjs[objIndex]--;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800723 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 -0800724 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800725 string_VkDbgObjectType(pNode->objType), (uint64_t) object, numTotalObjs, numObjs[objIndex],
Tony Barboura05dbaa2015-07-09 17:31:46 -0600726 string_VkDbgObjectType(pNode->objType));
727 delete pNode;
Michael Lentine13803dc2015-11-04 14:35:12 -0800728 VkSwapchainKHRMap.erase(reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600729 } else {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800730 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 -0600731 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
Michael Lentine13803dc2015-11-04 14:35:12 -0800732 reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600733 }
734}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600735//
736// Non-auto-generated API functions called by generated code
737//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600738VkResult
739explicit_CreateInstance(
740 const VkInstanceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800741 const VkAllocationCallbacks * pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600742 VkInstance * pInstance)
743{
David Pinedoc0fa1ab2015-07-31 10:46:25 -0600744
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600745 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, *pInstance);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800746 VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600747
748 if (result == VK_SUCCESS) {
749 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
750 my_data->report_data = debug_report_create_instance(
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600751 pInstanceTable,
752 *pInstance,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800753 pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600754 pCreateInfo->ppEnabledExtensionNames);
Jon Ashburn3dc39382015-09-17 10:00:32 -0600755 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600756
757 initObjectTracker(my_data);
Michael Lentine13803dc2015-11-04 14:35:12 -0800758 create_instance(*pInstance, *pInstance, VK_OBJECT_TYPE_INSTANCE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600759 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600760 return result;
761}
762
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600763void
Cody Northropd0802882015-08-03 17:04:53 -0600764explicit_GetPhysicalDeviceQueueFamilyProperties(
Tony Barbour59a47322015-06-24 16:06:58 -0600765 VkPhysicalDevice gpu,
Cody Northropd0802882015-08-03 17:04:53 -0600766 uint32_t* pCount,
767 VkQueueFamilyProperties* pProperties)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600768{
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600769 get_dispatch_table(ObjectTracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600770
771 loader_platform_thread_lock_mutex(&objLock);
Cody Northropd0802882015-08-03 17:04:53 -0600772 if (pProperties != NULL)
773 setGpuQueueInfoState(*pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600774 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600775}
776
777VkResult
778explicit_CreateDevice(
779 VkPhysicalDevice gpu,
780 const VkDeviceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800781 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600782 VkDevice *pDevice)
783{
784 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600785// VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, gpu);
786 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800787 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600788 if (result == VK_SUCCESS) {
789 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
790 //// VkLayerDispatchTable *pTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
791 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
792 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Michael Lentine13803dc2015-11-04 14:35:12 -0800793 create_device(*pDevice, *pDevice, VK_OBJECT_TYPE_DEVICE);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600794 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600795 }
796
797 loader_platform_thread_unlock_mutex(&objLock);
798 return result;
799}
800
Tobin Ehlisec598302015-09-15 15:02:17 -0600801VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
802{
803 VkBool32 skipCall = VK_FALSE;
804 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800805 skipCall |= validate_instance(instance, instance);
Tobin Ehlisec598302015-09-15 15:02:17 -0600806 loader_platform_thread_unlock_mutex(&objLock);
807 if (skipCall)
808 return VK_ERROR_VALIDATION_FAILED;
809 VkResult result = get_dispatch_table(ObjectTracker_instance_table_map, instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
810 loader_platform_thread_lock_mutex(&objLock);
811 if (result == VK_SUCCESS) {
812 if (pPhysicalDevices) {
813 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800814 create_physical_device(instance, pPhysicalDevices[i], VK_OBJECT_TYPE_PHYSICAL_DEVICE);
Tobin Ehlisec598302015-09-15 15:02:17 -0600815 }
816 }
817 }
818 loader_platform_thread_unlock_mutex(&objLock);
819 return result;
820}
821
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600822void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600823explicit_GetDeviceQueue(
824 VkDevice device,
825 uint32_t queueNodeIndex,
826 uint32_t queueIndex,
827 VkQueue *pQueue)
828{
829 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800830 validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600831 loader_platform_thread_unlock_mutex(&objLock);
832
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600833 get_dispatch_table(ObjectTracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600834
835 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600836 addQueueInfo(queueNodeIndex, *pQueue);
Michael Lentine13803dc2015-11-04 14:35:12 -0800837 create_queue(device, *pQueue, VK_OBJECT_TYPE_QUEUE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600838 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600839}
840
841VkResult
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600842explicit_MapMemory(
843 VkDevice device,
844 VkDeviceMemory mem,
845 VkDeviceSize offset,
846 VkDeviceSize size,
847 VkFlags flags,
848 void **ppData)
849{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600850 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600851 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800852 skipCall |= set_device_memory_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
853 skipCall |= validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600854 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600855 if (skipCall == VK_TRUE)
856 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600857
858 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
859
860 return result;
861}
862
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600863void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600864explicit_UnmapMemory(
865 VkDevice device,
866 VkDeviceMemory mem)
867{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600868 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600869 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800870 skipCall |= reset_device_memory_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
871 skipCall |= validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600872 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600873 if (skipCall == VK_TRUE)
874 return;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600875
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600876 get_dispatch_table(ObjectTracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600877}
878
879VkResult
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800880explicit_QueueBindSparse(
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600881 VkQueue queue,
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800882 uint32_t bindInfoCount,
883 const VkBindSparseInfo* pBindInfo,
884 VkFence fence)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600885{
886 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800887 validateQueueFlags(queue, "QueueBindSparse");
888
889 for (uint32_t i = 0; i < bindInfoCount; i++) {
890 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800891 validate_buffer(queue, pBindInfo[i].pBufferBinds[j].buffer);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800892 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800893 validate_image(queue, pBindInfo[i].pImageOpaqueBinds[j].image);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800894 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
Michael Lentine13803dc2015-11-04 14:35:12 -0800895 validate_image(queue, pBindInfo[i].pImageBinds[j].image);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800896 }
897
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600898 loader_platform_thread_unlock_mutex(&objLock);
899
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800900 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600901 return result;
902}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600903
904VkResult
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700905explicit_AllocateCommandBuffers(
906 VkDevice device,
907 const VkCommandBufferAllocateInfo *pAllocateInfo,
908 VkCommandBuffer* pCommandBuffers)
909{
910 VkBool32 skipCall = VK_FALSE;
911 loader_platform_thread_lock_mutex(&objLock);
912 skipCall |= validate_device(device, device);
913 skipCall |= validate_command_pool(device, pAllocateInfo->commandPool);
914 loader_platform_thread_unlock_mutex(&objLock);
915
916 if (skipCall) {
917 return VK_ERROR_VALIDATION_FAILED;
918 }
919
920 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateCommandBuffers(
921 device, pAllocateInfo, pCommandBuffers);
922
923 loader_platform_thread_lock_mutex(&objLock);
924 for (uint32_t i = 0; i < pAllocateInfo->bufferCount; i++) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800925 alloc_command_buffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], VK_OBJECT_TYPE_COMMAND_BUFFER);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700926 }
927 loader_platform_thread_unlock_mutex(&objLock);
928
929 return result;
930}
931
932VkResult
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800933explicit_AllocateDescriptorSets(
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700934 VkDevice device,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800935 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700936 VkDescriptorSet *pDescriptorSets)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600937{
Tobin Ehlisec598302015-09-15 15:02:17 -0600938 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600939 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800940 skipCall |= validate_device(device, device);
941 skipCall |= validate_descriptor_pool(device, pAllocateInfo->descriptorPool);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800942 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Michael Lentine13803dc2015-11-04 14:35:12 -0800943 skipCall |= validate_descriptor_set_layout(device, pAllocateInfo->pSetLayouts[i]);
Tobin Ehlisec598302015-09-15 15:02:17 -0600944 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600945 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600946 if (skipCall)
947 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600948
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800949 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateDescriptorSets(
950 device, pAllocateInfo, pDescriptorSets);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600951
952 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800953 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800954 alloc_descriptor_set(device, pAllocateInfo->descriptorPool, pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600955 }
956 loader_platform_thread_unlock_mutex(&objLock);
957
958 return result;
959}
960
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700961void
962explicit_FreeCommandBuffers(
963 VkDevice device,
964 VkCommandPool commandPool,
965 uint32_t commandBufferCount,
966 const VkCommandBuffer *pCommandBuffers)
967{
968 loader_platform_thread_lock_mutex(&objLock);
969 validate_command_pool(device, commandPool);
970 validate_device(device, device);
971 loader_platform_thread_unlock_mutex(&objLock);
972
973 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeCommandBuffers(device,
974 commandPool, commandBufferCount, pCommandBuffers);
975
976 loader_platform_thread_lock_mutex(&objLock);
977 for (uint32_t i = 0; i < commandBufferCount; i++)
978 {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800979 free_command_buffer(device, commandPool, *pCommandBuffers);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700980 pCommandBuffers++;
981 }
982 loader_platform_thread_unlock_mutex(&objLock);
983}
984
Ian Elliott05846062015-11-20 14:13:17 -0700985void
Ian Elliott7e40db92015-08-21 15:09:33 -0600986explicit_DestroySwapchainKHR(
Ian Elliott05846062015-11-20 14:13:17 -0700987 VkDevice device,
988 VkSwapchainKHR swapchain,
989 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600990{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600991 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600992 // A swapchain's images are implicitly deleted when the swapchain is deleted.
993 // Remove this swapchain's images from our map of such images.
Michael Lentine13803dc2015-11-04 14:35:12 -0800994 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = swapchainImageMap.begin();
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600995 while (itr != swapchainImageMap.end()) {
996 OBJTRACK_NODE* pNode = (*itr).second;
Michael Lentine13803dc2015-11-04 14:35:12 -0800997 if (pNode->parentObj == reinterpret_cast<uint64_t>(swapchain)) {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600998 swapchainImageMap.erase(itr++);
999 } else {
1000 ++itr;
1001 }
1002 }
Michael Lentine13803dc2015-11-04 14:35:12 -08001003 destroy_swapchain(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001004 loader_platform_thread_unlock_mutex(&objLock);
1005
Ian Elliott05846062015-11-20 14:13:17 -07001006 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001007}
1008
Mark Lobodzinski2141f652015-09-07 13:59:43 -06001009void
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001010explicit_FreeMemory(
1011 VkDevice device,
Chia-I Wuf7458c52015-10-26 21:10:41 +08001012 VkDeviceMemory mem,
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001013 const VkAllocationCallbacks* pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001014{
1015 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001016 validate_device(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001017 loader_platform_thread_unlock_mutex(&objLock);
1018
Chia-I Wuf7458c52015-10-26 21:10:41 +08001019 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001020
1021 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001022 destroy_device_memory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001023 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -06001024}
Tony Barboura05dbaa2015-07-09 17:31:46 -06001025
Tony Barbour770f80d2015-07-20 10:52:13 -06001026VkResult
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001027explicit_FreeDescriptorSets(
1028 VkDevice device,
1029 VkDescriptorPool descriptorPool,
1030 uint32_t count,
1031 const VkDescriptorSet *pDescriptorSets)
Tony Barbour770f80d2015-07-20 10:52:13 -06001032{
1033 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001034 validate_descriptor_pool(device, descriptorPool);
1035 validate_device(device, device);
Tony Barbour770f80d2015-07-20 10:52:13 -06001036 loader_platform_thread_unlock_mutex(&objLock);
1037 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
1038
1039 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter7ebf1212015-07-23 11:25:17 -06001040 for (uint32_t i=0; i<count; i++)
Tony Barbour770f80d2015-07-20 10:52:13 -06001041 {
Michael Lentinefc6aa762015-11-20 12:11:42 -08001042 free_descriptor_set(device, descriptorPool, *pDescriptorSets++);
Tony Barbour770f80d2015-07-20 10:52:13 -06001043 }
1044 loader_platform_thread_unlock_mutex(&objLock);
1045 return result;
1046}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001047
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001048void
1049explicit_DestroyDescriptorPool(
1050 VkDevice device,
1051 VkDescriptorPool descriptorPool,
1052 const VkAllocationCallbacks *pAllocator)
1053{
1054 VkBool32 skipCall = VK_FALSE;
1055 loader_platform_thread_lock_mutex(&objLock);
1056 skipCall |= validate_device(device, device);
1057 skipCall |= validate_descriptor_pool(device, descriptorPool);
1058 loader_platform_thread_unlock_mutex(&objLock);
1059 if (skipCall) {
1060 return;
1061 }
1062 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
1063 // Remove this pool's descriptor sets from our descriptorSet map.
1064 loader_platform_thread_lock_mutex(&objLock);
1065 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkDescriptorSetMap.begin();
1066 while (itr != VkDescriptorSetMap.end()) {
1067 OBJTRACK_NODE* pNode = (*itr).second;
Mark Lobodzinskib29731a2015-11-18 11:01:02 -07001068 auto del_itr = itr++;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001069 if (pNode->parentObj == reinterpret_cast<uint64_t>(descriptorPool)) {
Mark Lobodzinskib29731a2015-11-18 11:01:02 -07001070 destroy_descriptor_set(device, reinterpret_cast<VkDescriptorSet>((*del_itr).first));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001071 }
1072 }
1073 destroy_descriptor_pool(device, descriptorPool);
1074 loader_platform_thread_unlock_mutex(&objLock);
1075 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
1076}
1077
1078void
1079explicit_DestroyCommandPool(
1080 VkDevice device,
1081 VkCommandPool commandPool,
1082 const VkAllocationCallbacks *pAllocator)
1083{
1084 VkBool32 skipCall = VK_FALSE;
1085 loader_platform_thread_lock_mutex(&objLock);
1086 skipCall |= validate_device(device, device);
1087 skipCall |= validate_command_pool(device, commandPool);
1088 loader_platform_thread_unlock_mutex(&objLock);
1089 if (skipCall) {
1090 return;
1091 }
1092 loader_platform_thread_lock_mutex(&objLock);
1093 // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
1094 // Remove this pool's cmdBuffers from our cmd buffer map.
1095 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkCommandBufferMap.begin();
1096 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator del_itr;
1097 while (itr != VkCommandBufferMap.end()) {
1098 OBJTRACK_NODE* pNode = (*itr).second;
1099 del_itr = itr++;
1100 if (pNode->parentObj == reinterpret_cast<uint64_t>(commandPool)) {
1101 destroy_command_buffer(reinterpret_cast<VkCommandBuffer>((*del_itr).first),
1102 reinterpret_cast<VkCommandBuffer>((*del_itr).first));
1103 }
1104 }
1105 destroy_command_pool(device, commandPool);
1106 loader_platform_thread_unlock_mutex(&objLock);
1107 get_dispatch_table(ObjectTracker_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
1108}
1109
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001110VkResult
1111explicit_GetSwapchainImagesKHR(
1112 VkDevice device,
1113 VkSwapchainKHR swapchain,
1114 uint32_t *pCount,
1115 VkImage *pSwapchainImages)
1116{
1117 VkBool32 skipCall = VK_FALSE;
1118 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -08001119 skipCall |= validate_device(device, device);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001120 loader_platform_thread_unlock_mutex(&objLock);
1121 if (skipCall)
1122 return VK_ERROR_VALIDATION_FAILED;
1123
1124 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
1125
1126 if (pSwapchainImages != NULL) {
1127 loader_platform_thread_lock_mutex(&objLock);
1128 for (uint32_t i = 0; i < *pCount; i++) {
1129 create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
1130 }
1131 loader_platform_thread_unlock_mutex(&objLock);
1132 }
1133 return result;
1134}
1135