blob: a1e4a44ea89188a604842f60b5462ba24a305bf4 [file] [log] [blame]
Tobin Ehlis42586532014-11-14 13:01:02 -07001/*
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002 * Vulkan
Tobin Ehlis42586532014-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 Ehlis0c6f9ee2015-07-03 09:42:57 -060025#include "vk_layer.h"
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060026#include "vk_layer_extension_utils.h"
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060027#include "vk_enum_string_helper.h"
Mark Lobodzinskifae78852015-06-23 11:35:12 -060028
Tobin Ehlisca915872014-11-18 11:28:33 -070029// Object Tracker ERROR codes
30typedef enum _OBJECT_TRACK_ERROR
31{
Chia-I Wu09cf5f02015-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
Chia-I Wu09cf5f02015-01-05 14:33:42 +080036 OBJTRACK_OBJECT_LEAK, // OBJECT was not correctly freed/destroyed
37 OBJTRACK_OBJCOUNT_MAX_EXCEEDED, // Request for Object data in excess of max obj count
Tobin Ehlis803cc492015-06-08 17:36:28 -060038 OBJTRACK_INVALID_OBJECT, // Object used that has never been created
Tobin Ehlisca915872014-11-18 11:28:33 -070039} OBJECT_TRACK_ERROR;
40
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070041// Object Status -- used to track state of individual objects
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050042typedef VkFlags ObjectStatusFlags;
43typedef enum _ObjectStatusFlagBits
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070044{
Mark Lobodzinski40370872015-02-03 10:06:31 -060045 OBJSTATUS_NONE = 0x00000000, // No status is set
46 OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted
47 OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound
48 OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound
49 OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound
50 OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound
Mark Lobodzinski4988dea2015-02-03 11:52:26 -060051 OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050052} ObjectStatusFlagBits;
Chia-I Wuf8693382015-04-16 22:02:10 +080053
Tobin Ehlis42586532014-11-14 13:01:02 -070054typedef struct _OBJTRACK_NODE {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060055 uint64_t vkObj; // Object handle
56 VkDbgObjectType objType; // Object type identifier
57 ObjectStatusFlags status; // Object state
58 uint64_t parentObj; // Parent object
Tobin Ehlis42586532014-11-14 13:01:02 -070059} OBJTRACK_NODE;
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060060
Tobin Ehlis42586532014-11-14 13:01:02 -070061// prototype for extension functions
Mark Lobodzinskifae78852015-06-23 11:35:12 -060062uint64_t objTrackGetObjectCount(VkDevice device);
Tony Barboura05dbaa2015-07-09 17:31:46 -060063uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDbgObjectType type);
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060064
Tobin Ehlisca915872014-11-18 11:28:33 -070065// Func ptr typedefs
Mark Lobodzinskifae78852015-06-23 11:35:12 -060066typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
Tony Barboura05dbaa2015-07-09 17:31:46 -060067typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDbgObjectType);
Mark Lobodzinskifae78852015-06-23 11:35:12 -060068
Cody Northrop55443ef2015-09-28 15:09:32 -060069struct layer_data {
Mark Lobodzinskifae78852015-06-23 11:35:12 -060070 debug_report_data *report_data;
71 //TODO: put instance data here
72 VkDbgMsgCallback logging_callback;
Ian Elliott1064fe32015-07-06 14:31:32 -060073 bool wsi_enabled;
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060074 bool objtrack_extensions_enabled;
Cody Northrop55443ef2015-09-28 15:09:32 -060075
76 layer_data() :
77 report_data(nullptr),
78 logging_callback(nullptr),
79 wsi_enabled(false),
80 objtrack_extensions_enabled(false)
81 {};
82};
Mark Lobodzinskifae78852015-06-23 11:35:12 -060083
Jon Ashburn3dc39382015-09-17 10:00:32 -060084struct instExts {
85 bool wsi_enabled;
86};
87
88static std::unordered_map<void *, struct instExts> instanceExtMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -060089static std::unordered_map<void*, layer_data *> layer_data_map;
90static device_table_map ObjectTracker_device_table_map;
91static instance_table_map ObjectTracker_instance_table_map;
92
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -060093// We need additionally validate image usage using a separate map
94// of swapchain-created images
95static unordered_map<const void*, OBJTRACK_NODE*> swapchainImageMap;
96
Mark Lobodzinskifae78852015-06-23 11:35:12 -060097static long long unsigned int object_track_index = 0;
98static int objLockInitialized = 0;
99static loader_platform_thread_mutex objLock;
100
101// Objects stored in a global map w/ struct containing basic info
Tony Barboura05dbaa2015-07-09 17:31:46 -0600102// unordered_map<const void*, OBJTRACK_NODE*> objMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600103
Tony Barboura05dbaa2015-07-09 17:31:46 -0600104#define NUM_OBJECT_TYPES VK_OBJECT_TYPE_NUM
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600105
106static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
107static uint64_t numTotalObjs = 0;
Cody Northropd0802882015-08-03 17:04:53 -0600108static VkQueueFamilyProperties *queueInfo = NULL;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600109static uint32_t queueCount = 0;
110
111template layer_data *get_my_data_ptr<layer_data>(
112 void *data_key, std::unordered_map<void *, layer_data *> &data_map);
113
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600114static inline const char* string_VkDbgObjectType(VkDbgObjectType input_value)
115{
116 switch ((VkDbgObjectType)input_value)
117 {
118 case VK_OBJECT_TYPE_CMD_POOL:
119 return "VK_OBJECT_TYPE_CMD_POOL";
120 case VK_OBJECT_TYPE_BUFFER:
121 return "VK_OBJECT_TYPE_BUFFER";
122 case VK_OBJECT_TYPE_BUFFER_VIEW:
123 return "VK_OBJECT_TYPE_BUFFER_VIEW";
124 case VK_OBJECT_TYPE_ATTACHMENT_VIEW:
125 return "VK_OBJECT_TYPE_ATTACHMENT_VIEW";
126 case VK_OBJECT_TYPE_COMMAND_BUFFER:
127 return "VK_OBJECT_TYPE_COMMAND_BUFFER";
128 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
129 return "VK_OBJECT_TYPE_DESCRIPTOR_POOL";
130 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
131 return "VK_OBJECT_TYPE_DESCRIPTOR_SET";
132 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
133 return "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT";
134 case VK_OBJECT_TYPE_DEVICE:
135 return "VK_OBJECT_TYPE_DEVICE";
136 case VK_OBJECT_TYPE_DEVICE_MEMORY:
137 return "VK_OBJECT_TYPE_DEVICE_MEMORY";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600138 case VK_OBJECT_TYPE_EVENT:
139 return "VK_OBJECT_TYPE_EVENT";
140 case VK_OBJECT_TYPE_FENCE:
141 return "VK_OBJECT_TYPE_FENCE";
142 case VK_OBJECT_TYPE_FRAMEBUFFER:
143 return "VK_OBJECT_TYPE_FRAMEBUFFER";
144 case VK_OBJECT_TYPE_IMAGE:
145 return "VK_OBJECT_TYPE_IMAGE";
146 case VK_OBJECT_TYPE_IMAGE_VIEW:
147 return "VK_OBJECT_TYPE_IMAGE_VIEW";
148 case VK_OBJECT_TYPE_INSTANCE:
149 return "VK_OBJECT_TYPE_INSTANCE";
150 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
151 return "VK_OBJECT_TYPE_PHYSICAL_DEVICE";
152 case VK_OBJECT_TYPE_PIPELINE:
153 return "VK_OBJECT_TYPE_PIPELINE";
154 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
155 return "VK_OBJECT_TYPE_PIPELINE_LAYOUT";
156 case VK_OBJECT_TYPE_PIPELINE_CACHE:
157 return "VK_OBJECT_TYPE_PIPELINE_CACHE";
158 case VK_OBJECT_TYPE_QUERY_POOL:
159 return "VK_OBJECT_TYPE_QUERY_POOL";
160 case VK_OBJECT_TYPE_QUEUE:
161 return "VK_OBJECT_TYPE_QUEUE";
162 case VK_OBJECT_TYPE_RENDER_PASS:
163 return "VK_OBJECT_TYPE_RENDER_PASS";
164 case VK_OBJECT_TYPE_SAMPLER:
165 return "VK_OBJECT_TYPE_SAMPLER";
166 case VK_OBJECT_TYPE_SEMAPHORE:
167 return "VK_OBJECT_TYPE_SEMAPHORE";
168 case VK_OBJECT_TYPE_SHADER:
169 return "VK_OBJECT_TYPE_SHADER";
170 case VK_OBJECT_TYPE_SHADER_MODULE:
171 return "VK_OBJECT_TYPE_SHADER_MODULE";
Ian Elliott7e40db92015-08-21 15:09:33 -0600172 case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
173 return "VK_OBJECT_TYPE_SWAPCHAIN_KHR";
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600174 default:
175 return "Unhandled VkObjectType";
176 }
177}
178
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600179//
180// Internal Object Tracker Functions
181//
182
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600183static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
184{
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600185 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600186 VkLayerDispatchTable *pDisp = get_dispatch_table(ObjectTracker_device_table_map, device);
187 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
188 pDisp->GetSurfacePropertiesKHR = (PFN_vkGetSurfacePropertiesKHR) gpa(device, "vkGetSurfacePropertiesKHR");
189 pDisp->GetSurfaceFormatsKHR = (PFN_vkGetSurfaceFormatsKHR) gpa(device, "vkGetSurfaceFormatsKHR");
190 pDisp->GetSurfacePresentModesKHR = (PFN_vkGetSurfacePresentModesKHR) gpa(device, "vkGetSurfacePresentModesKHR");
191 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
192 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
193 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
194 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
195 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
Ian Elliott1064fe32015-07-06 14:31:32 -0600196 my_device_data->wsi_enabled = false;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800197 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott42a42522015-09-15 12:14:41 -0600198 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliott1064fe32015-07-06 14:31:32 -0600199 my_device_data->wsi_enabled = true;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600200
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600201 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0)
202 my_device_data->objtrack_extensions_enabled = true;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600203 }
204}
205
Jon Ashburn3dc39382015-09-17 10:00:32 -0600206static void createInstanceRegisterExtensions(const VkInstanceCreateInfo* pCreateInfo, VkInstance instance)
207{
208 uint32_t i;
209 VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(ObjectTracker_instance_table_map, instance);
210 PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
211 pDisp->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
212 instanceExtMap[pDisp].wsi_enabled = false;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800213 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Jon Ashburn3dc39382015-09-17 10:00:32 -0600214 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
215 instanceExtMap[pDisp].wsi_enabled = true;
216
217 }
218}
219
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600220// Indicate device or instance dispatch table type
221typedef enum _DispTableType
222{
223 DISP_TBL_TYPE_INSTANCE,
224 DISP_TBL_TYPE_DEVICE,
225} DispTableType;
226
Tony Barboura05dbaa2015-07-09 17:31:46 -0600227debug_report_data *mdd(const void* object)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600228{
229 dispatch_key key = get_dispatch_key(object);
230 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600231 return my_data->report_data;
232}
233
234debug_report_data *mid(VkInstance object)
235{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600236 dispatch_key key = get_dispatch_key(object);
237 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600238 return my_data->report_data;
239}
240
241// For each Queue's doubly linked-list of mem refs
242typedef struct _OT_MEM_INFO {
243 VkDeviceMemory mem;
244 struct _OT_MEM_INFO *pNextMI;
245 struct _OT_MEM_INFO *pPrevMI;
246
247} OT_MEM_INFO;
248
249// Track Queue information
250typedef struct _OT_QUEUE_INFO {
251 OT_MEM_INFO *pMemRefList;
252 struct _OT_QUEUE_INFO *pNextQI;
253 uint32_t queueNodeIndex;
254 VkQueue queue;
255 uint32_t refCount;
256} OT_QUEUE_INFO;
257
258// Global list of QueueInfo structures, one per queue
259static OT_QUEUE_INFO *g_pQueueInfo = NULL;
260
261// Convert an object type enum to an object type array index
262static uint32_t
263objTypeToIndex(
264 uint32_t objType)
265{
266 uint32_t index = objType;
267 if (objType > VK_OBJECT_TYPE_END_RANGE) {
Ian Elliott7e40db92015-08-21 15:09:33 -0600268 // These come from vk_ext_khr_swapchain.h, rebase
269 index = (index -(VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER * -1000)) + VK_OBJECT_TYPE_END_RANGE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600270 }
271 return index;
272}
273
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600274// Add new queue to head of global queue list
275static void
276addQueueInfo(
277 uint32_t queueNodeIndex,
278 VkQueue queue)
279{
280 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
281
282 if (pQueueInfo != NULL) {
283 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
284 pQueueInfo->queue = queue;
285 pQueueInfo->queueNodeIndex = queueNodeIndex;
286 pQueueInfo->pNextQI = g_pQueueInfo;
287 g_pQueueInfo = pQueueInfo;
288 }
289 else {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600290 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 -0600291 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
292 }
293}
294
295// Destroy memRef lists and free all memory
296static void
297destroyQueueMemRefLists(void)
298{
299 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
300 OT_QUEUE_INFO *pDelQueueInfo = NULL;
301 while (pQueueInfo != NULL) {
302 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
303 while (pMemInfo != NULL) {
304 OT_MEM_INFO *pDelMemInfo = pMemInfo;
305 pMemInfo = pMemInfo->pNextMI;
306 delete pDelMemInfo;
307 }
308 pDelQueueInfo = pQueueInfo;
309 pQueueInfo = pQueueInfo->pNextQI;
310 delete pDelQueueInfo;
311 }
312 g_pQueueInfo = pQueueInfo;
313}
314
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600315static void
316setGpuQueueInfoState(
Tony Barbour59a47322015-06-24 16:06:58 -0600317 uint32_t count,
318 void *pData)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600319{
Tony Barbour59a47322015-06-24 16:06:58 -0600320 queueCount = count;
Cody Northropd0802882015-08-03 17:04:53 -0600321 queueInfo = (VkQueueFamilyProperties*)realloc((void*)queueInfo, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600322 if (queueInfo != NULL) {
Cody Northropd0802882015-08-03 17:04:53 -0600323 memcpy(queueInfo, pData, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600324 }
325}
326
327// Check Queue type flags for selected queue operations
328static void
329validateQueueFlags(
330 VkQueue queue,
331 const char *function)
332{
333 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
334 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
335 pQueueInfo = pQueueInfo->pNextQI;
336 }
337 if (pQueueInfo != NULL) {
338 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_MEMMGR_BIT) == 0) {
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600339 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<uint64_t>(queue), 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600340 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not set", function);
341 } else {
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",
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600343 "Attempting %s on a possibly non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not known", function);
344 }
345 }
346}
347
Tony Barboura05dbaa2015-07-09 17:31:46 -0600348/* TODO: Port to new type safety */
349#if 0
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600350// Check object status for selected flag state
Courtney Goeltzenleuchtercd2a0992015-07-09 11:44:38 -0600351static VkBool32
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600352validate_status(
353 VkObject dispatchable_object,
354 VkObject vkObj,
355 VkObjectType objType,
356 ObjectStatusFlags status_mask,
357 ObjectStatusFlags status_flag,
358 VkFlags msg_flags,
359 OBJECT_TRACK_ERROR error_code,
360 const char *fail_msg)
361{
362 if (objMap.find(vkObj) != objMap.end()) {
363 OBJTRACK_NODE* pNode = objMap[vkObj];
364 if ((pNode->status & status_mask) != status_flag) {
365 char str[1024];
366 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
367 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600368 reinterpret_cast<uint64_t>(vkObj), fail_msg);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600369 return VK_FALSE;
370 }
371 return VK_TRUE;
372 }
373 else {
374 // If we do not find it print an error
375 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
376 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600377 reinterpret_cast<uint64_t>(vkObj), string_VkObjectType(objType));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600378 return VK_FALSE;
379 }
380}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600381#endif
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600382
383#include "vk_dispatch_table_helper.h"
384static void
385initObjectTracker(
386 layer_data *my_data)
387{
388 uint32_t report_flags = 0;
389 uint32_t debug_action = 0;
390 FILE *log_output = NULL;
391 const char *option_str;
392 // initialize ObjectTracker options
393 report_flags = getLayerOptionFlags("ObjectTrackerReportFlags", 0);
394 getLayerOptionEnum("ObjectTrackerDebugAction", (uint32_t *) &debug_action);
395
396 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
397 {
398 option_str = getLayerOption("ObjectTrackerLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -0600399 log_output = getLayerLogOutput(option_str, "ObjectTracker");
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600400 layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &my_data->logging_callback);
401 }
402
403 if (!objLockInitialized)
404 {
405 // TODO/TBD: Need to delete this mutex sometime. How??? One
406 // suggestion is to call this during vkCreateInstance(), and then we
407 // can clean it up during vkDestroyInstance(). However, that requires
408 // that the layer have per-instance locks. We need to come back and
409 // address this soon.
410 loader_platform_thread_create_mutex(&objLock);
411 objLockInitialized = 1;
412 }
413}
414
Tony Barboura05dbaa2015-07-09 17:31:46 -0600415//
416// Forward declares of generated routines
417//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600418
Tobin Ehlisec598302015-09-15 15:02:17 -0600419static void create_obj(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDbgObjectType objType);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600420static void create_obj(VkInstance dispatchable_object, VkInstance object, VkDbgObjectType objType);
421static void create_obj(VkDevice dispatchable_object, VkDevice object, VkDbgObjectType objType);
422static void create_obj(VkDevice dispatchable_object, VkDescriptorSet object, VkDbgObjectType objType);
Tobin Ehlisec598302015-09-15 15:02:17 -0600423static void create_obj(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectType objType);
424static VkBool32 validate_object(VkQueue dispatchable_object, VkImage object);
425static VkBool32 validate_object(VkCmdBuffer dispatchable_object, VkImage object);
426static VkBool32 validate_object(VkQueue dispatchable_object, VkCmdBuffer object);
427static VkBool32 validate_object(VkCmdBuffer dispatchable_object, VkDescriptorSet object);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600428static VkBool32 validate_object(VkInstance dispatchable_object, VkInstance object);
429static VkBool32 validate_object(VkDevice dispatchable_object, VkDevice object);
430static VkBool32 validate_object(VkDevice dispatchable_object, VkDescriptorPool object);
Tobin Ehlisec598302015-09-15 15:02:17 -0600431static VkBool32 validate_object(VkDevice dispatchable_object, VkDescriptorSetLayout object);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600432static void destroy_obj(VkInstance dispatchable_object, VkInstance object);
433static void destroy_obj(VkDevice dispatchable_object, VkDeviceMemory object);
Tony Barbour770f80d2015-07-20 10:52:13 -0600434static void destroy_obj(VkDevice dispatchable_object, VkDescriptorSet object);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600435static VkBool32 set_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
436static VkBool32 reset_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600437#if 0
438static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDbgObjectType objType,
439 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
440 const char *fail_msg);
441#endif
Tobin Ehlisec598302015-09-15 15:02:17 -0600442extern unordered_map<const void*, OBJTRACK_NODE*> VkPhysicalDeviceMap;
443extern unordered_map<const void*, OBJTRACK_NODE*> VkImageMap;
444extern unordered_map<const void*, OBJTRACK_NODE*> VkQueueMap;
445extern unordered_map<const void*, OBJTRACK_NODE*> VkDescriptorSetMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600446extern unordered_map<const void*, OBJTRACK_NODE*> VkBufferMap;
447extern unordered_map<const void*, OBJTRACK_NODE*> VkFenceMap;
448extern unordered_map<const void*, OBJTRACK_NODE*> VkSemaphoreMap;
449extern unordered_map<const void*, OBJTRACK_NODE*> VkCmdBufferMap;
Ian Elliott7e40db92015-08-21 15:09:33 -0600450extern unordered_map<const void*, OBJTRACK_NODE*> VkSwapchainKHRMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600451
Tobin Ehlisec598302015-09-15 15:02:17 -0600452static VkBool32 validate_object(VkQueue dispatchable_object, VkImage object)
453{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800454 if ((VkImageMap.find((void*)object) == VkImageMap.end()) &&
455 (swapchainImageMap.find((void*)object) == swapchainImageMap.end())) {
456 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
457 "Invalid VkImage Object %p", object);
Tobin Ehlisec598302015-09-15 15:02:17 -0600458 }
459 return VK_FALSE;
460}
461
462static VkBool32 validate_object(VkCmdBuffer dispatchable_object, VkImage object)
463{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800464 if ((VkImageMap.find((void*)object) == VkImageMap.end()) &&
465 (swapchainImageMap.find((void*)object) == swapchainImageMap.end())) {
466 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
467 "Invalid VkImage Object %p", object);
Tobin Ehlisec598302015-09-15 15:02:17 -0600468 }
469 return VK_FALSE;
470}
471
472static VkBool32 validate_object(VkQueue dispatchable_object, VkCmdBuffer object)
473{
474 if (VkCmdBufferMap.find(object) == VkCmdBufferMap.end()) {
475 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, reinterpret_cast<uint64_t>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
476 "Invalid VkCmdBuffer Object %p",reinterpret_cast<uint64_t>(object));
477 }
478 return VK_FALSE;
479}
480
481static VkBool32 validate_object(VkCmdBuffer dispatchable_object, VkDescriptorSet object)
482{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800483 if (VkDescriptorSetMap.find((void*)object) == VkDescriptorSetMap.end()) {
484 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
485 "Invalid VkDescriptorSet Object %p", object);
Tobin Ehlisec598302015-09-15 15:02:17 -0600486 }
487 return VK_FALSE;
488}
489
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600490static VkBool32 validate_object(VkQueue dispatchable_object, VkBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600491{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800492 if (VkBufferMap.find((void*)object) != VkBufferMap.end()) {
493 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
494 "Invalid VkBuffer Object %p", object);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600495 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600496 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600497}
498
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600499static VkBool32 set_status(VkQueue dispatchable_object, VkFence object, VkDbgObjectType objType, ObjectStatusFlags status_flag)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600500{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600501 VkBool32 skipCall = VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600502 if (object != VK_NULL_HANDLE) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800503 if (VkFenceMap.find((void*)object) != VkFenceMap.end()) {
504 OBJTRACK_NODE* pNode = VkFenceMap[(void*)object];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600505 pNode->status |= status_flag;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600506 }
507 else {
508 // If we do not find it print an error
Chia-I Wue2fc5522015-10-26 20:04:44 +0800509 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 -0600510 "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800511 (uint64_t) object, string_VkDbgObjectType(objType));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600512 }
513 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600514 return skipCall;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600515}
516
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600517static VkBool32 validate_object(VkQueue dispatchable_object, VkSemaphore object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600518{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800519 if (VkSemaphoreMap.find((void*)object) == VkSemaphoreMap.end()) {
520 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, (uint64_t) object, 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
521 "Invalid VkSemaphore Object %p", object);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600522 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600523 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600524}
525
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600526static VkBool32 validate_object(VkDevice dispatchable_object, VkCmdBuffer object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600527{
Tobin Ehlis2717d132015-07-10 18:25:07 -0600528 if (VkCmdBufferMap.find(object) == VkCmdBufferMap.end()) {
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600529 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, reinterpret_cast<uint64_t>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600530 "Invalid VkCmdBuffer Object %p",reinterpret_cast<uint64_t>(object));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600531 }
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600532 return VK_FALSE;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600533}
534
Tobin Ehlisec598302015-09-15 15:02:17 -0600535static void create_obj(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDbgObjectType objType)
536{
537 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
538 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
539 reinterpret_cast<uint64_t>(vkObj));
540
541 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
542 pNewObjNode->objType = objType;
543 pNewObjNode->status = OBJSTATUS_NONE;
544 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
545 VkPhysicalDeviceMap[vkObj] = pNewObjNode;
546 uint32_t objIndex = objTypeToIndex(objType);
547 numObjs[objIndex]++;
548 numTotalObjs++;
549}
550
Tony Barboura05dbaa2015-07-09 17:31:46 -0600551static void create_obj(VkDevice dispatchable_object, VkCmdBuffer vkObj, VkDbgObjectType objType)
552{
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600553 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 -0600554 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600555 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600556
557 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
558 pNewObjNode->objType = objType;
559 pNewObjNode->status = OBJSTATUS_NONE;
Courtney Goeltzenleuchterdee721d2015-08-26 15:09:25 -0600560 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600561 VkCmdBufferMap[vkObj] = pNewObjNode;
562 uint32_t objIndex = objTypeToIndex(objType);
563 numObjs[objIndex]++;
564 numTotalObjs++;
565}
Ian Elliott7e40db92015-08-21 15:09:33 -0600566static void create_obj(VkDevice dispatchable_object, VkSwapchainKHR vkObj, VkDbgObjectType objType)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600567{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800568 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 -0600569 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Chia-I Wue2fc5522015-10-26 20:04:44 +0800570 (uint64_t) vkObj);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600571
572 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
573 pNewObjNode->objType = objType;
574 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800575 pNewObjNode->vkObj = (uint64_t) vkObj;
576 VkSwapchainKHRMap[(void*) vkObj] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600577 uint32_t objIndex = objTypeToIndex(objType);
578 numObjs[objIndex]++;
579 numTotalObjs++;
580}
Tobin Ehlisec598302015-09-15 15:02:17 -0600581static void create_obj(VkDevice dispatchable_object, VkQueue vkObj, VkDbgObjectType objType)
582{
583 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
584 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
585 reinterpret_cast<uint64_t>(vkObj));
586
587 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
588 pNewObjNode->objType = objType;
589 pNewObjNode->status = OBJSTATUS_NONE;
590 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
591 VkQueueMap[vkObj] = pNewObjNode;
592 uint32_t objIndex = objTypeToIndex(objType);
593 numObjs[objIndex]++;
594 numTotalObjs++;
595}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600596static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain)
597{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800598 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 -0600599 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, "SwapchainImage",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800600 (uint64_t) vkObj);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600601
602 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
603 pNewObjNode->objType = VK_OBJECT_TYPE_IMAGE;
604 pNewObjNode->status = OBJSTATUS_NONE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800605 pNewObjNode->vkObj = (uint64_t) vkObj;
606 pNewObjNode->parentObj = (uint64_t) swapchain;
607 swapchainImageMap[(void*)vkObj] = pNewObjNode;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600608}
609
Ian Elliott7e40db92015-08-21 15:09:33 -0600610static void destroy_obj(VkDevice dispatchable_object, VkSwapchainKHR object)
Tony Barboura05dbaa2015-07-09 17:31:46 -0600611{
Chia-I Wue2fc5522015-10-26 20:04:44 +0800612 if (VkSwapchainKHRMap.find((void*) object) != VkSwapchainKHRMap.end()) {
613 OBJTRACK_NODE* pNode = VkSwapchainKHRMap[(void*) object];
Tony Barboura05dbaa2015-07-09 17:31:46 -0600614 uint32_t objIndex = objTypeToIndex(pNode->objType);
615 assert(numTotalObjs > 0);
616 numTotalObjs--;
617 assert(numObjs[objIndex] > 0);
618 numObjs[objIndex]--;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800619 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, pNode->objType, (uint64_t) object, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barboura05dbaa2015-07-09 17:31:46 -0600620 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%lu total objs remain & %lu %s objs).",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800621 string_VkDbgObjectType(pNode->objType), (uint64_t) object, numTotalObjs, numObjs[objIndex],
Tony Barboura05dbaa2015-07-09 17:31:46 -0600622 string_VkDbgObjectType(pNode->objType));
623 delete pNode;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800624 VkSwapchainKHRMap.erase((void*) object);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600625 } else {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800626 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 -0600627 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
Chia-I Wue2fc5522015-10-26 20:04:44 +0800628 (uint64_t) object);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600629 }
630}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600631//
632// Non-auto-generated API functions called by generated code
633//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600634VkResult
635explicit_CreateInstance(
636 const VkInstanceCreateInfo *pCreateInfo,
Chia-I Wuf7458c52015-10-26 21:10:41 +0800637 const VkAllocCallbacks * pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600638 VkInstance * pInstance)
639{
David Pinedoc0fa1ab2015-07-31 10:46:25 -0600640
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600641 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, *pInstance);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800642 VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600643
644 if (result == VK_SUCCESS) {
645 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
646 my_data->report_data = debug_report_create_instance(
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600647 pInstanceTable,
648 *pInstance,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800649 pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600650 pCreateInfo->ppEnabledExtensionNames);
Jon Ashburn3dc39382015-09-17 10:00:32 -0600651 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600652
653 initObjectTracker(my_data);
Tobin Ehlis3e46c802015-06-30 14:31:50 -0600654 create_obj(*pInstance, *pInstance, VK_OBJECT_TYPE_INSTANCE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600655 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600656 return result;
657}
658
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600659void
Cody Northropd0802882015-08-03 17:04:53 -0600660explicit_GetPhysicalDeviceQueueFamilyProperties(
Tony Barbour59a47322015-06-24 16:06:58 -0600661 VkPhysicalDevice gpu,
Cody Northropd0802882015-08-03 17:04:53 -0600662 uint32_t* pCount,
663 VkQueueFamilyProperties* pProperties)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600664{
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600665 get_dispatch_table(ObjectTracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600666
667 loader_platform_thread_lock_mutex(&objLock);
Cody Northropd0802882015-08-03 17:04:53 -0600668 if (pProperties != NULL)
669 setGpuQueueInfoState(*pCount, pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -0600670 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600671}
672
673VkResult
674explicit_CreateDevice(
675 VkPhysicalDevice gpu,
676 const VkDeviceCreateInfo *pCreateInfo,
Chia-I Wuf7458c52015-10-26 21:10:41 +0800677 const VkAllocCallbacks *pAllocator,
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600678 VkDevice *pDevice)
679{
680 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600681// VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, gpu);
682 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800683 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600684 if (result == VK_SUCCESS) {
685 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
686 //// VkLayerDispatchTable *pTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
687 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
688 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchterca173b82015-06-25 18:01:43 -0600689 create_obj(*pDevice, *pDevice, VK_OBJECT_TYPE_DEVICE);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600690 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600691 }
692
693 loader_platform_thread_unlock_mutex(&objLock);
694 return result;
695}
696
Tobin Ehlisec598302015-09-15 15:02:17 -0600697VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
698{
699 VkBool32 skipCall = VK_FALSE;
700 loader_platform_thread_lock_mutex(&objLock);
701 skipCall |= validate_object(instance, instance);
702 loader_platform_thread_unlock_mutex(&objLock);
703 if (skipCall)
704 return VK_ERROR_VALIDATION_FAILED;
705 VkResult result = get_dispatch_table(ObjectTracker_instance_table_map, instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
706 loader_platform_thread_lock_mutex(&objLock);
707 if (result == VK_SUCCESS) {
708 if (pPhysicalDevices) {
709 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
710 create_obj(instance, pPhysicalDevices[i], VK_OBJECT_TYPE_PHYSICAL_DEVICE);
711 }
712 }
713 }
714 loader_platform_thread_unlock_mutex(&objLock);
715 return result;
716}
717
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600718void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600719explicit_GetDeviceQueue(
720 VkDevice device,
721 uint32_t queueNodeIndex,
722 uint32_t queueIndex,
723 VkQueue *pQueue)
724{
725 loader_platform_thread_lock_mutex(&objLock);
726 validate_object(device, device);
727 loader_platform_thread_unlock_mutex(&objLock);
728
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600729 get_dispatch_table(ObjectTracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600730
731 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600732 addQueueInfo(queueNodeIndex, *pQueue);
733 create_obj(device, *pQueue, VK_OBJECT_TYPE_QUEUE);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600734 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600735}
736
737VkResult
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600738explicit_MapMemory(
739 VkDevice device,
740 VkDeviceMemory mem,
741 VkDeviceSize offset,
742 VkDeviceSize size,
743 VkFlags flags,
744 void **ppData)
745{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600746 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600747 loader_platform_thread_lock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600748 skipCall |= set_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
749 skipCall |= validate_object(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600750 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600751 if (skipCall == VK_TRUE)
752 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600753
754 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
755
756 return result;
757}
758
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600759void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600760explicit_UnmapMemory(
761 VkDevice device,
762 VkDeviceMemory mem)
763{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600764 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600765 loader_platform_thread_lock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600766 skipCall |= reset_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
767 skipCall |= validate_object(device, device);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600768 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600769 if (skipCall == VK_TRUE)
770 return;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600771
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600772 get_dispatch_table(ObjectTracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600773}
774
775VkResult
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800776explicit_QueueBindSparse(
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600777 VkQueue queue,
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800778 uint32_t bindInfoCount,
779 const VkBindSparseInfo* pBindInfo,
780 VkFence fence)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600781{
782 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800783 validateQueueFlags(queue, "QueueBindSparse");
784
785 for (uint32_t i = 0; i < bindInfoCount; i++) {
786 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
787 validate_object(queue, pBindInfo[i].pBufferBinds[j].buffer);
788 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
789 validate_object(queue, pBindInfo[i].pImageOpaqueBinds[j].image);
790 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
791 validate_object(queue, pBindInfo[i].pImageBinds[j].image);
792 }
793
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600794 loader_platform_thread_unlock_mutex(&objLock);
795
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800796 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600797 return result;
798}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600799
800VkResult
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600801explicit_AllocDescriptorSets(
802 VkDevice device,
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600803 const VkDescriptorSetAllocInfo *pAllocInfo,
Cody Northrop1e4f8022015-08-03 12:47:29 -0600804 VkDescriptorSet *pDescriptorSets)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600805{
Tobin Ehlisec598302015-09-15 15:02:17 -0600806 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600807 loader_platform_thread_lock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600808 skipCall |= validate_object(device, device);
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600809 skipCall |= validate_object(device, pAllocInfo->descriptorPool);
Chia-I Wud50a7d72015-10-26 20:48:51 +0800810 for (uint32_t i = 0; i < pAllocInfo->setLayoutCount; i++) {
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600811 skipCall |= validate_object(device, pAllocInfo->pSetLayouts[i]);
Tobin Ehlisec598302015-09-15 15:02:17 -0600812 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600813 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600814 if (skipCall)
815 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600816
817 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocDescriptorSets(
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600818 device, pAllocInfo, pDescriptorSets);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600819
820 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wud50a7d72015-10-26 20:48:51 +0800821 for (uint32_t i = 0; i < pAllocInfo->setLayoutCount; i++) {
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600822 create_obj(device, pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);
823 }
824 loader_platform_thread_unlock_mutex(&objLock);
825
826 return result;
827}
828
829VkResult
Ian Elliott7e40db92015-08-21 15:09:33 -0600830explicit_DestroySwapchainKHR(
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600831 VkDevice device,
Ian Elliott7e40db92015-08-21 15:09:33 -0600832 VkSwapchainKHR swapchain)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600833{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600834 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600835 // A swapchain's images are implicitly deleted when the swapchain is deleted.
836 // Remove this swapchain's images from our map of such images.
837 unordered_map<const void*, OBJTRACK_NODE*>::iterator itr = swapchainImageMap.begin();
838 while (itr != swapchainImageMap.end()) {
839 OBJTRACK_NODE* pNode = (*itr).second;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800840 if (pNode->parentObj == (uint64_t) swapchain) {
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600841 swapchainImageMap.erase(itr++);
842 } else {
843 ++itr;
844 }
845 }
Ian Elliott7e40db92015-08-21 15:09:33 -0600846 destroy_obj(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600847 loader_platform_thread_unlock_mutex(&objLock);
848
Ian Elliott7e40db92015-08-21 15:09:33 -0600849 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600850 return result;
851}
852
Mark Lobodzinski2141f652015-09-07 13:59:43 -0600853void
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600854explicit_FreeMemory(
855 VkDevice device,
Chia-I Wuf7458c52015-10-26 21:10:41 +0800856 VkDeviceMemory mem,
857 const VkAllocCallbacks* pAllocator)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600858{
859 loader_platform_thread_lock_mutex(&objLock);
860 validate_object(device, device);
861 loader_platform_thread_unlock_mutex(&objLock);
862
Chia-I Wuf7458c52015-10-26 21:10:41 +0800863 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600864
865 loader_platform_thread_lock_mutex(&objLock);
866 destroy_obj(device, mem);
867 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600868}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600869
Tony Barbour770f80d2015-07-20 10:52:13 -0600870VkResult
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600871explicit_FreeDescriptorSets(
872 VkDevice device,
873 VkDescriptorPool descriptorPool,
874 uint32_t count,
875 const VkDescriptorSet *pDescriptorSets)
Tony Barbour770f80d2015-07-20 10:52:13 -0600876{
877 loader_platform_thread_lock_mutex(&objLock);
878 validate_object(device, descriptorPool);
879 validate_object(device, device);
880 loader_platform_thread_unlock_mutex(&objLock);
881 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
882
883 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter7ebf1212015-07-23 11:25:17 -0600884 for (uint32_t i=0; i<count; i++)
Tony Barbour770f80d2015-07-20 10:52:13 -0600885 {
886 destroy_obj(device, *pDescriptorSets++);
887 }
888 loader_platform_thread_unlock_mutex(&objLock);
889 return result;
890}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600891
892VkResult
893explicit_GetSwapchainImagesKHR(
894 VkDevice device,
895 VkSwapchainKHR swapchain,
896 uint32_t *pCount,
897 VkImage *pSwapchainImages)
898{
899 VkBool32 skipCall = VK_FALSE;
900 loader_platform_thread_lock_mutex(&objLock);
901 skipCall |= validate_object(device, device);
902 loader_platform_thread_unlock_mutex(&objLock);
903 if (skipCall)
904 return VK_ERROR_VALIDATION_FAILED;
905
906 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
907
908 if (pSwapchainImages != NULL) {
909 loader_platform_thread_lock_mutex(&objLock);
910 for (uint32_t i = 0; i < *pCount; i++) {
911 create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
912 }
913 loader_platform_thread_unlock_mutex(&objLock);
914 }
915 return result;
916}
917