blob: 824c255b9df812de60cab77604ec13d9e73e0321 [file] [log] [blame]
Tobin Ehlisacab8882014-11-14 13:01:02 -07001/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002 * Vulkan
Tobin Ehlisacab8882014-11-14 13:01:02 -07003 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
Tobin Ehlis2d1d9702015-07-03 09:42:57 -060025#include "vk_layer.h"
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -060026#include "vk_layer_extension_utils.h"
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060027#include "vk_enum_string_helper.h"
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060028
Tobin Ehlis3c26a542014-11-18 11:28:33 -070029// Object Tracker ERROR codes
30typedef enum _OBJECT_TRACK_ERROR
31{
Chia-I Wub1466182015-01-05 14:33:42 +080032 OBJTRACK_NONE, // Used for INFO & other non-error messages
33 OBJTRACK_UNKNOWN_OBJECT, // Updating uses of object that's not in global object list
34 OBJTRACK_INTERNAL_ERROR, // Bug with data tracking within the layer
35 OBJTRACK_DESTROY_OBJECT_FAILED, // Couldn't find object to be destroyed
Mark Lobodzinski7a3d5ff2015-05-05 18:24:45 -050036 OBJTRACK_OBJECT_TYPE_MISMATCH, // Object did not match corresponding Object Type
Chia-I Wub1466182015-01-05 14:33:42 +080037 OBJTRACK_OBJECT_LEAK, // OBJECT was not correctly freed/destroyed
38 OBJTRACK_OBJCOUNT_MAX_EXCEEDED, // Request for Object data in excess of max obj count
Tobin Ehlis235c20e2015-01-16 08:56:30 -070039 OBJTRACK_INVALID_FENCE, // Requested status of unsubmitted fence object
Tobin Ehlis586aa012015-06-08 17:36:28 -060040 OBJTRACK_INVALID_OBJECT, // Object used that has never been created
Tobin Ehlis3c26a542014-11-18 11:28:33 -070041} OBJECT_TRACK_ERROR;
42
Tobin Ehlis235c20e2015-01-16 08:56:30 -070043// Object Status -- used to track state of individual objects
Mark Lobodzinski7d2d5ac2015-05-20 17:33:47 -050044typedef VkFlags ObjectStatusFlags;
45typedef enum _ObjectStatusFlagBits
Tobin Ehlis235c20e2015-01-16 08:56:30 -070046{
Mark Lobodzinski01552702015-02-03 10:06:31 -060047 OBJSTATUS_NONE = 0x00000000, // No status is set
48 OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted
49 OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound
50 OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound
51 OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound
52 OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound
Mark Lobodzinski4186e712015-02-03 11:52:26 -060053 OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped
Mark Lobodzinski7d2d5ac2015-05-20 17:33:47 -050054} ObjectStatusFlagBits;
Chia-I Wu5b66aa52015-04-16 22:02:10 +080055
Tobin Ehlisacab8882014-11-14 13:01:02 -070056typedef struct _OBJTRACK_NODE {
Tony Barbour2a199c12015-07-09 17:31:46 -060057 uint64_t vkObj;
58 VkDbgObjectType objType;
59 ObjectStatusFlags status;
Tobin Ehlisacab8882014-11-14 13:01:02 -070060} OBJTRACK_NODE;
Mark Lobodzinskie1d3f0c2015-02-09 10:20:53 -060061
Tobin Ehlisacab8882014-11-14 13:01:02 -070062// prototype for extension functions
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060063uint64_t objTrackGetObjectCount(VkDevice device);
Tony Barbour2a199c12015-07-09 17:31:46 -060064uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDbgObjectType type);
Mark Lobodzinskie1d3f0c2015-02-09 10:20:53 -060065
Tobin Ehlis3c26a542014-11-18 11:28:33 -070066// Func ptr typedefs
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060067typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
Tony Barbour2a199c12015-07-09 17:31:46 -060068typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDbgObjectType);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060069
70typedef struct _layer_data {
71 debug_report_data *report_data;
72 //TODO: put instance data here
73 VkDbgMsgCallback logging_callback;
Ian Elliottb134e842015-07-06 14:31:32 -060074 bool wsi_enabled;
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -060075 bool objtrack_extensions_enabled;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060076} layer_data;
77
78static std::unordered_map<void*, layer_data *> layer_data_map;
79static device_table_map ObjectTracker_device_table_map;
80static instance_table_map ObjectTracker_instance_table_map;
81
82static long long unsigned int object_track_index = 0;
83static int objLockInitialized = 0;
84static loader_platform_thread_mutex objLock;
85
86// Objects stored in a global map w/ struct containing basic info
Tony Barbour2a199c12015-07-09 17:31:46 -060087// unordered_map<const void*, OBJTRACK_NODE*> objMap;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060088
Tony Barbour2a199c12015-07-09 17:31:46 -060089#define NUM_OBJECT_TYPES VK_OBJECT_TYPE_NUM
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060090
91static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
92static uint64_t numTotalObjs = 0;
93static VkPhysicalDeviceQueueProperties *queueInfo = NULL;
94static uint32_t queueCount = 0;
95
96template layer_data *get_my_data_ptr<layer_data>(
97 void *data_key, std::unordered_map<void *, layer_data *> &data_map);
98
99//
100// Internal Object Tracker Functions
101//
102
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600103static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
104{
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600105 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliottb134e842015-07-06 14:31:32 -0600106 my_device_data->wsi_enabled = false;
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600107 for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) {
Ian Elliottb134e842015-07-06 14:31:32 -0600108 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_WSI_SWAPCHAIN_EXTENSION_NAME) == 0)
109 my_device_data->wsi_enabled = true;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600110
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600111 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0)
112 my_device_data->objtrack_extensions_enabled = true;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600113 }
114}
115
116// Indicate device or instance dispatch table type
117typedef enum _DispTableType
118{
119 DISP_TBL_TYPE_INSTANCE,
120 DISP_TBL_TYPE_DEVICE,
121} DispTableType;
122
Tony Barbour2a199c12015-07-09 17:31:46 -0600123debug_report_data *mdd(const void* object)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600124{
125 dispatch_key key = get_dispatch_key(object);
126 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600127 return my_data->report_data;
128}
129
130debug_report_data *mid(VkInstance object)
131{
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600132 dispatch_key key = get_dispatch_key(object);
133 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600134 return my_data->report_data;
135}
136
137// For each Queue's doubly linked-list of mem refs
138typedef struct _OT_MEM_INFO {
139 VkDeviceMemory mem;
140 struct _OT_MEM_INFO *pNextMI;
141 struct _OT_MEM_INFO *pPrevMI;
142
143} OT_MEM_INFO;
144
145// Track Queue information
146typedef struct _OT_QUEUE_INFO {
147 OT_MEM_INFO *pMemRefList;
148 struct _OT_QUEUE_INFO *pNextQI;
149 uint32_t queueNodeIndex;
150 VkQueue queue;
151 uint32_t refCount;
152} OT_QUEUE_INFO;
153
154// Global list of QueueInfo structures, one per queue
155static OT_QUEUE_INFO *g_pQueueInfo = NULL;
156
157// Convert an object type enum to an object type array index
158static uint32_t
159objTypeToIndex(
160 uint32_t objType)
161{
162 uint32_t index = objType;
163 if (objType > VK_OBJECT_TYPE_END_RANGE) {
Ian Elliottb134e842015-07-06 14:31:32 -0600164 // These come from vk_wsi_swapchain.h, rebase
165 index = (index -(VK_WSI_DEVICE_SWAPCHAIN_EXTENSION_NUMBER * -1000)) + VK_OBJECT_TYPE_END_RANGE;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600166 }
167 return index;
168}
169
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600170// Add new queue to head of global queue list
171static void
172addQueueInfo(
173 uint32_t queueNodeIndex,
174 VkQueue queue)
175{
176 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
177
178 if (pQueueInfo != NULL) {
179 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
180 pQueueInfo->queue = queue;
181 pQueueInfo->queueNodeIndex = queueNodeIndex;
182 pQueueInfo->pNextQI = g_pQueueInfo;
183 g_pQueueInfo = pQueueInfo;
184 }
185 else {
Tony Barbour2a199c12015-07-09 17:31:46 -0600186 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<VkUintPtrLeast64>(queue), 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK",
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600187 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
188 }
189}
190
191// Destroy memRef lists and free all memory
192static void
193destroyQueueMemRefLists(void)
194{
195 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
196 OT_QUEUE_INFO *pDelQueueInfo = NULL;
197 while (pQueueInfo != NULL) {
198 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
199 while (pMemInfo != NULL) {
200 OT_MEM_INFO *pDelMemInfo = pMemInfo;
201 pMemInfo = pMemInfo->pNextMI;
202 delete pDelMemInfo;
203 }
204 pDelQueueInfo = pQueueInfo;
205 pQueueInfo = pQueueInfo->pNextQI;
206 delete pDelQueueInfo;
207 }
208 g_pQueueInfo = pQueueInfo;
209}
210
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600211static void
212setGpuQueueInfoState(
Tony Barbour426b9052015-06-24 16:06:58 -0600213 uint32_t count,
214 void *pData)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600215{
Tony Barbour426b9052015-06-24 16:06:58 -0600216 queueCount = count;
217 queueInfo = (VkPhysicalDeviceQueueProperties*)realloc((void*)queueInfo, count * sizeof(VkPhysicalDeviceQueueProperties));
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600218 if (queueInfo != NULL) {
Tony Barbour426b9052015-06-24 16:06:58 -0600219 memcpy(queueInfo, pData, count * sizeof(VkPhysicalDeviceQueueProperties));
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600220 }
221}
222
223// Check Queue type flags for selected queue operations
224static void
225validateQueueFlags(
226 VkQueue queue,
227 const char *function)
228{
229 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
230 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
231 pQueueInfo = pQueueInfo->pNextQI;
232 }
233 if (pQueueInfo != NULL) {
234 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_MEMMGR_BIT) == 0) {
Tony Barbour2a199c12015-07-09 17:31:46 -0600235 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<VkUintPtrLeast64>(queue), 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600236 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not set", function);
237 } else {
Tony Barbour2a199c12015-07-09 17:31:46 -0600238 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<VkUintPtrLeast64>(queue), 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600239 "Attempting %s on a possibly non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not known", function);
240 }
241 }
242}
243
Tony Barbour2a199c12015-07-09 17:31:46 -0600244/* TODO: Port to new type safety */
245#if 0
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600246// Check object status for selected flag state
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600247static VkBool32
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600248validate_status(
249 VkObject dispatchable_object,
250 VkObject vkObj,
251 VkObjectType objType,
252 ObjectStatusFlags status_mask,
253 ObjectStatusFlags status_flag,
254 VkFlags msg_flags,
255 OBJECT_TRACK_ERROR error_code,
256 const char *fail_msg)
257{
258 if (objMap.find(vkObj) != objMap.end()) {
259 OBJTRACK_NODE* pNode = objMap[vkObj];
260 if ((pNode->status & status_mask) != status_flag) {
261 char str[1024];
262 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
263 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
264 reinterpret_cast<VkUintPtrLeast64>(vkObj), fail_msg);
265 return VK_FALSE;
266 }
267 return VK_TRUE;
268 }
269 else {
270 // If we do not find it print an error
271 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
272 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
273 reinterpret_cast<VkUintPtrLeast64>(vkObj), string_VkObjectType(objType));
274 return VK_FALSE;
275 }
276}
Tony Barbour2a199c12015-07-09 17:31:46 -0600277#endif
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600278
279#include "vk_dispatch_table_helper.h"
280static void
281initObjectTracker(
282 layer_data *my_data)
283{
284 uint32_t report_flags = 0;
285 uint32_t debug_action = 0;
286 FILE *log_output = NULL;
287 const char *option_str;
288 // initialize ObjectTracker options
289 report_flags = getLayerOptionFlags("ObjectTrackerReportFlags", 0);
290 getLayerOptionEnum("ObjectTrackerDebugAction", (uint32_t *) &debug_action);
291
292 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
293 {
294 option_str = getLayerOption("ObjectTrackerLogFilename");
295 if (option_str) {
296 log_output = fopen(option_str, "w");
297 }
298 if (log_output == NULL) {
299 log_output = stdout;
300 }
301
302 layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &my_data->logging_callback);
303 }
304
305 if (!objLockInitialized)
306 {
307 // TODO/TBD: Need to delete this mutex sometime. How??? One
308 // suggestion is to call this during vkCreateInstance(), and then we
309 // can clean it up during vkDestroyInstance(). However, that requires
310 // that the layer have per-instance locks. We need to come back and
311 // address this soon.
312 loader_platform_thread_create_mutex(&objLock);
313 objLockInitialized = 1;
314 }
315}
316
Tony Barbour2a199c12015-07-09 17:31:46 -0600317//
318// Forward declares of generated routines
319//
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600320
Tony Barbour2a199c12015-07-09 17:31:46 -0600321static void create_obj(VkInstance dispatchable_object, VkInstance object, VkDbgObjectType objType);
322static void create_obj(VkDevice dispatchable_object, VkDevice object, VkDbgObjectType objType);
323static void create_obj(VkDevice dispatchable_object, VkDescriptorSet object, VkDbgObjectType objType);
324static void validate_object(VkInstance dispatchable_object, VkInstance object);
325static void validate_object(VkDevice dispatchable_object, VkDevice object);
326static void validate_object(VkDevice dispatchable_object, VkDescriptorPool object);
327static void destroy_obj(VkInstance dispatchable_object, VkInstance object);
328static void destroy_obj(VkDevice dispatchable_object, VkDeviceMemory object);
Tony Barbour912e8152015-07-20 10:52:13 -0600329static void destroy_obj(VkDevice dispatchable_object, VkDescriptorSet object);
Tony Barbour2a199c12015-07-09 17:31:46 -0600330static void set_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
331static void reset_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
332#if 0
333static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDbgObjectType objType,
334 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
335 const char *fail_msg);
336#endif
337extern unordered_map<const void*, OBJTRACK_NODE*> VkBufferMap;
338extern unordered_map<const void*, OBJTRACK_NODE*> VkFenceMap;
339extern unordered_map<const void*, OBJTRACK_NODE*> VkSemaphoreMap;
340extern unordered_map<const void*, OBJTRACK_NODE*> VkCmdBufferMap;
341extern unordered_map<const void*, OBJTRACK_NODE*> VkSwapChainWSIMap;
342
343static void validate_object(VkQueue dispatchable_object, VkBuffer object)
344{
345 if (VkBufferMap.find((void*)object.handle) != VkBufferMap.end()) {
346 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object.handle, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Tony Barbour8db65372015-07-10 18:32:33 -0600347 "Invalid VkBuffer Object %p", object.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600348 }
349}
350
351static void set_status(VkQueue dispatchable_object, VkFence object, VkDbgObjectType objType, ObjectStatusFlags status_flag)
352{
353 if (object != VK_NULL_HANDLE) {
354 if (VkFenceMap.find((void*)object.handle) != VkFenceMap.end()) {
355 OBJTRACK_NODE* pNode = VkFenceMap[(void*)object.handle];
356 pNode->status |= status_flag;
357 return;
358 }
359 else {
360 // If we do not find it print an error
Tony Barbour8db65372015-07-10 18:32:33 -0600361 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object.handle, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barbour2a199c12015-07-09 17:31:46 -0600362 "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Tony Barbour8db65372015-07-10 18:32:33 -0600363 object.handle, string_VkDbgObjectType(objType));
Tony Barbour2a199c12015-07-09 17:31:46 -0600364 }
365 }
366}
367
368static void validate_object(VkQueue dispatchable_object, VkSemaphore object)
369{
370 if (VkSemaphoreMap.find((void*)object.handle) == VkSemaphoreMap.end()) {
371 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object.handle, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Tony Barbour8db65372015-07-10 18:32:33 -0600372 "Invalid VkSemaphore Object %p", object.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600373 }
374}
375
376static void validate_object(VkDevice dispatchable_object, VkCmdBuffer object)
377{
Tobin Ehlis33ce8fd2015-07-10 18:25:07 -0600378 if (VkCmdBufferMap.find(object) == VkCmdBufferMap.end()) {
Tony Barbour2a199c12015-07-09 17:31:46 -0600379 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, reinterpret_cast<VkUintPtrLeast64>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Tobin Ehlis33ce8fd2015-07-10 18:25:07 -0600380 "Invalid VkCmdBuffer Object %p",reinterpret_cast<VkUintPtrLeast64>(object));
Tony Barbour2a199c12015-07-09 17:31:46 -0600381 }
382}
383
384static void create_obj(VkDevice dispatchable_object, VkCmdBuffer vkObj, VkDbgObjectType objType)
385{
386 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<VkUintPtrLeast64>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
387 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
388 reinterpret_cast<VkUintPtrLeast64>(vkObj));
389
390 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
391 pNewObjNode->objType = objType;
392 pNewObjNode->status = OBJSTATUS_NONE;
393 pNewObjNode->vkObj = reinterpret_cast<VkUintPtrLeast64>(vkObj);
394 VkCmdBufferMap[vkObj] = pNewObjNode;
395 uint32_t objIndex = objTypeToIndex(objType);
396 numObjs[objIndex]++;
397 numTotalObjs++;
398}
399static void create_obj(VkDevice dispatchable_object, VkSwapChainWSI vkObj, VkDbgObjectType objType)
400{
Tony Barbour7910de72015-07-13 16:37:21 -0600401 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, vkObj.handle, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barbour2a199c12015-07-09 17:31:46 -0600402 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Tony Barbour7910de72015-07-13 16:37:21 -0600403 vkObj.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600404
405 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
406 pNewObjNode->objType = objType;
407 pNewObjNode->status = OBJSTATUS_NONE;
Tony Barbour7910de72015-07-13 16:37:21 -0600408 pNewObjNode->vkObj = vkObj.handle;
Ian Elliottb134e842015-07-06 14:31:32 -0600409 VkSwapChainWSIMap[(void*) vkObj.handle] = pNewObjNode;
Tony Barbour2a199c12015-07-09 17:31:46 -0600410 uint32_t objIndex = objTypeToIndex(objType);
411 numObjs[objIndex]++;
412 numTotalObjs++;
413}
Ian Elliottb134e842015-07-06 14:31:32 -0600414static void destroy_obj(VkDevice dispatchable_object, VkSwapChainWSI object)
Tony Barbour2a199c12015-07-09 17:31:46 -0600415{
Ian Elliottb134e842015-07-06 14:31:32 -0600416 if (VkSwapChainWSIMap.find((void*) object.handle) != VkSwapChainWSIMap.end()) {
417 OBJTRACK_NODE* pNode = VkSwapChainWSIMap[(void*) object.handle];
Tony Barbour2a199c12015-07-09 17:31:46 -0600418 uint32_t objIndex = objTypeToIndex(pNode->objType);
419 assert(numTotalObjs > 0);
420 numTotalObjs--;
421 assert(numObjs[objIndex] > 0);
422 numObjs[objIndex]--;
Tony Barbour7910de72015-07-13 16:37:21 -0600423 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, pNode->objType, object.handle, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barbour2a199c12015-07-09 17:31:46 -0600424 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%lu total objs remain & %lu %s objs).",
Tony Barbour7910de72015-07-13 16:37:21 -0600425 string_VkDbgObjectType(pNode->objType), object.handle, numTotalObjs, numObjs[objIndex],
Tony Barbour2a199c12015-07-09 17:31:46 -0600426 string_VkDbgObjectType(pNode->objType));
427 delete pNode;
Ian Elliottb134e842015-07-06 14:31:32 -0600428 VkSwapChainWSIMap.erase((void*) object.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600429 } else {
Tony Barbour7910de72015-07-13 16:37:21 -0600430 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, object.handle, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barbour2a199c12015-07-09 17:31:46 -0600431 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
Tony Barbour7910de72015-07-13 16:37:21 -0600432 object.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600433 }
434}
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600435//
436// Non-auto-generated API functions called by generated code
437//
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600438VkResult
439explicit_CreateInstance(
440 const VkInstanceCreateInfo *pCreateInfo,
441 VkInstance * pInstance)
442{
443 loader_platform_thread_lock_mutex(&objLock);
444 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, *pInstance);
445 VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pInstance);
446
447 if (result == VK_SUCCESS) {
448 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
449 my_data->report_data = debug_report_create_instance(
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600450 pInstanceTable,
451 *pInstance,
452 pCreateInfo->extensionCount,
453 pCreateInfo->ppEnabledExtensionNames);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600454
455 initObjectTracker(my_data);
Tobin Ehlis86b52ec2015-06-30 14:31:50 -0600456 create_obj(*pInstance, *pInstance, VK_OBJECT_TYPE_INSTANCE);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600457 }
458 loader_platform_thread_unlock_mutex(&objLock);
459 return result;
460}
461
462VkResult
Tony Barbour426b9052015-06-24 16:06:58 -0600463explicit_GetPhysicalDeviceQueueProperties(
464 VkPhysicalDevice gpu,
465 uint32_t count,
466 VkPhysicalDeviceQueueProperties* pProperties)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600467{
Tony Barbour426b9052015-06-24 16:06:58 -0600468 VkResult result = get_dispatch_table(ObjectTracker_instance_table_map, gpu)->GetPhysicalDeviceQueueProperties(gpu, count, pProperties);
469
470 loader_platform_thread_lock_mutex(&objLock);
471 setGpuQueueInfoState(count, pProperties);
472 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600473 return result;
474}
475
476VkResult
477explicit_CreateDevice(
478 VkPhysicalDevice gpu,
479 const VkDeviceCreateInfo *pCreateInfo,
480 VkDevice *pDevice)
481{
482 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600483// VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, gpu);
484 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
485 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pDevice);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600486 if (result == VK_SUCCESS) {
487 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
488 //// VkLayerDispatchTable *pTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
489 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
490 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600491 create_obj(*pDevice, *pDevice, VK_OBJECT_TYPE_DEVICE);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600492 }
493
494 loader_platform_thread_unlock_mutex(&objLock);
495 return result;
496}
497
498VkResult
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600499explicit_GetDeviceQueue(
500 VkDevice device,
501 uint32_t queueNodeIndex,
502 uint32_t queueIndex,
503 VkQueue *pQueue)
504{
505 loader_platform_thread_lock_mutex(&objLock);
506 validate_object(device, device);
507 loader_platform_thread_unlock_mutex(&objLock);
508
509 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
510
511 loader_platform_thread_lock_mutex(&objLock);
512 addQueueInfo(queueNodeIndex, *pQueue);
513 loader_platform_thread_unlock_mutex(&objLock);
514
515 return result;
516}
517
518VkResult
519explicit_QueueSubmit(
520 VkQueue queue,
521 uint32_t cmdBufferCount,
522 const VkCmdBuffer *pCmdBuffers,
523 VkFence fence)
524{
525 loader_platform_thread_lock_mutex(&objLock);
526 set_status(queue, fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED);
527 // TODO: Fix for updated memory reference mechanism
528 // validate_memory_mapping_status(pMemRefs, memRefCount);
529 // validate_mem_ref_count(memRefCount);
530 loader_platform_thread_unlock_mutex(&objLock);
531
532 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
533
534 return result;
535}
536
537VkResult
538explicit_MapMemory(
539 VkDevice device,
540 VkDeviceMemory mem,
541 VkDeviceSize offset,
542 VkDeviceSize size,
543 VkFlags flags,
544 void **ppData)
545{
546 loader_platform_thread_lock_mutex(&objLock);
547 set_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
548 validate_object(device, device);
549 loader_platform_thread_unlock_mutex(&objLock);
550
551 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
552
553 return result;
554}
555
556VkResult
557explicit_UnmapMemory(
558 VkDevice device,
559 VkDeviceMemory mem)
560{
561 loader_platform_thread_lock_mutex(&objLock);
562 reset_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
563 validate_object(device, device);
564 loader_platform_thread_unlock_mutex(&objLock);
565
566 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->UnmapMemory(device, mem);
567
568 return result;
569}
570
571VkResult
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600572explicit_QueueBindSparseBufferMemory(
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600573 VkQueue queue,
574 VkBuffer buffer,
575 uint32_t numBindings,
576 const VkSparseMemoryBindInfo* pBindInfo)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600577{
578 loader_platform_thread_lock_mutex(&objLock);
579 validateQueueFlags(queue, "QueueBindSparseBufferMemory");
580 validate_object(queue, buffer);
581 loader_platform_thread_unlock_mutex(&objLock);
582
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600583 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparseBufferMemory(queue, buffer, numBindings, pBindInfo);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600584 return result;
585}
586
587VkResult
588explicit_QueueBindSparseImageMemory(
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600589 VkQueue queue,
590 VkImage image,
591 uint32_t numBindings,
592 const VkSparseImageMemoryBindInfo* pBindInfo)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600593{
594 loader_platform_thread_lock_mutex(&objLock);
595 validateQueueFlags(queue, "QueueBindSparseImageMemory");
596 loader_platform_thread_unlock_mutex(&objLock);
597
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600598 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparseImageMemory(queue, image, numBindings, pBindInfo);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600599 return result;
600}
601
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600602VkResult
603explicit_QueueBindSparseImageOpaqueMemory(
604 VkQueue queue,
605 VkImage image,
606 uint32_t numBindings,
607 const VkSparseMemoryBindInfo* pBindInfo)
608{
609 loader_platform_thread_lock_mutex(&objLock);
610 validateQueueFlags(queue, "QueueBindSparseImageOpaqueMemory");
611 loader_platform_thread_unlock_mutex(&objLock);
612
613 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparseImageOpaqueMemory(queue, image, numBindings, pBindInfo);
614 return result;
615}
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600616
617VkResult
618explicit_GetFenceStatus(
619 VkDevice device,
620 VkFence fence)
621{
622 loader_platform_thread_lock_mutex(&objLock);
623 // Warn if submitted_flag is not set
Tony Barbour2a199c12015-07-09 17:31:46 -0600624#if 0
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600625 validate_status(device, fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED,
626 VK_DBG_REPORT_ERROR_BIT, OBJTRACK_INVALID_FENCE, "Status Requested for Unsubmitted Fence");
Tony Barbour2a199c12015-07-09 17:31:46 -0600627#endif
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600628 validate_object(device, device);
629 loader_platform_thread_unlock_mutex(&objLock);
630
631 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetFenceStatus(device, fence);
632
633 return result;
634}
635
636VkResult
637explicit_WaitForFences(
638 VkDevice device,
639 uint32_t fenceCount,
640 const VkFence *pFences,
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600641 VkBool32 waitAll,
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600642 uint64_t timeout)
643{
644 loader_platform_thread_lock_mutex(&objLock);
Tony Barbour2a199c12015-07-09 17:31:46 -0600645#if 0
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600646 // Warn if waiting on unsubmitted fence
647 for (uint32_t i = 0; i < fenceCount; i++) {
648 validate_status(device, pFences[i], VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED,
649 VK_DBG_REPORT_ERROR_BIT, OBJTRACK_INVALID_FENCE, "Waiting for Unsubmitted Fence");
650 }
Tony Barbour2a199c12015-07-09 17:31:46 -0600651#endif
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600652 validate_object(device, device);
653 loader_platform_thread_unlock_mutex(&objLock);
654
655 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
656
657 return result;
658}
659
660VkResult
661explicit_AllocDescriptorSets(
662 VkDevice device,
663 VkDescriptorPool descriptorPool,
664 VkDescriptorSetUsage setUsage,
665 uint32_t count,
666 const VkDescriptorSetLayout *pSetLayouts,
667 VkDescriptorSet *pDescriptorSets,
668 uint32_t *pCount)
669{
670 loader_platform_thread_lock_mutex(&objLock);
671 validate_object(device, device);
672 validate_object(device, descriptorPool);
673 loader_platform_thread_unlock_mutex(&objLock);
674
675 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocDescriptorSets(
676 device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
677
678 loader_platform_thread_lock_mutex(&objLock);
679 for (uint32_t i = 0; i < *pCount; i++) {
680 create_obj(device, pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);
681 }
682 loader_platform_thread_unlock_mutex(&objLock);
683
684 return result;
685}
686
687VkResult
688explicit_DestroySwapChainWSI(
Ian Elliottb134e842015-07-06 14:31:32 -0600689 VkDevice device,
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600690 VkSwapChainWSI swapChain)
691{
692
693 loader_platform_thread_lock_mutex(&objLock);
Ian Elliottb134e842015-07-06 14:31:32 -0600694 destroy_obj(device, swapChain);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600695 loader_platform_thread_unlock_mutex(&objLock);
696
Ian Elliottb134e842015-07-06 14:31:32 -0600697 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapChainWSI(device, swapChain);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600698
699 return result;
700}
701
702VkResult
703explicit_FreeMemory(
704 VkDevice device,
705 VkDeviceMemory mem)
706{
707 loader_platform_thread_lock_mutex(&objLock);
708 validate_object(device, device);
709 loader_platform_thread_unlock_mutex(&objLock);
710
711 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeMemory(device, mem);
712
713 loader_platform_thread_lock_mutex(&objLock);
714 destroy_obj(device, mem);
715 loader_platform_thread_unlock_mutex(&objLock);
716
717 return result;
718}
Tony Barbour2a199c12015-07-09 17:31:46 -0600719
Tony Barbour912e8152015-07-20 10:52:13 -0600720VkResult
721explicit_FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets)
722{
723 loader_platform_thread_lock_mutex(&objLock);
724 validate_object(device, descriptorPool);
725 validate_object(device, device);
726 loader_platform_thread_unlock_mutex(&objLock);
727 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
728
729 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter78fc0472015-07-23 11:25:17 -0600730 for (uint32_t i=0; i<count; i++)
Tony Barbour912e8152015-07-20 10:52:13 -0600731 {
732 destroy_obj(device, *pDescriptorSets++);
733 }
734 loader_platform_thread_unlock_mutex(&objLock);
735 return result;
736}