blob: 141d0d9f9fb260fb87f4a4d6d8ab889c5b37592a [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
Chia-I Wub1466182015-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 Ehlis235c20e2015-01-16 08:56:30 -070038 OBJTRACK_INVALID_FENCE, // Requested status of unsubmitted fence object
Tobin Ehlis586aa012015-06-08 17:36:28 -060039 OBJTRACK_INVALID_OBJECT, // Object used that has never been created
Tobin Ehlis3c26a542014-11-18 11:28:33 -070040} OBJECT_TRACK_ERROR;
41
Tobin Ehlis235c20e2015-01-16 08:56:30 -070042// Object Status -- used to track state of individual objects
Mark Lobodzinski7d2d5ac2015-05-20 17:33:47 -050043typedef VkFlags ObjectStatusFlags;
44typedef enum _ObjectStatusFlagBits
Tobin Ehlis235c20e2015-01-16 08:56:30 -070045{
Mark Lobodzinski01552702015-02-03 10:06:31 -060046 OBJSTATUS_NONE = 0x00000000, // No status is set
47 OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted
48 OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound
49 OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound
50 OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound
51 OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound
Mark Lobodzinski4186e712015-02-03 11:52:26 -060052 OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped
Mark Lobodzinski7d2d5ac2015-05-20 17:33:47 -050053} ObjectStatusFlagBits;
Chia-I Wu5b66aa52015-04-16 22:02:10 +080054
Tobin Ehlisacab8882014-11-14 13:01:02 -070055typedef struct _OBJTRACK_NODE {
Tony Barbour2a199c12015-07-09 17:31:46 -060056 uint64_t vkObj;
57 VkDbgObjectType objType;
58 ObjectStatusFlags status;
Tobin Ehlisacab8882014-11-14 13:01:02 -070059} OBJTRACK_NODE;
Mark Lobodzinskie1d3f0c2015-02-09 10:20:53 -060060
Tobin Ehlisacab8882014-11-14 13:01:02 -070061// prototype for extension functions
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060062uint64_t objTrackGetObjectCount(VkDevice device);
Tony Barbour2a199c12015-07-09 17:31:46 -060063uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDbgObjectType type);
Mark Lobodzinskie1d3f0c2015-02-09 10:20:53 -060064
Tobin Ehlis3c26a542014-11-18 11:28:33 -070065// Func ptr typedefs
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060066typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
Tony Barbour2a199c12015-07-09 17:31:46 -060067typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDbgObjectType);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060068
69typedef struct _layer_data {
70 debug_report_data *report_data;
71 //TODO: put instance data here
72 VkDbgMsgCallback logging_callback;
Ian Elliottb134e842015-07-06 14:31:32 -060073 bool wsi_enabled;
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -060074 bool objtrack_extensions_enabled;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060075} layer_data;
76
77static std::unordered_map<void*, layer_data *> layer_data_map;
78static device_table_map ObjectTracker_device_table_map;
79static instance_table_map ObjectTracker_instance_table_map;
80
81static long long unsigned int object_track_index = 0;
82static int objLockInitialized = 0;
83static loader_platform_thread_mutex objLock;
84
85// Objects stored in a global map w/ struct containing basic info
Tony Barbour2a199c12015-07-09 17:31:46 -060086// unordered_map<const void*, OBJTRACK_NODE*> objMap;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060087
Tony Barbour2a199c12015-07-09 17:31:46 -060088#define NUM_OBJECT_TYPES VK_OBJECT_TYPE_NUM
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060089
90static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
91static uint64_t numTotalObjs = 0;
Cody Northropef72e2a2015-08-03 17:04:53 -060092static VkQueueFamilyProperties *queueInfo = NULL;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060093static uint32_t queueCount = 0;
94
95template layer_data *get_my_data_ptr<layer_data>(
96 void *data_key, std::unordered_map<void *, layer_data *> &data_map);
97
Mark Lobodzinskif993d542015-09-01 08:52:55 -060098static inline const char* string_VkDbgObjectType(VkDbgObjectType input_value)
99{
100 switch ((VkDbgObjectType)input_value)
101 {
102 case VK_OBJECT_TYPE_CMD_POOL:
103 return "VK_OBJECT_TYPE_CMD_POOL";
104 case VK_OBJECT_TYPE_BUFFER:
105 return "VK_OBJECT_TYPE_BUFFER";
106 case VK_OBJECT_TYPE_BUFFER_VIEW:
107 return "VK_OBJECT_TYPE_BUFFER_VIEW";
108 case VK_OBJECT_TYPE_ATTACHMENT_VIEW:
109 return "VK_OBJECT_TYPE_ATTACHMENT_VIEW";
110 case VK_OBJECT_TYPE_COMMAND_BUFFER:
111 return "VK_OBJECT_TYPE_COMMAND_BUFFER";
112 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
113 return "VK_OBJECT_TYPE_DESCRIPTOR_POOL";
114 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
115 return "VK_OBJECT_TYPE_DESCRIPTOR_SET";
116 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
117 return "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT";
118 case VK_OBJECT_TYPE_DEVICE:
119 return "VK_OBJECT_TYPE_DEVICE";
120 case VK_OBJECT_TYPE_DEVICE_MEMORY:
121 return "VK_OBJECT_TYPE_DEVICE_MEMORY";
122 case VK_OBJECT_TYPE_DYNAMIC_BLEND_STATE:
123 return "VK_OBJECT_TYPE_DYNAMIC_BLEND_STATE";
124 case VK_OBJECT_TYPE_DYNAMIC_DEPTH_BOUNDS_STATE:
125 return "VK_OBJECT_TYPE_DYNAMIC_DEPTH_BOUNDS_STATE";
126 case VK_OBJECT_TYPE_DYNAMIC_STENCIL_STATE:
127 return "VK_OBJECT_TYPE_DYNAMIC_STENCIL_STATE";
128 case VK_OBJECT_TYPE_DYNAMIC_LINE_WIDTH_STATE:
129 return "VK_OBJECT_TYPE_DYNAMIC_LINE_WIDTH_STATE";
130 case VK_OBJECT_TYPE_DYNAMIC_DEPTH_BIAS_STATE:
131 return "VK_OBJECT_TYPE_DYNAMIC_DEPTH_BIAS_STATE";
132 case VK_OBJECT_TYPE_DYNAMIC_VIEWPORT_STATE:
133 return "VK_OBJECT_TYPE_DYNAMIC_VIEPORT_STATE";
134 case VK_OBJECT_TYPE_EVENT:
135 return "VK_OBJECT_TYPE_EVENT";
136 case VK_OBJECT_TYPE_FENCE:
137 return "VK_OBJECT_TYPE_FENCE";
138 case VK_OBJECT_TYPE_FRAMEBUFFER:
139 return "VK_OBJECT_TYPE_FRAMEBUFFER";
140 case VK_OBJECT_TYPE_IMAGE:
141 return "VK_OBJECT_TYPE_IMAGE";
142 case VK_OBJECT_TYPE_IMAGE_VIEW:
143 return "VK_OBJECT_TYPE_IMAGE_VIEW";
144 case VK_OBJECT_TYPE_INSTANCE:
145 return "VK_OBJECT_TYPE_INSTANCE";
146 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
147 return "VK_OBJECT_TYPE_PHYSICAL_DEVICE";
148 case VK_OBJECT_TYPE_PIPELINE:
149 return "VK_OBJECT_TYPE_PIPELINE";
150 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
151 return "VK_OBJECT_TYPE_PIPELINE_LAYOUT";
152 case VK_OBJECT_TYPE_PIPELINE_CACHE:
153 return "VK_OBJECT_TYPE_PIPELINE_CACHE";
154 case VK_OBJECT_TYPE_QUERY_POOL:
155 return "VK_OBJECT_TYPE_QUERY_POOL";
156 case VK_OBJECT_TYPE_QUEUE:
157 return "VK_OBJECT_TYPE_QUEUE";
158 case VK_OBJECT_TYPE_RENDER_PASS:
159 return "VK_OBJECT_TYPE_RENDER_PASS";
160 case VK_OBJECT_TYPE_SAMPLER:
161 return "VK_OBJECT_TYPE_SAMPLER";
162 case VK_OBJECT_TYPE_SEMAPHORE:
163 return "VK_OBJECT_TYPE_SEMAPHORE";
164 case VK_OBJECT_TYPE_SHADER:
165 return "VK_OBJECT_TYPE_SHADER";
166 case VK_OBJECT_TYPE_SHADER_MODULE:
167 return "VK_OBJECT_TYPE_SHADER_MODULE";
Ian Elliott338dedb2015-08-21 15:09:33 -0600168 case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
169 return "VK_OBJECT_TYPE_SWAPCHAIN_KHR";
Mark Lobodzinskif993d542015-09-01 08:52:55 -0600170 default:
171 return "Unhandled VkObjectType";
172 }
173}
174
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600175//
176// Internal Object Tracker Functions
177//
178
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600179static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
180{
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600181 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliottb134e842015-07-06 14:31:32 -0600182 my_device_data->wsi_enabled = false;
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600183 for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) {
Ian Elliottb6067262015-09-15 12:14:41 -0600184 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliottb134e842015-07-06 14:31:32 -0600185 my_device_data->wsi_enabled = true;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600186
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600187 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0)
188 my_device_data->objtrack_extensions_enabled = true;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600189 }
190}
191
192// Indicate device or instance dispatch table type
193typedef enum _DispTableType
194{
195 DISP_TBL_TYPE_INSTANCE,
196 DISP_TBL_TYPE_DEVICE,
197} DispTableType;
198
Tony Barbour2a199c12015-07-09 17:31:46 -0600199debug_report_data *mdd(const void* object)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600200{
201 dispatch_key key = get_dispatch_key(object);
202 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600203 return my_data->report_data;
204}
205
206debug_report_data *mid(VkInstance object)
207{
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600208 dispatch_key key = get_dispatch_key(object);
209 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600210 return my_data->report_data;
211}
212
213// For each Queue's doubly linked-list of mem refs
214typedef struct _OT_MEM_INFO {
215 VkDeviceMemory mem;
216 struct _OT_MEM_INFO *pNextMI;
217 struct _OT_MEM_INFO *pPrevMI;
218
219} OT_MEM_INFO;
220
221// Track Queue information
222typedef struct _OT_QUEUE_INFO {
223 OT_MEM_INFO *pMemRefList;
224 struct _OT_QUEUE_INFO *pNextQI;
225 uint32_t queueNodeIndex;
226 VkQueue queue;
227 uint32_t refCount;
228} OT_QUEUE_INFO;
229
230// Global list of QueueInfo structures, one per queue
231static OT_QUEUE_INFO *g_pQueueInfo = NULL;
232
233// Convert an object type enum to an object type array index
234static uint32_t
235objTypeToIndex(
236 uint32_t objType)
237{
238 uint32_t index = objType;
239 if (objType > VK_OBJECT_TYPE_END_RANGE) {
Ian Elliott338dedb2015-08-21 15:09:33 -0600240 // These come from vk_ext_khr_swapchain.h, rebase
241 index = (index -(VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER * -1000)) + VK_OBJECT_TYPE_END_RANGE;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600242 }
243 return index;
244}
245
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600246// Add new queue to head of global queue list
247static void
248addQueueInfo(
249 uint32_t queueNodeIndex,
250 VkQueue queue)
251{
252 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
253
254 if (pQueueInfo != NULL) {
255 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
256 pQueueInfo->queue = queue;
257 pQueueInfo->queueNodeIndex = queueNodeIndex;
258 pQueueInfo->pNextQI = g_pQueueInfo;
259 g_pQueueInfo = pQueueInfo;
260 }
261 else {
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600262 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<uint64_t>(queue), 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK",
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600263 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
264 }
265}
266
267// Destroy memRef lists and free all memory
268static void
269destroyQueueMemRefLists(void)
270{
271 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
272 OT_QUEUE_INFO *pDelQueueInfo = NULL;
273 while (pQueueInfo != NULL) {
274 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
275 while (pMemInfo != NULL) {
276 OT_MEM_INFO *pDelMemInfo = pMemInfo;
277 pMemInfo = pMemInfo->pNextMI;
278 delete pDelMemInfo;
279 }
280 pDelQueueInfo = pQueueInfo;
281 pQueueInfo = pQueueInfo->pNextQI;
282 delete pDelQueueInfo;
283 }
284 g_pQueueInfo = pQueueInfo;
285}
286
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600287static void
288setGpuQueueInfoState(
Tony Barbour426b9052015-06-24 16:06:58 -0600289 uint32_t count,
290 void *pData)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600291{
Tony Barbour426b9052015-06-24 16:06:58 -0600292 queueCount = count;
Cody Northropef72e2a2015-08-03 17:04:53 -0600293 queueInfo = (VkQueueFamilyProperties*)realloc((void*)queueInfo, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600294 if (queueInfo != NULL) {
Cody Northropef72e2a2015-08-03 17:04:53 -0600295 memcpy(queueInfo, pData, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600296 }
297}
298
299// Check Queue type flags for selected queue operations
300static void
301validateQueueFlags(
302 VkQueue queue,
303 const char *function)
304{
305 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
306 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
307 pQueueInfo = pQueueInfo->pNextQI;
308 }
309 if (pQueueInfo != NULL) {
310 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_MEMMGR_BIT) == 0) {
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600311 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<uint64_t>(queue), 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600312 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not set", function);
313 } else {
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600314 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_QUEUE, reinterpret_cast<uint64_t>(queue), 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600315 "Attempting %s on a possibly non-memory-management capable queue -- VK_QUEUE_SPARSE_MEMMGR_BIT not known", function);
316 }
317 }
318}
319
Tony Barbour2a199c12015-07-09 17:31:46 -0600320/* TODO: Port to new type safety */
321#if 0
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600322// Check object status for selected flag state
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600323static VkBool32
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600324validate_status(
325 VkObject dispatchable_object,
326 VkObject vkObj,
327 VkObjectType objType,
328 ObjectStatusFlags status_mask,
329 ObjectStatusFlags status_flag,
330 VkFlags msg_flags,
331 OBJECT_TRACK_ERROR error_code,
332 const char *fail_msg)
333{
334 if (objMap.find(vkObj) != objMap.end()) {
335 OBJTRACK_NODE* pNode = objMap[vkObj];
336 if ((pNode->status & status_mask) != status_flag) {
337 char str[1024];
338 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
339 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600340 reinterpret_cast<uint64_t>(vkObj), fail_msg);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600341 return VK_FALSE;
342 }
343 return VK_TRUE;
344 }
345 else {
346 // If we do not find it print an error
347 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, 0, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
348 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600349 reinterpret_cast<uint64_t>(vkObj), string_VkObjectType(objType));
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600350 return VK_FALSE;
351 }
352}
Tony Barbour2a199c12015-07-09 17:31:46 -0600353#endif
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600354
355#include "vk_dispatch_table_helper.h"
356static void
357initObjectTracker(
358 layer_data *my_data)
359{
360 uint32_t report_flags = 0;
361 uint32_t debug_action = 0;
362 FILE *log_output = NULL;
363 const char *option_str;
364 // initialize ObjectTracker options
365 report_flags = getLayerOptionFlags("ObjectTrackerReportFlags", 0);
366 getLayerOptionEnum("ObjectTrackerDebugAction", (uint32_t *) &debug_action);
367
368 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
369 {
370 option_str = getLayerOption("ObjectTrackerLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -0600371 log_output = getLayerLogOutput(option_str, "ObjectTracker");
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600372 layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &my_data->logging_callback);
373 }
374
375 if (!objLockInitialized)
376 {
377 // TODO/TBD: Need to delete this mutex sometime. How??? One
378 // suggestion is to call this during vkCreateInstance(), and then we
379 // can clean it up during vkDestroyInstance(). However, that requires
380 // that the layer have per-instance locks. We need to come back and
381 // address this soon.
382 loader_platform_thread_create_mutex(&objLock);
383 objLockInitialized = 1;
384 }
385}
386
Tony Barbour2a199c12015-07-09 17:31:46 -0600387//
388// Forward declares of generated routines
389//
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600390
Tony Barbour2a199c12015-07-09 17:31:46 -0600391static void create_obj(VkInstance dispatchable_object, VkInstance object, VkDbgObjectType objType);
392static void create_obj(VkDevice dispatchable_object, VkDevice object, VkDbgObjectType objType);
393static void create_obj(VkDevice dispatchable_object, VkDescriptorSet object, VkDbgObjectType objType);
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600394static VkBool32 validate_object(VkInstance dispatchable_object, VkInstance object);
395static VkBool32 validate_object(VkDevice dispatchable_object, VkDevice object);
396static VkBool32 validate_object(VkDevice dispatchable_object, VkDescriptorPool object);
Tony Barbour2a199c12015-07-09 17:31:46 -0600397static void destroy_obj(VkInstance dispatchable_object, VkInstance object);
398static void destroy_obj(VkDevice dispatchable_object, VkDeviceMemory object);
Tony Barbour912e8152015-07-20 10:52:13 -0600399static void destroy_obj(VkDevice dispatchable_object, VkDescriptorSet object);
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600400static VkBool32 set_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
401static VkBool32 reset_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDbgObjectType objType, ObjectStatusFlags status_flag);
Tony Barbour2a199c12015-07-09 17:31:46 -0600402#if 0
403static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDbgObjectType objType,
404 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
405 const char *fail_msg);
406#endif
407extern unordered_map<const void*, OBJTRACK_NODE*> VkBufferMap;
408extern unordered_map<const void*, OBJTRACK_NODE*> VkFenceMap;
409extern unordered_map<const void*, OBJTRACK_NODE*> VkSemaphoreMap;
410extern unordered_map<const void*, OBJTRACK_NODE*> VkCmdBufferMap;
Ian Elliott338dedb2015-08-21 15:09:33 -0600411extern unordered_map<const void*, OBJTRACK_NODE*> VkSwapchainKHRMap;
Tony Barbour2a199c12015-07-09 17:31:46 -0600412
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600413static VkBool32 validate_object(VkQueue dispatchable_object, VkBuffer object)
Tony Barbour2a199c12015-07-09 17:31:46 -0600414{
415 if (VkBufferMap.find((void*)object.handle) != VkBufferMap.end()) {
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600416 return 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 -0600417 "Invalid VkBuffer Object %p", object.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600418 }
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600419 return VK_FALSE;
Tony Barbour2a199c12015-07-09 17:31:46 -0600420}
421
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600422static VkBool32 set_status(VkQueue dispatchable_object, VkFence object, VkDbgObjectType objType, ObjectStatusFlags status_flag)
Tony Barbour2a199c12015-07-09 17:31:46 -0600423{
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600424 VkBool32 skipCall = VK_FALSE;
Tony Barbour2a199c12015-07-09 17:31:46 -0600425 if (object != VK_NULL_HANDLE) {
426 if (VkFenceMap.find((void*)object.handle) != VkFenceMap.end()) {
427 OBJTRACK_NODE* pNode = VkFenceMap[(void*)object.handle];
428 pNode->status |= status_flag;
Tony Barbour2a199c12015-07-09 17:31:46 -0600429 }
430 else {
431 // If we do not find it print an error
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600432 skipCall |= 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 -0600433 "Unable to set status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Tony Barbour8db65372015-07-10 18:32:33 -0600434 object.handle, string_VkDbgObjectType(objType));
Tony Barbour2a199c12015-07-09 17:31:46 -0600435 }
436 }
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600437 return skipCall;
Tony Barbour2a199c12015-07-09 17:31:46 -0600438}
439
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600440static VkBool32 validate_object(VkQueue dispatchable_object, VkSemaphore object)
Tony Barbour2a199c12015-07-09 17:31:46 -0600441{
442 if (VkSemaphoreMap.find((void*)object.handle) == VkSemaphoreMap.end()) {
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600443 return 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 -0600444 "Invalid VkSemaphore Object %p", object.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600445 }
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600446 return VK_FALSE;
Tony Barbour2a199c12015-07-09 17:31:46 -0600447}
448
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600449static VkBool32 validate_object(VkDevice dispatchable_object, VkCmdBuffer object)
Tony Barbour2a199c12015-07-09 17:31:46 -0600450{
Tobin Ehlis33ce8fd2015-07-10 18:25:07 -0600451 if (VkCmdBufferMap.find(object) == VkCmdBufferMap.end()) {
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600452 return log_msg(mdd(dispatchable_object), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, reinterpret_cast<uint64_t>(object), 0, OBJTRACK_INVALID_OBJECT, "OBJTRACK",
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600453 "Invalid VkCmdBuffer Object %p",reinterpret_cast<uint64_t>(object));
Tony Barbour2a199c12015-07-09 17:31:46 -0600454 }
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600455 return VK_FALSE;
Tony Barbour2a199c12015-07-09 17:31:46 -0600456}
457
458static void create_obj(VkDevice dispatchable_object, VkCmdBuffer vkObj, VkDbgObjectType objType)
459{
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600460 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, reinterpret_cast<uint64_t>(vkObj), 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barbour2a199c12015-07-09 17:31:46 -0600461 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600462 reinterpret_cast<uint64_t>(vkObj));
Tony Barbour2a199c12015-07-09 17:31:46 -0600463
464 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
465 pNewObjNode->objType = objType;
466 pNewObjNode->status = OBJSTATUS_NONE;
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600467 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Tony Barbour2a199c12015-07-09 17:31:46 -0600468 VkCmdBufferMap[vkObj] = pNewObjNode;
469 uint32_t objIndex = objTypeToIndex(objType);
470 numObjs[objIndex]++;
471 numTotalObjs++;
472}
Ian Elliott338dedb2015-08-21 15:09:33 -0600473static void create_obj(VkDevice dispatchable_object, VkSwapchainKHR vkObj, VkDbgObjectType objType)
Tony Barbour2a199c12015-07-09 17:31:46 -0600474{
Tony Barbour7910de72015-07-13 16:37:21 -0600475 log_msg(mdd(dispatchable_object), VK_DBG_REPORT_INFO_BIT, objType, vkObj.handle, 0, OBJTRACK_NONE, "OBJTRACK",
Tony Barbour2a199c12015-07-09 17:31:46 -0600476 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDbgObjectType(objType),
Tony Barbour7910de72015-07-13 16:37:21 -0600477 vkObj.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600478
479 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
480 pNewObjNode->objType = objType;
481 pNewObjNode->status = OBJSTATUS_NONE;
Tony Barbour7910de72015-07-13 16:37:21 -0600482 pNewObjNode->vkObj = vkObj.handle;
Ian Elliott338dedb2015-08-21 15:09:33 -0600483 VkSwapchainKHRMap[(void*) vkObj.handle] = pNewObjNode;
Tony Barbour2a199c12015-07-09 17:31:46 -0600484 uint32_t objIndex = objTypeToIndex(objType);
485 numObjs[objIndex]++;
486 numTotalObjs++;
487}
Ian Elliott338dedb2015-08-21 15:09:33 -0600488static void destroy_obj(VkDevice dispatchable_object, VkSwapchainKHR object)
Tony Barbour2a199c12015-07-09 17:31:46 -0600489{
Ian Elliott338dedb2015-08-21 15:09:33 -0600490 if (VkSwapchainKHRMap.find((void*) object.handle) != VkSwapchainKHRMap.end()) {
491 OBJTRACK_NODE* pNode = VkSwapchainKHRMap[(void*) object.handle];
Tony Barbour2a199c12015-07-09 17:31:46 -0600492 uint32_t objIndex = objTypeToIndex(pNode->objType);
493 assert(numTotalObjs > 0);
494 numTotalObjs--;
495 assert(numObjs[objIndex] > 0);
496 numObjs[objIndex]--;
Tony Barbour7910de72015-07-13 16:37:21 -0600497 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 -0600498 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%lu total objs remain & %lu %s objs).",
Tony Barbour7910de72015-07-13 16:37:21 -0600499 string_VkDbgObjectType(pNode->objType), object.handle, numTotalObjs, numObjs[objIndex],
Tony Barbour2a199c12015-07-09 17:31:46 -0600500 string_VkDbgObjectType(pNode->objType));
501 delete pNode;
Ian Elliott338dedb2015-08-21 15:09:33 -0600502 VkSwapchainKHRMap.erase((void*) object.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600503 } else {
Tony Barbour7910de72015-07-13 16:37:21 -0600504 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 -0600505 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
Tony Barbour7910de72015-07-13 16:37:21 -0600506 object.handle);
Tony Barbour2a199c12015-07-09 17:31:46 -0600507 }
508}
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600509//
510// Non-auto-generated API functions called by generated code
511//
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600512VkResult
513explicit_CreateInstance(
514 const VkInstanceCreateInfo *pCreateInfo,
515 VkInstance * pInstance)
516{
David Pinedo565035c2015-07-31 10:46:25 -0600517
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600518 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, *pInstance);
519 VkResult result = pInstanceTable->CreateInstance(pCreateInfo, pInstance);
520
521 if (result == VK_SUCCESS) {
522 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
523 my_data->report_data = debug_report_create_instance(
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600524 pInstanceTable,
525 *pInstance,
526 pCreateInfo->extensionCount,
527 pCreateInfo->ppEnabledExtensionNames);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600528
529 initObjectTracker(my_data);
Tobin Ehlis86b52ec2015-06-30 14:31:50 -0600530 create_obj(*pInstance, *pInstance, VK_OBJECT_TYPE_INSTANCE);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600531 }
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600532 return result;
533}
534
535VkResult
Cody Northropef72e2a2015-08-03 17:04:53 -0600536explicit_GetPhysicalDeviceQueueFamilyProperties(
Tony Barbour426b9052015-06-24 16:06:58 -0600537 VkPhysicalDevice gpu,
Cody Northropef72e2a2015-08-03 17:04:53 -0600538 uint32_t* pCount,
539 VkQueueFamilyProperties* pProperties)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600540{
Cody Northropef72e2a2015-08-03 17:04:53 -0600541 VkResult result = get_dispatch_table(ObjectTracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600542
543 loader_platform_thread_lock_mutex(&objLock);
Cody Northropef72e2a2015-08-03 17:04:53 -0600544 if (pProperties != NULL)
545 setGpuQueueInfoState(*pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600546 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600547 return result;
548}
549
550VkResult
551explicit_CreateDevice(
552 VkPhysicalDevice gpu,
553 const VkDeviceCreateInfo *pCreateInfo,
554 VkDevice *pDevice)
555{
556 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600557// VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ObjectTracker_instance_table_map, gpu);
558 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
559 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pDevice);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600560 if (result == VK_SUCCESS) {
561 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
562 //// VkLayerDispatchTable *pTable = get_dispatch_table(ObjectTracker_device_table_map, *pDevice);
563 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
564 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -0600565 create_obj(*pDevice, *pDevice, VK_OBJECT_TYPE_DEVICE);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600566 }
567
568 loader_platform_thread_unlock_mutex(&objLock);
569 return result;
570}
571
572VkResult
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600573explicit_GetDeviceQueue(
574 VkDevice device,
575 uint32_t queueNodeIndex,
576 uint32_t queueIndex,
577 VkQueue *pQueue)
578{
579 loader_platform_thread_lock_mutex(&objLock);
580 validate_object(device, device);
581 loader_platform_thread_unlock_mutex(&objLock);
582
583 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
584
585 loader_platform_thread_lock_mutex(&objLock);
586 addQueueInfo(queueNodeIndex, *pQueue);
587 loader_platform_thread_unlock_mutex(&objLock);
588
589 return result;
590}
591
592VkResult
593explicit_QueueSubmit(
594 VkQueue queue,
595 uint32_t cmdBufferCount,
596 const VkCmdBuffer *pCmdBuffers,
597 VkFence fence)
598{
599 loader_platform_thread_lock_mutex(&objLock);
600 set_status(queue, fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED);
601 // TODO: Fix for updated memory reference mechanism
602 // validate_memory_mapping_status(pMemRefs, memRefCount);
603 // validate_mem_ref_count(memRefCount);
604 loader_platform_thread_unlock_mutex(&objLock);
605
606 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
607
608 return result;
609}
610
611VkResult
612explicit_MapMemory(
613 VkDevice device,
614 VkDeviceMemory mem,
615 VkDeviceSize offset,
616 VkDeviceSize size,
617 VkFlags flags,
618 void **ppData)
619{
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600620 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600621 loader_platform_thread_lock_mutex(&objLock);
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600622 skipCall |= set_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
623 skipCall |= validate_object(device, device);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600624 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600625 if (skipCall == VK_TRUE)
626 return VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600627
628 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
629
630 return result;
631}
632
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600633void
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600634explicit_UnmapMemory(
635 VkDevice device,
636 VkDeviceMemory mem)
637{
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600638 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600639 loader_platform_thread_lock_mutex(&objLock);
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600640 skipCall |= reset_status(device, mem, VK_OBJECT_TYPE_DEVICE_MEMORY, OBJSTATUS_GPU_MEM_MAPPED);
641 skipCall |= validate_object(device, device);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600642 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600643 if (skipCall == VK_TRUE)
644 return;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600645
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600646 get_dispatch_table(ObjectTracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600647}
648
649VkResult
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600650explicit_QueueBindSparseBufferMemory(
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600651 VkQueue queue,
652 VkBuffer buffer,
653 uint32_t numBindings,
654 const VkSparseMemoryBindInfo* pBindInfo)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600655{
656 loader_platform_thread_lock_mutex(&objLock);
657 validateQueueFlags(queue, "QueueBindSparseBufferMemory");
658 validate_object(queue, buffer);
659 loader_platform_thread_unlock_mutex(&objLock);
660
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600661 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparseBufferMemory(queue, buffer, numBindings, pBindInfo);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600662 return result;
663}
664
665VkResult
666explicit_QueueBindSparseImageMemory(
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600667 VkQueue queue,
668 VkImage image,
669 uint32_t numBindings,
670 const VkSparseImageMemoryBindInfo* pBindInfo)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600671{
672 loader_platform_thread_lock_mutex(&objLock);
673 validateQueueFlags(queue, "QueueBindSparseImageMemory");
674 loader_platform_thread_unlock_mutex(&objLock);
675
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600676 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparseImageMemory(queue, image, numBindings, pBindInfo);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600677 return result;
678}
679
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600680VkResult
681explicit_QueueBindSparseImageOpaqueMemory(
682 VkQueue queue,
683 VkImage image,
684 uint32_t numBindings,
685 const VkSparseMemoryBindInfo* pBindInfo)
686{
687 loader_platform_thread_lock_mutex(&objLock);
688 validateQueueFlags(queue, "QueueBindSparseImageOpaqueMemory");
689 loader_platform_thread_unlock_mutex(&objLock);
690
691 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, queue)->QueueBindSparseImageOpaqueMemory(queue, image, numBindings, pBindInfo);
692 return result;
693}
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600694
695VkResult
696explicit_GetFenceStatus(
697 VkDevice device,
698 VkFence fence)
699{
700 loader_platform_thread_lock_mutex(&objLock);
701 // Warn if submitted_flag is not set
Tony Barbour2a199c12015-07-09 17:31:46 -0600702#if 0
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600703 validate_status(device, fence, VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED,
704 VK_DBG_REPORT_ERROR_BIT, OBJTRACK_INVALID_FENCE, "Status Requested for Unsubmitted Fence");
Tony Barbour2a199c12015-07-09 17:31:46 -0600705#endif
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600706 validate_object(device, device);
707 loader_platform_thread_unlock_mutex(&objLock);
708
709 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->GetFenceStatus(device, fence);
710
711 return result;
712}
713
714VkResult
715explicit_WaitForFences(
716 VkDevice device,
717 uint32_t fenceCount,
718 const VkFence *pFences,
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600719 VkBool32 waitAll,
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600720 uint64_t timeout)
721{
722 loader_platform_thread_lock_mutex(&objLock);
Tony Barbour2a199c12015-07-09 17:31:46 -0600723#if 0
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600724 // Warn if waiting on unsubmitted fence
725 for (uint32_t i = 0; i < fenceCount; i++) {
726 validate_status(device, pFences[i], VK_OBJECT_TYPE_FENCE, OBJSTATUS_FENCE_IS_SUBMITTED, OBJSTATUS_FENCE_IS_SUBMITTED,
727 VK_DBG_REPORT_ERROR_BIT, OBJTRACK_INVALID_FENCE, "Waiting for Unsubmitted Fence");
728 }
Tony Barbour2a199c12015-07-09 17:31:46 -0600729#endif
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600730 validate_object(device, device);
731 loader_platform_thread_unlock_mutex(&objLock);
732
733 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
734
735 return result;
736}
737
738VkResult
739explicit_AllocDescriptorSets(
740 VkDevice device,
741 VkDescriptorPool descriptorPool,
742 VkDescriptorSetUsage setUsage,
743 uint32_t count,
744 const VkDescriptorSetLayout *pSetLayouts,
Cody Northropc8aa4a52015-08-03 12:47:29 -0600745 VkDescriptorSet *pDescriptorSets)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600746{
747 loader_platform_thread_lock_mutex(&objLock);
748 validate_object(device, device);
749 validate_object(device, descriptorPool);
750 loader_platform_thread_unlock_mutex(&objLock);
751
752 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->AllocDescriptorSets(
Cody Northropc8aa4a52015-08-03 12:47:29 -0600753 device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600754
755 loader_platform_thread_lock_mutex(&objLock);
Cody Northropc8aa4a52015-08-03 12:47:29 -0600756 for (uint32_t i = 0; i < count; i++) {
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600757 create_obj(device, pDescriptorSets[i], VK_OBJECT_TYPE_DESCRIPTOR_SET);
758 }
759 loader_platform_thread_unlock_mutex(&objLock);
760
761 return result;
762}
763
764VkResult
Ian Elliott338dedb2015-08-21 15:09:33 -0600765explicit_DestroySwapchainKHR(
Ian Elliottb134e842015-07-06 14:31:32 -0600766 VkDevice device,
Ian Elliott338dedb2015-08-21 15:09:33 -0600767 VkSwapchainKHR swapchain)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600768{
769
770 loader_platform_thread_lock_mutex(&objLock);
Ian Elliott338dedb2015-08-21 15:09:33 -0600771 destroy_obj(device, swapchain);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600772 loader_platform_thread_unlock_mutex(&objLock);
773
Ian Elliott338dedb2015-08-21 15:09:33 -0600774 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600775
776 return result;
777}
778
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600779void
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600780explicit_FreeMemory(
781 VkDevice device,
782 VkDeviceMemory mem)
783{
784 loader_platform_thread_lock_mutex(&objLock);
785 validate_object(device, device);
786 loader_platform_thread_unlock_mutex(&objLock);
787
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600788 get_dispatch_table(ObjectTracker_device_table_map, device)->FreeMemory(device, mem);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600789
790 loader_platform_thread_lock_mutex(&objLock);
791 destroy_obj(device, mem);
792 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600793}
Tony Barbour2a199c12015-07-09 17:31:46 -0600794
Tony Barbour912e8152015-07-20 10:52:13 -0600795VkResult
796explicit_FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets)
797{
798 loader_platform_thread_lock_mutex(&objLock);
799 validate_object(device, descriptorPool);
800 validate_object(device, device);
801 loader_platform_thread_unlock_mutex(&objLock);
802 VkResult result = get_dispatch_table(ObjectTracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
803
804 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter78fc0472015-07-23 11:25:17 -0600805 for (uint32_t i=0; i<count; i++)
Tony Barbour912e8152015-07-20 10:52:13 -0600806 {
807 destroy_obj(device, *pDescriptorSets++);
808 }
809 loader_platform_thread_unlock_mutex(&objLock);
810 return result;
811}