blob: c99a08f76823bb4a52e1c34e66cd090e273d86fa [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
Tobin Ehlis0c6f9ee2015-07-03 09:42:57 -060028#include "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
Tobin Ehlisca915872014-11-18 11:28:33 -070042} OBJECT_TRACK_ERROR;
43
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070044// Object Status -- used to track state of individual objects
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050045typedef VkFlags ObjectStatusFlags;
46typedef enum _ObjectStatusFlagBits
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070047{
Mark Lobodzinski40370872015-02-03 10:06:31 -060048 OBJSTATUS_NONE = 0x00000000, // No status is set
49 OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted
50 OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound
51 OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound
52 OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound
53 OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound
Mark Lobodzinski4988dea2015-02-03 11:52:26 -060054 OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050055} ObjectStatusFlagBits;
Chia-I Wuf8693382015-04-16 22:02:10 +080056
Tobin Ehlis42586532014-11-14 13:01:02 -070057typedef struct _OBJTRACK_NODE {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060058 uint64_t vkObj; // Object handle
59 VkDbgObjectType objType; // Object type identifier
60 ObjectStatusFlags status; // Object state
61 uint64_t parentObj; // Parent object
Tobin Ehlis42586532014-11-14 13:01:02 -070062} OBJTRACK_NODE;
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060063
Tobin Ehlis42586532014-11-14 13:01:02 -070064// prototype for extension functions
Mark Lobodzinskifae78852015-06-23 11:35:12 -060065uint64_t objTrackGetObjectCount(VkDevice device);
Tony Barboura05dbaa2015-07-09 17:31:46 -060066uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDbgObjectType type);
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060067
Tobin Ehlisca915872014-11-18 11:28:33 -070068// Func ptr typedefs
Mark Lobodzinskifae78852015-06-23 11:35:12 -060069typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
Tony Barboura05dbaa2015-07-09 17:31:46 -060070typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDbgObjectType);
Mark Lobodzinskifae78852015-06-23 11:35:12 -060071
Cody Northrop55443ef2015-09-28 15:09:32 -060072struct layer_data {
Mark Lobodzinskifae78852015-06-23 11:35:12 -060073 debug_report_data *report_data;
74 //TODO: put instance data here
75 VkDbgMsgCallback logging_callback;
Ian Elliott1064fe32015-07-06 14:31:32 -060076 bool wsi_enabled;
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060077 bool objtrack_extensions_enabled;
Cody Northrop55443ef2015-09-28 15:09:32 -060078
79 layer_data() :
80 report_data(nullptr),
81 logging_callback(nullptr),
82 wsi_enabled(false),
83 objtrack_extensions_enabled(false)
84 {};
85};
Mark Lobodzinskifae78852015-06-23 11:35:12 -060086
Jon Ashburn3dc39382015-09-17 10:00:32 -060087struct instExts {
88 bool wsi_enabled;
89};
90
91static std::unordered_map<void *, struct instExts> instanceExtMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -060092static std::unordered_map<void*, layer_data *> layer_data_map;
93static device_table_map ObjectTracker_device_table_map;
94static instance_table_map ObjectTracker_instance_table_map;
95
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060096// We need additionally validate image usage using a separate map
97// of swapchain-created images
98static unordered_map<const void*, OBJTRACK_NODE*> swapchainImageMap;
99
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600100static long long unsigned int object_track_index = 0;
101static int objLockInitialized = 0;
102static loader_platform_thread_mutex objLock;
103
104// Objects stored in a global map w/ struct containing basic info
Tony Barboura05dbaa2015-07-09 17:31:46 -0600105// unordered_map<const void*, OBJTRACK_NODE*> objMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600106
Tony Barboura05dbaa2015-07-09 17:31:46 -0600107#define NUM_OBJECT_TYPES VK_OBJECT_TYPE_NUM
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600108
109static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
110static uint64_t numTotalObjs = 0;
Cody Northropd0802882015-08-03 17:04:53 -0600111static VkQueueFamilyProperties *queueInfo = NULL;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600112static uint32_t queueCount = 0;
113
114template layer_data *get_my_data_ptr<layer_data>(
115 void *data_key, std::unordered_map<void *, layer_data *> &data_map);
116
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600117static inline const char* string_VkDbgObjectType(VkDbgObjectType input_value)
118{
119 switch ((VkDbgObjectType)input_value)
120 {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800121 case VK_OBJECT_TYPE_COMMAND_POOL:
122 return "VK_OBJECT_TYPE_COMMAND_POOL";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600123 case VK_OBJECT_TYPE_BUFFER:
124 return "VK_OBJECT_TYPE_BUFFER";
125 case VK_OBJECT_TYPE_BUFFER_VIEW:
126 return "VK_OBJECT_TYPE_BUFFER_VIEW";
127 case VK_OBJECT_TYPE_ATTACHMENT_VIEW:
128 return "VK_OBJECT_TYPE_ATTACHMENT_VIEW";
129 case VK_OBJECT_TYPE_COMMAND_BUFFER:
130 return "VK_OBJECT_TYPE_COMMAND_BUFFER";
131 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
132 return "VK_OBJECT_TYPE_DESCRIPTOR_POOL";
133 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
134 return "VK_OBJECT_TYPE_DESCRIPTOR_SET";
135 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
136 return "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT";
137 case VK_OBJECT_TYPE_DEVICE:
138 return "VK_OBJECT_TYPE_DEVICE";
139 case VK_OBJECT_TYPE_DEVICE_MEMORY:
140 return "VK_OBJECT_TYPE_DEVICE_MEMORY";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600141 case VK_OBJECT_TYPE_EVENT:
142 return "VK_OBJECT_TYPE_EVENT";
143 case VK_OBJECT_TYPE_FENCE:
144 return "VK_OBJECT_TYPE_FENCE";
145 case VK_OBJECT_TYPE_FRAMEBUFFER:
146 return "VK_OBJECT_TYPE_FRAMEBUFFER";
147 case VK_OBJECT_TYPE_IMAGE:
148 return "VK_OBJECT_TYPE_IMAGE";
149 case VK_OBJECT_TYPE_IMAGE_VIEW:
150 return "VK_OBJECT_TYPE_IMAGE_VIEW";
151 case VK_OBJECT_TYPE_INSTANCE:
152 return "VK_OBJECT_TYPE_INSTANCE";
153 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
154 return "VK_OBJECT_TYPE_PHYSICAL_DEVICE";
155 case VK_OBJECT_TYPE_PIPELINE:
156 return "VK_OBJECT_TYPE_PIPELINE";
157 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
158 return "VK_OBJECT_TYPE_PIPELINE_LAYOUT";
159 case VK_OBJECT_TYPE_PIPELINE_CACHE:
160 return "VK_OBJECT_TYPE_PIPELINE_CACHE";
161 case VK_OBJECT_TYPE_QUERY_POOL:
162 return "VK_OBJECT_TYPE_QUERY_POOL";
163 case VK_OBJECT_TYPE_QUEUE:
164 return "VK_OBJECT_TYPE_QUEUE";
165 case VK_OBJECT_TYPE_RENDER_PASS:
166 return "VK_OBJECT_TYPE_RENDER_PASS";
167 case VK_OBJECT_TYPE_SAMPLER:
168 return "VK_OBJECT_TYPE_SAMPLER";
169 case VK_OBJECT_TYPE_SEMAPHORE:
170 return "VK_OBJECT_TYPE_SEMAPHORE";
171 case VK_OBJECT_TYPE_SHADER:
172 return "VK_OBJECT_TYPE_SHADER";
173 case VK_OBJECT_TYPE_SHADER_MODULE:
174 return "VK_OBJECT_TYPE_SHADER_MODULE";
Ian Elliott7e40db92015-08-21 15:09:33 -0600175 case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
176 return "VK_OBJECT_TYPE_SWAPCHAIN_KHR";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600177 default:
178 return "Unhandled VkObjectType";
179 }
180}
181
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600182//
183// Internal Object Tracker Functions
184//
185
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600186static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
187{
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600188 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600189 VkLayerDispatchTable *pDisp = get_dispatch_table(ObjectTracker_device_table_map, device);
190 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
191 pDisp->GetSurfacePropertiesKHR = (PFN_vkGetSurfacePropertiesKHR) gpa(device, "vkGetSurfacePropertiesKHR");
192 pDisp->GetSurfaceFormatsKHR = (PFN_vkGetSurfaceFormatsKHR) gpa(device, "vkGetSurfaceFormatsKHR");
193 pDisp->GetSurfacePresentModesKHR = (PFN_vkGetSurfacePresentModesKHR) gpa(device, "vkGetSurfacePresentModesKHR");
194 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 Elliott42a42522015-09-15 12:14:41 -0600201 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_KHR_DEVICE_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");
215 instanceExtMap[pDisp].wsi_enabled = false;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800216 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Jon Ashburn3dc39382015-09-17 10:00:32 -0600217 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
218 instanceExtMap[pDisp].wsi_enabled = true;
219
220 }
221}
222
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600223// Indicate device or instance dispatch table type
224typedef enum _DispTableType
225{
226 DISP_TBL_TYPE_INSTANCE,
227 DISP_TBL_TYPE_DEVICE,
228} DispTableType;
229
Tony Barboura05dbaa2015-07-09 17:31:46 -0600230debug_report_data *mdd(const void* object)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600231{
232 dispatch_key key = get_dispatch_key(object);
233 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600234 return my_data->report_data;
235}
236
237debug_report_data *mid(VkInstance object)
238{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600239 dispatch_key key = get_dispatch_key(object);
240 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600241 return my_data->report_data;
242}
243
244// For each Queue's doubly linked-list of mem refs
245typedef struct _OT_MEM_INFO {
246 VkDeviceMemory mem;
247 struct _OT_MEM_INFO *pNextMI;
248 struct _OT_MEM_INFO *pPrevMI;
249
250} OT_MEM_INFO;
251
252// Track Queue information
253typedef struct _OT_QUEUE_INFO {
254 OT_MEM_INFO *pMemRefList;
255 struct _OT_QUEUE_INFO *pNextQI;
256 uint32_t queueNodeIndex;
257 VkQueue queue;
258 uint32_t refCount;
259} OT_QUEUE_INFO;
260
261// Global list of QueueInfo structures, one per queue
262static OT_QUEUE_INFO *g_pQueueInfo = NULL;
263
264// Convert an object type enum to an object type array index
265static uint32_t
266objTypeToIndex(
267 uint32_t objType)
268{
269 uint32_t index = objType;
270 if (objType > VK_OBJECT_TYPE_END_RANGE) {
Ian Elliott7e40db92015-08-21 15:09:33 -0600271 // These come from vk_ext_khr_swapchain.h, rebase
272 index = (index -(VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER * -1000)) + VK_OBJECT_TYPE_END_RANGE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600273 }
274 return index;
275}
276
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600277// Add new queue to head of global queue list
278static void
279addQueueInfo(
280 uint32_t queueNodeIndex,
281 VkQueue queue)
282{
283 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
284
285 if (pQueueInfo != NULL) {
286 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
287 pQueueInfo->queue = queue;
288 pQueueInfo->queueNodeIndex = queueNodeIndex;
289 pQueueInfo->pNextQI = g_pQueueInfo;
290 g_pQueueInfo = pQueueInfo;
291 }
292 else {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600293 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 -0600294 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
295 }
296}
297
298// Destroy memRef lists and free all memory
299static void
300destroyQueueMemRefLists(void)
301{
302 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
303 OT_QUEUE_INFO *pDelQueueInfo = NULL;
304 while (pQueueInfo != NULL) {
305 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
306 while (pMemInfo != NULL) {
307 OT_MEM_INFO *pDelMemInfo = pMemInfo;
308 pMemInfo = pMemInfo->pNextMI;
309 delete pDelMemInfo;
310 }
311 pDelQueueInfo = pQueueInfo;
312 pQueueInfo = pQueueInfo->pNextQI;
313 delete pDelQueueInfo;
314 }
315 g_pQueueInfo = pQueueInfo;
316}
317
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600318static void
319setGpuQueueInfoState(
Tony Barbour59a47322015-06-24 16:06:58 -0600320 uint32_t count,
321 void *pData)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600322{
Tony Barbour59a47322015-06-24 16:06:58 -0600323 queueCount = count;
Cody Northropd0802882015-08-03 17:04:53 -0600324 queueInfo = (VkQueueFamilyProperties*)realloc((void*)queueInfo, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600325 if (queueInfo != NULL) {
Cody Northropd0802882015-08-03 17:04:53 -0600326 memcpy(queueInfo, pData, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600327 }
328}
329
330// Check Queue type flags for selected queue operations
331static void
332validateQueueFlags(
333 VkQueue queue,
334 const char *function)
335{
336 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
337 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
338 pQueueInfo = pQueueInfo->pNextQI;
339 }
340 if (pQueueInfo != NULL) {
Chia-I Wu2bfb33c2015-10-26 17:24:52 +0800341 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600342 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 +0800343 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600344 } else {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600345 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 +0800346 "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 -0600347 }
348 }
349}
350
Tony Barboura05dbaa2015-07-09 17:31:46 -0600351/* TODO: Port to new type safety */
352#if 0
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600353// Check object status for selected flag state
Courtney Goeltzenleuchtercd2a0992015-07-09 11:44:38 -0600354static VkBool32
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600355validate_status(
356 VkObject dispatchable_object,
357 VkObject vkObj,
358 VkObjectType objType,
359 ObjectStatusFlags status_mask,
360 ObjectStatusFlags status_flag,
361 VkFlags msg_flags,
362 OBJECT_TRACK_ERROR error_code,
363 const char *fail_msg)
364{
365 if (objMap.find(vkObj) != objMap.end()) {
366 OBJTRACK_NODE* pNode = objMap[vkObj];
367 if ((pNode->status & status_mask) != status_flag) {
368 char str[1024];
369 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
370 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600371 reinterpret_cast<uint64_t>(vkObj), fail_msg);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600372 return VK_FALSE;
373 }
374 return VK_TRUE;
375 }
376 else {
377 // If we do not find it print an error
378 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
379 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600380 reinterpret_cast<uint64_t>(vkObj), string_VkObjectType(objType));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600381 return VK_FALSE;
382 }
383}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600384#endif
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600385
386#include "vk_dispatch_table_helper.h"
387static void
388initObjectTracker(
389 layer_data *my_data)
390{
391 uint32_t report_flags = 0;
392 uint32_t debug_action = 0;
393 FILE *log_output = NULL;
394 const char *option_str;
395 // initialize ObjectTracker options
396 report_flags = getLayerOptionFlags("ObjectTrackerReportFlags", 0);
397 getLayerOptionEnum("ObjectTrackerDebugAction", (uint32_t *) &debug_action);
398
399 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
400 {
401 option_str = getLayerOption("ObjectTrackerLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600402 log_output = getLayerLogOutput(option_str, "ObjectTracker");
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600403 layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &my_data->logging_callback);
404 }
405
406 if (!objLockInitialized)
407 {
408 // TODO/TBD: Need to delete this mutex sometime. How??? One
409 // suggestion is to call this during vkCreateInstance(), and then we
410 // can clean it up during vkDestroyInstance(). However, that requires
411 // that the layer have per-instance locks. We need to come back and
412 // address this soon.
413 loader_platform_thread_create_mutex(&objLock);
414 objLockInitialized = 1;
415 }
416}
417
Tony Barboura05dbaa2015-07-09 17:31:46 -0600418//
419// Forward declares of generated routines
420//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600421
Tobin Ehlisec598302015-09-15 15:02:17 -0600422static void create_obj(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDbgObjectType objType);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600423static void create_obj(VkInstance dispatchable_object, VkInstance object, VkDbgObjectType objType);
424static void create_obj(VkDevice dispatchable_object, VkDevice object, VkDbgObjectType objType);
425static void create_obj(VkDevice dispatchable_object, VkDescriptorSet object, VkDbgObjectType objType);
Tobin Ehlisec598302015-09-15 15:02:17 -0600426static void create_obj(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectType objType);
427static VkBool32 validate_object(VkQueue dispatchable_object, VkImage object);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800428static VkBool32 validate_object(VkCommandBuffer dispatchable_object, VkImage object);
429static VkBool32 validate_object(VkQueue dispatchable_object, VkCommandBuffer object);
430static VkBool32 validate_object(VkCommandBuffer dispatchable_object, VkDescriptorSet object);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600431static VkBool32 validate_object(VkInstance dispatchable_object, VkInstance object);
432static VkBool32 validate_object(VkDevice dispatchable_object, VkDevice object);
433static VkBool32 validate_object(VkDevice dispatchable_object, VkDescriptorPool object);
Tobin Ehlisec598302015-09-15 15:02:17 -0600434static VkBool32 validate_object(VkDevice dispatchable_object, VkDescriptorSetLayout object);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600435static void destroy_obj(VkInstance dispatchable_object, VkInstance object);
436static void destroy_obj(VkDevice dispatchable_object, VkDeviceMemory object);
Tony Barbour770f80d2015-07-20 10:52:13 -0600437static void destroy_obj(VkDevice dispatchable_object, VkDescriptorSet object);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600438static VkBool32 set_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
439static VkBool32 reset_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600440#if 0
441static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDbgObjectType objType,
442 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
443 const char *fail_msg);
444#endif
Tobin Ehlisec598302015-09-15 15:02:17 -0600445extern unordered_map<const void*, OBJTRACK_NODE*> VkPhysicalDeviceMap;
446extern unordered_map<const void*, OBJTRACK_NODE*> VkImageMap;
447extern unordered_map<const void*, OBJTRACK_NODE*> VkQueueMap;
448extern unordered_map<const void*, OBJTRACK_NODE*> VkDescriptorSetMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600449extern unordered_map<const void*, OBJTRACK_NODE*> VkBufferMap;
450extern unordered_map<const void*, OBJTRACK_NODE*> VkFenceMap;
451extern unordered_map<const void*, OBJTRACK_NODE*> VkSemaphoreMap;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800452extern unordered_map<const void*, OBJTRACK_NODE*> VkCommandBufferMap;
Ian Elliott7e40db92015-08-21 15:09:33 -0600453extern unordered_map<const void*, OBJTRACK_NODE*> VkSwapchainKHRMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600454
Tobin Ehlisec598302015-09-15 15:02:17 -0600455static VkBool32 validate_object(VkQueue dispatchable_object, VkImage object)
456{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800457 if ((VkImageMap.find((void*)object) == VkImageMap.end()) &&
458 (swapchainImageMap.find((void*)object) == swapchainImageMap.end())) {
459 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 -0800460 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600461 }
462 return VK_FALSE;
463}
464
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800465static VkBool32 validate_object(VkCommandBuffer dispatchable_object, VkImage object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600466{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800467 if ((VkImageMap.find((void*)object) == VkImageMap.end()) &&
468 (swapchainImageMap.find((void*)object) == swapchainImageMap.end())) {
469 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 -0800470 "Invalid VkImage Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600471 }
472 return VK_FALSE;
473}
474
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800475static VkBool32 validate_object(VkQueue dispatchable_object, VkCommandBuffer object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600476{
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800477 if (VkCommandBufferMap.find(object) == VkCommandBufferMap.end()) {
Tobin Ehlisec598302015-09-15 15:02:17 -0600478 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 -0800479 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600480 }
481 return VK_FALSE;
482}
483
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800484static VkBool32 validate_object(VkCommandBuffer dispatchable_object, VkDescriptorSet object)
Tobin Ehlisec598302015-09-15 15:02:17 -0600485{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800486 if (VkDescriptorSetMap.find((void*)object) == VkDescriptorSetMap.end()) {
487 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 -0800488 "Invalid VkDescriptorSet Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tobin Ehlisec598302015-09-15 15:02:17 -0600489 }
490 return VK_FALSE;
491}
492
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600493static VkBool32 validate_object(VkQueue dispatchable_object, VkBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600494{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800495 if (VkBufferMap.find((void*)object) != VkBufferMap.end()) {
496 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 -0800497 "Invalid VkBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600498 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600499 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600500}
501
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600502static VkBool32 set_status(VkQueue dispatchable_object, VkFence object, VkDbgObjectType objType, ObjectStatusFlags status_flag)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600503{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600504 VkBool32 skipCall = VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600505 if (object != VK_NULL_HANDLE) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800506 if (VkFenceMap.find((void*)object) != VkFenceMap.end()) {
507 OBJTRACK_NODE* pNode = VkFenceMap[(void*)object];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600508 pNode->status |= status_flag;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600509 }
510 else {
511 // If we do not find it print an error
Chia-I Wue2fc5522015-10-26 20:04:44 +0800512 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 -0600513 "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800514 (uint64_t) object, string_VkDbgObjectType(objType));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600515 }
516 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600517 return skipCall;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600518}
519
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600520static VkBool32 validate_object(VkQueue dispatchable_object, VkSemaphore object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600521{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800522 if (VkSemaphoreMap.find((void*)object) == VkSemaphoreMap.end()) {
523 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 -0800524 "Invalid VkSemaphore Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600525 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600526 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600527}
528
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800529static VkBool32 validate_object(VkDevice dispatchable_object, VkCommandBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600530{
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800531 if (VkCommandBufferMap.find(object) == VkCommandBufferMap.end()) {
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600532 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 -0800533 "Invalid VkCommandBuffer Object %" PRIu64, reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600534 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600535 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600536}
537
Tobin Ehlisec598302015-09-15 15:02:17 -0600538static void create_obj(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDbgObjectType objType)
539{
540 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
541 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
542 reinterpret_cast<uint64_t>(vkObj));
543
544 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
545 pNewObjNode->objType = objType;
546 pNewObjNode->status = OBJSTATUS_NONE;
547 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
548 VkPhysicalDeviceMap[vkObj] = pNewObjNode;
549 uint32_t objIndex = objTypeToIndex(objType);
550 numObjs[objIndex]++;
551 numTotalObjs++;
552}
553
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800554static void create_obj(VkDevice dispatchable_object, VkCommandBuffer vkObj, VkDbgObjectType objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600555{
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600556 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barboura05dbaa2015-07-09 17:31:46 -0600557 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600558 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600559
560 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
561 pNewObjNode->objType = objType;
562 pNewObjNode->status = OBJSTATUS_NONE;
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600563 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800564 VkCommandBufferMap[vkObj] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600565 uint32_t objIndex = objTypeToIndex(objType);
566 numObjs[objIndex]++;
567 numTotalObjs++;
568}
Ian Elliott7e40db92015-08-21 15:09:33 -0600569static void create_obj(VkDevice dispatchable_object, VkSwapchainKHR vkObj, VkDbgObjectType objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600570{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800571 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 -0600572 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Chia-I Wue2fc5522015-10-26 20:04:44 +0800573 (uint64_t) vkObj);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600574
575 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
576 pNewObjNode->objType = objType;
577 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800578 pNewObjNode->vkObj = (uint64_t) vkObj;
579 VkSwapchainKHRMap[(void*) vkObj] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600580 uint32_t objIndex = objTypeToIndex(objType);
581 numObjs[objIndex]++;
582 numTotalObjs++;
583}
Tobin Ehlisec598302015-09-15 15:02:17 -0600584static void create_obj(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectType objType)
585{
586 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
587 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
588 reinterpret_cast<uint64_t>(vkObj));
589
590 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
591 pNewObjNode->objType = objType;
592 pNewObjNode->status = OBJSTATUS_NONE;
593 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
594 VkQueueMap[vkObj] = pNewObjNode;
595 uint32_t objIndex = objTypeToIndex(objType);
596 numObjs[objIndex]++;
597 numTotalObjs++;
598}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600599static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain)
600{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800601 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 -0600602 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, "SwapchainImage",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800603 (uint64_t) vkObj);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600604
605 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
606 pNewObjNode->objType = VK_OBJECT_TYPE_IMAGE;
607 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800608 pNewObjNode->vkObj = (uint64_t) vkObj;
609 pNewObjNode->parentObj = (uint64_t) swapchain;
610 swapchainImageMap[(void*)vkObj] = pNewObjNode;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600611}
612
Ian Elliott7e40db92015-08-21 15:09:33 -0600613static void destroy_obj(VkDevice dispatchable_object, VkSwapchainKHR object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600614{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800615 if (VkSwapchainKHRMap.find((void*) object) != VkSwapchainKHRMap.end()) {
616 OBJTRACK_NODE* pNode = VkSwapchainKHRMap[(void*) object];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600617 uint32_t objIndex = objTypeToIndex(pNode->objType);
618 assert(numTotalObjs > 0);
619 numTotalObjs--;
620 assert(numObjs[objIndex] > 0);
621 numObjs[objIndex]--;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800622 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 -0800623 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800624 string_VkDbgObjectType(pNode->objType), (uint64_t) object, numTotalObjs, numObjs[objIndex],
Tony Barboura05dbaa2015-07-09 17:31:46 -0600625 string_VkDbgObjectType(pNode->objType));
626 delete pNode;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800627 VkSwapchainKHRMap.erase((void*) object);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600628 } else {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800629 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 -0600630 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800631 (uint64_t) object);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600632 }
633}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600634//
635// Non-auto-generated API functions called by generated code
636//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600637VkResult
638explicit_CreateInstance(
639 const VkInstanceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800640 const VkAllocationCallbacks * pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600641 VkInstance * pInstance)
642{
David Pinedoc0fa1ab2015-07-31 10:46:25 -0600643
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600644 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, *pInstance);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800645 VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600646
647 if (result == VK_SUCCESS) {
648 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
649 my_data->report_data = debug_report_create_instance(
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600650 pInstanceTable,
651 *pInstance,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800652 pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600653 pCreateInfo->ppEnabledExtensionNames);
Jon Ashburn3dc39382015-09-17 10:00:32 -0600654 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600655
656 initObjectTracker(my_data);
Tobin Ehlis3e46c802015-06-30 14:31:50 -0600657 create_obj(*pInstance, *pInstance, VK_OBJECT_TYPE_INSTANCE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600658 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600659 return result;
660}
661
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600662void
Cody Northropd0802882015-08-03 17:04:53 -0600663explicit_GetPhysicalDeviceQueueFamilyProperties(
Tony Barbour59a47322015-06-24 16:06:58 -0600664 VkPhysicalDevice gpu,
Cody Northropd0802882015-08-03 17:04:53 -0600665 uint32_t* pCount,
666 VkQueueFamilyProperties* pProperties)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600667{
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600668 get_dispatch_table(ObjectTracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600669
670 loader_platform_thread_lock_mutex(&objLock);
Cody Northropd0802882015-08-03 17:04:53 -0600671 if (pProperties != NULL)
672 setGpuQueueInfoState(*pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600673 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600674}
675
676VkResult
677explicit_CreateDevice(
678 VkPhysicalDevice gpu,
679 const VkDeviceCreateInfo *pCreateInfo,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800680 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600681 VkDevice *pDevice)
682{
683 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600684// VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, gpu);
685 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800686 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600687 if (result == VK_SUCCESS) {
688 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
689 //// VkLayerDispatchTable *pTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
690 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
691 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600692 create_obj(*pDevice, *pDevice, VK_OBJECT_TYPE_DEVICE);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600693 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600694 }
695
696 loader_platform_thread_unlock_mutex(&objLock);
697 return result;
698}
699
Tobin Ehlisec598302015-09-15 15:02:17 -0600700VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
701{
702 VkBool32 skipCall = VK_FALSE;
703 loader_platform_thread_lock_mutex(&objLock);
704 skipCall |= validate_object(instance, instance);
705 loader_platform_thread_unlock_mutex(&objLock);
706 if (skipCall)
707 return VK_ERROR_VALIDATION_FAILED;
708 VkResult result = get_dispatch_table(ObjectTracker_instance_table_map, instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
709 loader_platform_thread_lock_mutex(&objLock);
710 if (result == VK_SUCCESS) {
711 if (pPhysicalDevices) {
712 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
713 create_obj(instance, pPhysicalDevices[i], VK_OBJECT_TYPE_PHYSICAL_DEVICE);
714 }
715 }
716 }
717 loader_platform_thread_unlock_mutex(&objLock);
718 return result;
719}
720
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600721void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600722explicit_GetDeviceQueue(
723 VkDevice device,
724 uint32_t queueNodeIndex,
725 uint32_t queueIndex,
726 VkQueue *pQueue)
727{
728 loader_platform_thread_lock_mutex(&objLock);
729 validate_object(device, device);
730 loader_platform_thread_unlock_mutex(&objLock);
731
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600732 get_dispatch_table(ObjectTracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600733
734 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600735 addQueueInfo(queueNodeIndex, *pQueue);
736 create_obj(device, *pQueue, VK_OBJECT_TYPE_QUEUE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600737 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600738}
739
740VkResult
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600741explicit_MapMemory(
742 VkDevice device,
743 VkDeviceMemory mem,
744 VkDeviceSize offset,
745 VkDeviceSize size,
746 VkFlags flags,
747 void **ppData)
748{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600749 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600750 loader_platform_thread_lock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600751 skipCall |= set_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
752 skipCall |= validate_object(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600753 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600754 if (skipCall == VK_TRUE)
755 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600756
757 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
758
759 return result;
760}
761
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600762void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600763explicit_UnmapMemory(
764 VkDevice device,
765 VkDeviceMemory mem)
766{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600767 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600768 loader_platform_thread_lock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600769 skipCall |= reset_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
770 skipCall |= validate_object(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600771 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600772 if (skipCall == VK_TRUE)
773 return;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600774
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600775 get_dispatch_table(ObjectTracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600776}
777
778VkResult
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800779explicit_QueueBindSparse(
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600780 VkQueue queue,
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800781 uint32_t bindInfoCount,
782 const VkBindSparseInfo* pBindInfo,
783 VkFence fence)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600784{
785 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800786 validateQueueFlags(queue, "QueueBindSparse");
787
788 for (uint32_t i = 0; i < bindInfoCount; i++) {
789 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
790 validate_object(queue, pBindInfo[i].pBufferBinds[j].buffer);
791 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
792 validate_object(queue, pBindInfo[i].pImageOpaqueBinds[j].image);
793 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
794 validate_object(queue, pBindInfo[i].pImageBinds[j].image);
795 }
796
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600797 loader_platform_thread_unlock_mutex(&objLock);
798
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800799 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600800 return result;
801}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600802
803VkResult
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800804explicit_AllocateDescriptorSets(
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600805 VkDevice device,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800806 const VkDescriptorSetAllocateInfo *pAllocateInfo,
Cody Northrop1e4f8022015-08-03 12:47:29 -0600807 VkDescriptorSet *pDescriptorSets)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600808{
Tobin Ehlisec598302015-09-15 15:02:17 -0600809 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600810 loader_platform_thread_lock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600811 skipCall |= validate_object(device, device);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800812 skipCall |= validate_object(device, pAllocateInfo->descriptorPool);
813 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
814 skipCall |= validate_object(device, pAllocateInfo->pSetLayouts[i]);
Tobin Ehlisec598302015-09-15 15:02:17 -0600815 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600816 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600817 if (skipCall)
818 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600819
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800820 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocateDescriptorSets(
821 device, pAllocateInfo, pDescriptorSets);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600822
823 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800824 for (uint32_t i = 0; i < pAllocateInfo->setLayoutCount; i++) {
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600825 create_obj(device, pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);
826 }
827 loader_platform_thread_unlock_mutex(&objLock);
828
829 return result;
830}
831
832VkResult
Ian Elliott7e40db92015-08-21 15:09:33 -0600833explicit_DestroySwapchainKHR(
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600834 VkDevice device,
Ian Elliott7e40db92015-08-21 15:09:33 -0600835 VkSwapchainKHR swapchain)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600836{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600837 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600838 // A swapchain's images are implicitly deleted when the swapchain is deleted.
839 // Remove this swapchain's images from our map of such images.
840 unordered_map<const void*, OBJTRACK_NODE*>::iterator itr = swapchainImageMap.begin();
841 while (itr != swapchainImageMap.end()) {
842 OBJTRACK_NODE* pNode = (*itr).second;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800843 if (pNode->parentObj == (uint64_t) swapchain) {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600844 swapchainImageMap.erase(itr++);
845 } else {
846 ++itr;
847 }
848 }
Ian Elliott7e40db92015-08-21 15:09:33 -0600849 destroy_obj(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600850 loader_platform_thread_unlock_mutex(&objLock);
851
Ian Elliott7e40db92015-08-21 15:09:33 -0600852 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600853 return result;
854}
855
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600856void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600857explicit_FreeMemory(
858 VkDevice device,
Chia-I Wuf7458c52015-10-26 21:10:41 +0800859 VkDeviceMemory mem,
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800860 const VkAllocationCallbacks* pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600861{
862 loader_platform_thread_lock_mutex(&objLock);
863 validate_object(device, device);
864 loader_platform_thread_unlock_mutex(&objLock);
865
Chia-I Wuf7458c52015-10-26 21:10:41 +0800866 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600867
868 loader_platform_thread_lock_mutex(&objLock);
869 destroy_obj(device, mem);
870 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600871}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600872
Tony Barbour770f80d2015-07-20 10:52:13 -0600873VkResult
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600874explicit_FreeDescriptorSets(
875 VkDevice device,
876 VkDescriptorPool descriptorPool,
877 uint32_t count,
878 const VkDescriptorSet *pDescriptorSets)
Tony Barbour770f80d2015-07-20 10:52:13 -0600879{
880 loader_platform_thread_lock_mutex(&objLock);
881 validate_object(device, descriptorPool);
882 validate_object(device, device);
883 loader_platform_thread_unlock_mutex(&objLock);
884 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
885
886 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter7ebf1212015-07-23 11:25:17 -0600887 for (uint32_t i=0; i<count; i++)
Tony Barbour770f80d2015-07-20 10:52:13 -0600888 {
889 destroy_obj(device, *pDescriptorSets++);
890 }
891 loader_platform_thread_unlock_mutex(&objLock);
892 return result;
893}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600894
895VkResult
896explicit_GetSwapchainImagesKHR(
897 VkDevice device,
898 VkSwapchainKHR swapchain,
899 uint32_t *pCount,
900 VkImage *pSwapchainImages)
901{
902 VkBool32 skipCall = VK_FALSE;
903 loader_platform_thread_lock_mutex(&objLock);
904 skipCall |= validate_object(device, device);
905 loader_platform_thread_unlock_mutex(&objLock);
906 if (skipCall)
907 return VK_ERROR_VALIDATION_FAILED;
908
909 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
910
911 if (pSwapchainImages != NULL) {
912 loader_platform_thread_lock_mutex(&objLock);
913 for (uint32_t i = 0; i < *pCount; i++) {
914 create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
915 }
916 loader_platform_thread_unlock_mutex(&objLock);
917 }
918 return result;
919}
920