blob: db61f7a0ceaaabbd4e3d9e7c09cb7e3f0ebf1021 [file] [log] [blame]
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
4 * Copyright (C) 2015-2016 Google Inc.
Tobin Ehlis42586532014-11-14 13:01:02 -07005 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials
11 * are furnished to do so, subject to the following conditions:
Tobin Ehlis42586532014-11-14 13:01:02 -070012 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070013 * The above copyright notice(s) and this permission notice shall be included
14 * in all copies or substantial portions of the Materials.
Tobin Ehlis42586532014-11-14 13:01:02 -070015 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070016 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Tobin Ehlis42586532014-11-14 13:01:02 -070017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 *
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23 * USE OR OTHER DEALINGS IN THE MATERIALS
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060024 *
25 * Author: Jon Ashburn <jon@lunarg.com>
26 * Author: Mark Lobodzinski <mark@lunarg.com>
27 * Author: Tobin Ehlis <tobin@lunarg.com>
Tobin Ehlis42586532014-11-14 13:01:02 -070028 */
29
David Pinedo9316d3b2015-11-06 12:54:48 -070030#include "vulkan/vk_layer.h"
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060031#include "vk_layer_extension_utils.h"
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060032#include "vk_enum_string_helper.h"
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -070033#include "vk_layer_table.h"
Mark Lobodzinskifae78852015-06-23 11:35:12 -060034
Tobin Ehlisca915872014-11-18 11:28:33 -070035// Object Tracker ERROR codes
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070036typedef enum _OBJECT_TRACK_ERROR
37{
38 OBJTRACK_NONE, // Used for INFO & other non-error messages
39 OBJTRACK_UNKNOWN_OBJECT, // Updating uses of object that's not in global object list
40 OBJTRACK_INTERNAL_ERROR, // Bug with data tracking within the layer
41 OBJTRACK_DESTROY_OBJECT_FAILED, // Couldn't find object to be destroyed
42 OBJTRACK_OBJECT_LEAK, // OBJECT was not correctly freed/destroyed
43 OBJTRACK_OBJCOUNT_MAX_EXCEEDED, // Request for Object data in excess of max obj count
44 OBJTRACK_INVALID_OBJECT, // Object used that has never been created
45 OBJTRACK_DESCRIPTOR_POOL_MISMATCH, // Descriptor Pools specified incorrectly
46 OBJTRACK_COMMAND_POOL_MISMATCH, // Command Pools specified incorrectly
Tobin Ehlisca915872014-11-18 11:28:33 -070047} OBJECT_TRACK_ERROR;
48
Tobin Ehlis91ce77e2015-01-16 08:56:30 -070049// Object Status -- used to track state of individual objects
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050050typedef VkFlags ObjectStatusFlags;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070051typedef enum _ObjectStatusFlagBits
52{
53 OBJSTATUS_NONE = 0x00000000, // No status is set
54 OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted
55 OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound
56 OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound
57 OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound
58 OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound
59 OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped
60 OBJSTATUS_COMMAND_BUFFER_SECONDARY = 0x00000040, // Command Buffer is of type SECONDARY
Mark Lobodzinski38f0db22015-05-20 17:33:47 -050061} ObjectStatusFlagBits;
Chia-I Wuf8693382015-04-16 22:02:10 +080062
Tobin Ehlis42586532014-11-14 13:01:02 -070063typedef struct _OBJTRACK_NODE {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070064 uint64_t vkObj; // Object handle
65 VkDebugReportObjectTypeEXT objType; // Object type identifier
66 ObjectStatusFlags status; // Object state
67 uint64_t parentObj; // Parent object
Tobin Ehlis42586532014-11-14 13:01:02 -070068} OBJTRACK_NODE;
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060069
Tobin Ehlis42586532014-11-14 13:01:02 -070070// prototype for extension functions
Mark Lobodzinskifae78852015-06-23 11:35:12 -060071uint64_t objTrackGetObjectCount(VkDevice device);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070072uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDebugReportObjectTypeEXT type);
Mark Lobodzinskiaae93e52015-02-09 10:20:53 -060073
Tobin Ehlisca915872014-11-18 11:28:33 -070074// Func ptr typedefs
Mark Lobodzinskifae78852015-06-23 11:35:12 -060075typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070076typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDebugReportObjectTypeEXT);
Mark Lobodzinskifae78852015-06-23 11:35:12 -060077
Cody Northrop55443ef2015-09-28 15:09:32 -060078struct layer_data {
Mark Lobodzinskifae78852015-06-23 11:35:12 -060079 debug_report_data *report_data;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070080 //TODO: put instance data here
81 VkDebugReportCallbackEXT logging_callback;
Ian Elliott1064fe32015-07-06 14:31:32 -060082 bool wsi_enabled;
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -060083 bool objtrack_extensions_enabled;
Cody Northrop55443ef2015-09-28 15:09:32 -060084
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070085 layer_data() :
86 report_data(nullptr),
87 logging_callback(VK_NULL_HANDLE),
88 wsi_enabled(false),
89 objtrack_extensions_enabled(false)
90 {};
Cody Northrop55443ef2015-09-28 15:09:32 -060091};
Mark Lobodzinskifae78852015-06-23 11:35:12 -060092
Jon Ashburn3dc39382015-09-17 10:00:32 -060093struct instExts {
94 bool wsi_enabled;
95};
96
97static std::unordered_map<void *, struct instExts> instanceExtMap;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070098static std::unordered_map<void*, layer_data *> layer_data_map;
99static device_table_map object_tracker_device_table_map;
100static instance_table_map object_tracker_instance_table_map;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600101
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600102// We need additionally validate image usage using a separate map
103// of swapchain-created images
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700104static unordered_map<uint64_t, OBJTRACK_NODE*> swapchainImageMap;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600105
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600106static long long unsigned int object_track_index = 0;
107static int objLockInitialized = 0;
108static loader_platform_thread_mutex objLock;
109
110// Objects stored in a global map w/ struct containing basic info
Tony Barboura05dbaa2015-07-09 17:31:46 -0600111// unordered_map<const void*, OBJTRACK_NODE*> objMap;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600112
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700113#define NUM_OBJECT_TYPES (VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT+1)
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600114
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700115static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
116static uint64_t numTotalObjs = 0;
117static VkQueueFamilyProperties *queueInfo = NULL;
118static uint32_t queueCount = 0;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600119
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700120template layer_data *get_my_data_ptr<layer_data>(
121 void *data_key, std::unordered_map<void *, layer_data *> &data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600122
Mark Lobodzinski2eeb3c62015-09-01 08:52:55 -0600123
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600124//
125// Internal Object Tracker Functions
126//
127
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700128static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
129{
130 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
131 VkLayerDispatchTable *pDisp = get_dispatch_table(object_tracker_device_table_map, device);
Jon Ashburn8acd2332015-09-16 18:08:32 -0600132 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700133 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
134 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
135 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
136 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
137 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
Ian Elliott1064fe32015-07-06 14:31:32 -0600138 my_device_data->wsi_enabled = false;
Jon Ashburnf19916e2016-01-11 13:12:43 -0700139 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700140 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliott1064fe32015-07-06 14:31:32 -0600141 my_device_data->wsi_enabled = true;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600142
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700143 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0)
Courtney Goeltzenleuchterfce8cd22015-07-05 22:13:43 -0600144 my_device_data->objtrack_extensions_enabled = true;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600145 }
146}
147
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700148static void createInstanceRegisterExtensions(const VkInstanceCreateInfo* pCreateInfo, VkInstance instance)
149{
Jon Ashburn3dc39382015-09-17 10:00:32 -0600150 uint32_t i;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700151 VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(object_tracker_instance_table_map, instance);
Jon Ashburn3dc39382015-09-17 10:00:32 -0600152 PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700153 pDisp->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
154 pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
155 pDisp->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
156 pDisp->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
Mark Lobodzinskie86e1382015-11-24 15:50:44 -0700157
158#if VK_USE_PLATFORM_WIN32_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700159 pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) gpa(instance, "vkCreateWin32SurfaceKHR");
160 pDisp->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700161#endif // VK_USE_PLATFORM_WIN32_KHR
162#ifdef VK_USE_PLATFORM_XCB_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700163 pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) gpa(instance, "vkCreateXcbSurfaceKHR");
164 pDisp->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700165#endif // VK_USE_PLATFORM_XCB_KHR
166#ifdef VK_USE_PLATFORM_XLIB_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700167 pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR) gpa(instance, "vkCreateXlibSurfaceKHR");
168 pDisp->GetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700169#endif // VK_USE_PLATFORM_XLIB_KHR
170#ifdef VK_USE_PLATFORM_MIR_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700171 pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR) gpa(instance, "vkCreateMirSurfaceKHR");
172 pDisp->GetPhysicalDeviceMirPresentationSupportKHR = (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700173#endif // VK_USE_PLATFORM_MIR_KHR
174#ifdef VK_USE_PLATFORM_WAYLAND_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700175 pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR) gpa(instance, "vkCreateWaylandSurfaceKHR");
176 pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700177#endif // VK_USE_PLATFORM_WAYLAND_KHR
178#ifdef VK_USE_PLATFORM_ANDROID_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700179 pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR) gpa(instance, "vkCreateAndroidSurfaceKHR");
Mark Lobodzinskia8a5f852015-12-10 16:25:21 -0700180#endif // VK_USE_PLATFORM_ANDROID_KHR
Mark Lobodzinskie86e1382015-11-24 15:50:44 -0700181
Jon Ashburn3dc39382015-09-17 10:00:32 -0600182 instanceExtMap[pDisp].wsi_enabled = false;
Jon Ashburnf19916e2016-01-11 13:12:43 -0700183 for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700184 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
Jon Ashburn3dc39382015-09-17 10:00:32 -0600185 instanceExtMap[pDisp].wsi_enabled = true;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700186
Jon Ashburn3dc39382015-09-17 10:00:32 -0600187 }
188}
189
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600190// Indicate device or instance dispatch table type
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700191typedef enum _DispTableType
192{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600193 DISP_TBL_TYPE_INSTANCE,
194 DISP_TBL_TYPE_DEVICE,
195} DispTableType;
196
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700197debug_report_data *mdd(const void* object)
198{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600199 dispatch_key key = get_dispatch_key(object);
200 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600201 return my_data->report_data;
202}
203
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700204debug_report_data *mid(VkInstance object)
205{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600206 dispatch_key key = get_dispatch_key(object);
207 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600208 return my_data->report_data;
209}
210
211// For each Queue's doubly linked-list of mem refs
212typedef struct _OT_MEM_INFO {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700213 VkDeviceMemory mem;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600214 struct _OT_MEM_INFO *pNextMI;
215 struct _OT_MEM_INFO *pPrevMI;
216
217} OT_MEM_INFO;
218
219// Track Queue information
220typedef struct _OT_QUEUE_INFO {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700221 OT_MEM_INFO *pMemRefList;
222 struct _OT_QUEUE_INFO *pNextQI;
223 uint32_t queueNodeIndex;
224 VkQueue queue;
225 uint32_t refCount;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600226} OT_QUEUE_INFO;
227
228// Global list of QueueInfo structures, one per queue
229static OT_QUEUE_INFO *g_pQueueInfo = NULL;
230
231// Convert an object type enum to an object type array index
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700232static uint32_t
233objTypeToIndex(
234 uint32_t objType)
235{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600236 uint32_t index = objType;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600237 return index;
238}
239
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600240// Add new queue to head of global queue list
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700241static void
242addQueueInfo(
243 uint32_t queueNodeIndex,
244 VkQueue queue)
245{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600246 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
247
248 if (pQueueInfo != NULL) {
249 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700250 pQueueInfo->queue = queue;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600251 pQueueInfo->queueNodeIndex = queueNodeIndex;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700252 pQueueInfo->pNextQI = g_pQueueInfo;
253 g_pQueueInfo = pQueueInfo;
254 }
255 else {
256 log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, reinterpret_cast<uint64_t>(queue), __LINE__, OBJTRACK_INTERNAL_ERROR, "OBJTRACK",
257 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600258 }
259}
260
261// Destroy memRef lists and free all memory
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700262static void
263destroyQueueMemRefLists(void)
264{
265 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600266 OT_QUEUE_INFO *pDelQueueInfo = NULL;
267 while (pQueueInfo != NULL) {
268 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
269 while (pMemInfo != NULL) {
270 OT_MEM_INFO *pDelMemInfo = pMemInfo;
271 pMemInfo = pMemInfo->pNextMI;
272 delete pDelMemInfo;
273 }
274 pDelQueueInfo = pQueueInfo;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700275 pQueueInfo = pQueueInfo->pNextQI;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600276 delete pDelQueueInfo;
277 }
278 g_pQueueInfo = pQueueInfo;
279}
280
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700281static void
282setGpuQueueInfoState(
283 uint32_t count,
284 void *pData)
285{
Tony Barbour59a47322015-06-24 16:06:58 -0600286 queueCount = count;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700287 queueInfo = (VkQueueFamilyProperties*)realloc((void*)queueInfo, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600288 if (queueInfo != NULL) {
Cody Northropd0802882015-08-03 17:04:53 -0600289 memcpy(queueInfo, pData, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600290 }
291}
292
293// Check Queue type flags for selected queue operations
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700294static void
295validateQueueFlags(
296 VkQueue queue,
297 const char *function)
298{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600299 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
300 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
301 pQueueInfo = pQueueInfo->pNextQI;
302 }
303 if (pQueueInfo != NULL) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700304 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
305 log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, reinterpret_cast<uint64_t>(queue), __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
306 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600307 }
308 }
309}
310
Tony Barboura05dbaa2015-07-09 17:31:46 -0600311/* TODO: Port to new type safety */
312#if 0
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600313// Check object status for selected flag state
Courtney Goeltzenleuchtercd2a0992015-07-09 11:44:38 -0600314static VkBool32
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600315validate_status(
316 VkObject dispatchable_object,
317 VkObject vkObj,
318 VkObjectType objType,
319 ObjectStatusFlags status_mask,
320 ObjectStatusFlags status_flag,
321 VkFlags msg_flags,
322 OBJECT_TRACK_ERROR error_code,
323 const char *fail_msg)
324{
325 if (objMap.find(vkObj) != objMap.end()) {
326 OBJTRACK_NODE* pNode = objMap[vkObj];
327 if ((pNode->status & status_mask) != status_flag) {
328 char str[1024];
Mark Lobodzinski6085c2b2016-01-04 15:48:11 -0700329 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600330 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
Mark Young93ecb1d2016-01-13 13:47:16 -0700331 static_cast<uint64_t>(vkObj), fail_msg);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600332 return VK_FALSE;
333 }
334 return VK_TRUE;
335 }
336 else {
337 // If we do not find it print an error
Mark Lobodzinski6085c2b2016-01-04 15:48:11 -0700338 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600339 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Mark Young93ecb1d2016-01-13 13:47:16 -0700340 static_cast<uint64_t>(vkObj), string_VkObjectType(objType));
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600341 return VK_FALSE;
342 }
343}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600344#endif
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600345
346#include "vk_dispatch_table_helper.h"
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700347static void
348initObjectTracker(
349 layer_data *my_data,
350 const VkAllocationCallbacks *pAllocator)
351{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600352 uint32_t report_flags = 0;
353 uint32_t debug_action = 0;
354 FILE *log_output = NULL;
355 const char *option_str;
Mark Lobodzinski8cbde242016-02-23 09:58:39 -0700356 // initialize object_tracker options
357 report_flags = getLayerOptionFlags("lunarg_object_tracker.report_flags", 0);
358 getLayerOptionEnum("lunarg_object_tracker.debug_action", (uint32_t *) &debug_action);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600359
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700360 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
361 {
Mark Lobodzinski8cbde242016-02-23 09:58:39 -0700362 option_str = getLayerOption("lunarg_object_tracker.log_filename");
363 log_output = getLayerLogOutput(option_str, "lunarg_object_tracker");
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700364 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700365 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700366 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700367 dbgInfo.pfnCallback = log_callback;
368 dbgInfo.pUserData = log_output;
369 dbgInfo.flags = report_flags;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700370 layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &my_data->logging_callback);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600371 }
372
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700373 if (!objLockInitialized)
374 {
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600375 // TODO/TBD: Need to delete this mutex sometime. How??? One
376 // suggestion is to call this during vkCreateInstance(), and then we
377 // can clean it up during vkDestroyInstance(). However, that requires
378 // that the layer have per-instance locks. We need to come back and
379 // address this soon.
380 loader_platform_thread_create_mutex(&objLock);
381 objLockInitialized = 1;
382 }
383}
384
Tony Barboura05dbaa2015-07-09 17:31:46 -0600385//
386// Forward declares of generated routines
387//
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600388
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700389static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeEXT objType);
390static void create_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType);
391static void create_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
392static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeEXT objType);
393static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
394static VkBool32 validate_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
395static VkBool32 validate_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
396static VkBool32 validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
397static VkBool32 validate_descriptor_set_layout(VkDevice dispatchable_object, VkDescriptorSetLayout object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
398static VkBool32 validate_command_pool(VkDevice dispatchable_object, VkCommandPool object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
399static VkBool32 validate_buffer(VkQueue dispatchable_object, VkBuffer object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
400static void create_pipeline(VkDevice dispatchable_object, VkPipeline vkObj, VkDebugReportObjectTypeEXT objType);
401static VkBool32 validate_pipeline_cache(VkDevice dispatchable_object, VkPipelineCache object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
402static VkBool32 validate_render_pass(VkDevice dispatchable_object, VkRenderPass object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
403static VkBool32 validate_shader_module(VkDevice dispatchable_object, VkShaderModule object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
404static VkBool32 validate_pipeline_layout(VkDevice dispatchable_object, VkPipelineLayout object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
405static VkBool32 validate_pipeline(VkDevice dispatchable_object, VkPipeline object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
406static void destroy_command_pool(VkDevice dispatchable_object, VkCommandPool object);
407static void destroy_command_buffer(VkCommandBuffer dispatchable_object, VkCommandBuffer object);
408static void destroy_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
409static void destroy_descriptor_set(VkDevice dispatchable_object, VkDescriptorSet object);
410static void destroy_device_memory(VkDevice dispatchable_object, VkDeviceMemory object);
411static void destroy_swapchain_khr(VkDevice dispatchable_object, VkSwapchainKHR object);
412static VkBool32 set_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeEXT objType, ObjectStatusFlags status_flag);
413static VkBool32 reset_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeEXT objType, ObjectStatusFlags status_flag);
Tony Barboura05dbaa2015-07-09 17:31:46 -0600414#if 0
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700415static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDebugReportObjectTypeEXT objType,
Tony Barboura05dbaa2015-07-09 17:31:46 -0600416 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
417 const char *fail_msg);
418#endif
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700419extern unordered_map<uint64_t, OBJTRACK_NODE*> VkPhysicalDeviceMap;
420extern unordered_map<uint64_t, OBJTRACK_NODE*> VkImageMap;
421extern unordered_map<uint64_t, OBJTRACK_NODE*> VkQueueMap;
422extern unordered_map<uint64_t, OBJTRACK_NODE*> VkDescriptorSetMap;
423extern unordered_map<uint64_t, OBJTRACK_NODE*> VkBufferMap;
424extern unordered_map<uint64_t, OBJTRACK_NODE*> VkFenceMap;
425extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSemaphoreMap;
426extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandPoolMap;
427extern unordered_map<uint64_t, OBJTRACK_NODE*> VkCommandBufferMap;
428extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSwapchainKHRMap;
429extern unordered_map<uint64_t, OBJTRACK_NODE*> VkSurfaceKHRMap;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600430
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700431static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeEXT objType)
432{
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700433 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700434 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeEXT(objType),
435 reinterpret_cast<uint64_t>(vkObj));
Tobin Ehlisec598302015-09-15 15:02:17 -0600436
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700437 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
Tobin Ehlisec598302015-09-15 15:02:17 -0600438 pNewObjNode->objType = objType;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700439 pNewObjNode->status = OBJSTATUS_NONE;
440 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800441 VkPhysicalDeviceMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600442 uint32_t objIndex = objTypeToIndex(objType);
443 numObjs[objIndex]++;
444 numTotalObjs++;
445}
446
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700447static void create_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR vkObj, VkDebugReportObjectTypeEXT objType)
448{
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700449 // TODO: Add tracking of surface objects
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700450 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700451 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeEXT(objType),
452 (uint64_t)(vkObj));
Tobin Ehlis86684f92016-01-05 10:33:58 -0700453
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700454 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
Tobin Ehlis86684f92016-01-05 10:33:58 -0700455 pNewObjNode->objType = objType;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700456 pNewObjNode->status = OBJSTATUS_NONE;
457 pNewObjNode->vkObj = (uint64_t)(vkObj);
Tobin Ehlis86684f92016-01-05 10:33:58 -0700458 VkSurfaceKHRMap[(uint64_t)vkObj] = pNewObjNode;
459 uint32_t objIndex = objTypeToIndex(objType);
460 numObjs[objIndex]++;
461 numTotalObjs++;
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700462}
463
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700464static void destroy_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR object)
465{
Mark Young93ecb1d2016-01-13 13:47:16 -0700466 uint64_t object_handle = (uint64_t)(object);
Tobin Ehlis86684f92016-01-05 10:33:58 -0700467 if (VkSurfaceKHRMap.find(object_handle) != VkSurfaceKHRMap.end()) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700468 OBJTRACK_NODE* pNode = VkSurfaceKHRMap[(uint64_t)object];
Tobin Ehlis86684f92016-01-05 10:33:58 -0700469 uint32_t objIndex = objTypeToIndex(pNode->objType);
470 assert(numTotalObjs > 0);
471 numTotalObjs--;
472 assert(numObjs[objIndex] > 0);
473 numObjs[objIndex]--;
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700474 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700475 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
476 string_VkDebugReportObjectTypeEXT(pNode->objType), (uint64_t)(object), numTotalObjs, numObjs[objIndex],
477 string_VkDebugReportObjectTypeEXT(pNode->objType));
Tobin Ehlis86684f92016-01-05 10:33:58 -0700478 delete pNode;
479 VkSurfaceKHRMap.erase(object_handle);
480 } else {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700481 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT ) 0, object_handle, __LINE__, OBJTRACK_NONE, "OBJTRACK",
482 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
483 object_handle);
Tobin Ehlis86684f92016-01-05 10:33:58 -0700484 }
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -0700485}
486
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700487static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer vkObj, VkDebugReportObjectTypeEXT objType, VkCommandBufferLevel level)
488{
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700489 log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700490 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeEXT(objType),
491 reinterpret_cast<uint64_t>(vkObj));
Tony Barboura05dbaa2015-07-09 17:31:46 -0600492
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700493 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
494 pNewObjNode->objType = objType;
495 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
496 pNewObjNode->parentObj = (uint64_t) commandPool;
Mark Lobodzinski2fba0322016-01-23 18:31:23 -0700497 if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
498 pNewObjNode->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
499 } else {
500 pNewObjNode->status = OBJSTATUS_NONE;
501 }
Michael Lentine13803dc2015-11-04 14:35:12 -0800502 VkCommandBufferMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barboura05dbaa2015-07-09 17:31:46 -0600503 uint32_t objIndex = objTypeToIndex(objType);
504 numObjs[objIndex]++;
505 numTotalObjs++;
506}
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700507
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700508static void free_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer)
509{
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700510 uint64_t object_handle = reinterpret_cast<uint64_t>(commandBuffer);
511 if (VkCommandBufferMap.find(object_handle) != VkCommandBufferMap.end()) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700512 OBJTRACK_NODE* pNode = VkCommandBufferMap[(uint64_t)commandBuffer];
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700513
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700514 if (pNode->parentObj != (uint64_t)(commandPool)) {
515 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_COMMAND_POOL_MISMATCH, "OBJTRACK",
516 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
517 reinterpret_cast<uint64_t>(commandBuffer), pNode->parentObj, (uint64_t)(commandPool));
518 } else {
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700519
520 uint32_t objIndex = objTypeToIndex(pNode->objType);
521 assert(numTotalObjs > 0);
522 numTotalObjs--;
523 assert(numObjs[objIndex] > 0);
524 numObjs[objIndex]--;
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700525 log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700526 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
527 string_VkDebugReportObjectTypeEXT(pNode->objType), reinterpret_cast<uint64_t>(commandBuffer), numTotalObjs, numObjs[objIndex],
528 string_VkDebugReportObjectTypeEXT(pNode->objType));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700529 delete pNode;
530 VkCommandBufferMap.erase(object_handle);
531 }
532 } else {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700533 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT) 0, object_handle, __LINE__, OBJTRACK_NONE, "OBJTRACK",
534 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
535 object_handle);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700536 }
537}
538
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700539static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet vkObj, VkDebugReportObjectTypeEXT objType)
540{
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700541 log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700542 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeEXT(objType),
543 (uint64_t)(vkObj));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700544
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700545 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
546 pNewObjNode->objType = objType;
547 pNewObjNode->status = OBJSTATUS_NONE;
548 pNewObjNode->vkObj = (uint64_t)(vkObj);
549 pNewObjNode->parentObj = (uint64_t) descriptorPool;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700550 VkDescriptorSetMap[(uint64_t)vkObj] = pNewObjNode;
551 uint32_t objIndex = objTypeToIndex(objType);
552 numObjs[objIndex]++;
553 numTotalObjs++;
554}
555
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700556static void free_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet descriptorSet)
557{
Mark Young93ecb1d2016-01-13 13:47:16 -0700558 uint64_t object_handle = (uint64_t)(descriptorSet);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700559 if (VkDescriptorSetMap.find(object_handle) != VkDescriptorSetMap.end()) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700560 OBJTRACK_NODE* pNode = VkDescriptorSetMap[(uint64_t)descriptorSet];
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700561
Mark Young93ecb1d2016-01-13 13:47:16 -0700562 if (pNode->parentObj != (uint64_t)(descriptorPool)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700563 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_DESCRIPTOR_POOL_MISMATCH, "OBJTRACK",
564 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
565 (uint64_t)(descriptorSet), pNode->parentObj, (uint64_t)(descriptorPool));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700566 } else {
567 uint32_t objIndex = objTypeToIndex(pNode->objType);
568 assert(numTotalObjs > 0);
569 numTotalObjs--;
570 assert(numObjs[objIndex] > 0);
571 numObjs[objIndex]--;
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700572 log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700573 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
574 string_VkDebugReportObjectTypeEXT(pNode->objType), (uint64_t)(descriptorSet), numTotalObjs, numObjs[objIndex],
575 string_VkDebugReportObjectTypeEXT(pNode->objType));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700576 delete pNode;
577 VkDescriptorSetMap.erase(object_handle);
578 }
579 } else {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700580 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT) 0, object_handle, __LINE__, OBJTRACK_NONE, "OBJTRACK",
581 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
582 object_handle);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700583 }
584}
585
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700586static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeEXT objType)
587{
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700588 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700589 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, string_VkDebugReportObjectTypeEXT(objType),
590 reinterpret_cast<uint64_t>(vkObj));
Tobin Ehlisec598302015-09-15 15:02:17 -0600591
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700592 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
Tobin Ehlisec598302015-09-15 15:02:17 -0600593 pNewObjNode->objType = objType;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700594 pNewObjNode->status = OBJSTATUS_NONE;
595 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine13803dc2015-11-04 14:35:12 -0800596 VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlisec598302015-09-15 15:02:17 -0600597 uint32_t objIndex = objTypeToIndex(objType);
598 numObjs[objIndex]++;
599 numTotalObjs++;
600}
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700601static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain)
602{
Mark Lobodzinski510e20d2016-02-11 09:26:16 -0700603 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t) vkObj, __LINE__, OBJTRACK_NONE, "OBJTRACK",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700604 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64 , object_track_index++, "SwapchainImage",
605 (uint64_t)(vkObj));
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600606
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700607 OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
608 pNewObjNode->objType = VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT;
609 pNewObjNode->status = OBJSTATUS_NONE;
610 pNewObjNode->vkObj = (uint64_t) vkObj;
611 pNewObjNode->parentObj = (uint64_t) swapchain;
Mark Young93ecb1d2016-01-13 13:47:16 -0700612 swapchainImageMap[(uint64_t)(vkObj)] = pNewObjNode;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600613}
614
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600615//
616// Non-auto-generated API functions called by generated code
617//
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700618VkResult
619explicit_CreateInstance(
620 const VkInstanceCreateInfo *pCreateInfo,
621 const VkAllocationCallbacks *pAllocator,
622 VkInstance *pInstance)
623{
624 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
David Pinedoc0fa1ab2015-07-31 10:46:25 -0600625
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700626 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700627 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
628 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700629 if (fpCreateInstance == NULL) {
630 return VK_ERROR_INITIALIZATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600631 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700632
633 // Advance the link info for the next element on the chain
634 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
635
636 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
637 if (result != VK_SUCCESS) {
638 return result;
639 }
640
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700641 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
642 initInstanceTable(*pInstance, fpGetInstanceProcAddr, object_tracker_instance_table_map);
643 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, *pInstance);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700644
645 my_data->report_data = debug_report_create_instance(
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700646 pInstanceTable,
647 *pInstance,
648 pCreateInfo->enabledExtensionCount,
649 pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700650
651 initObjectTracker(my_data, pAllocator);
652 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
653
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700654 create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700655
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600656 return result;
657}
658
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700659void
660explicit_GetPhysicalDeviceQueueFamilyProperties(
661 VkPhysicalDevice gpu,
662 uint32_t* pCount,
663 VkQueueFamilyProperties* pProperties)
664{
665 get_dispatch_table(object_tracker_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
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700673VkResult
674explicit_CreateDevice(
675 VkPhysicalDevice gpu,
676 const VkDeviceCreateInfo *pCreateInfo,
677 const VkAllocationCallbacks *pAllocator,
678 VkDevice *pDevice)
679{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600680 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700681 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700682
683 assert(chain_info->u.pLayerInfo);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700684 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
685 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
686 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(NULL, "vkCreateDevice");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700687 if (fpCreateDevice == NULL) {
688 loader_platform_thread_unlock_mutex(&objLock);
689 return VK_ERROR_INITIALIZATION_FAILED;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600690 }
691
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700692 // Advance the link info for the next element on the chain
693 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
694
695 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
696 if (result != VK_SUCCESS) {
697 loader_platform_thread_unlock_mutex(&objLock);
698 return result;
699 }
700
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700701 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
702 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
703 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700704
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700705 initDeviceTable(*pDevice, fpGetDeviceProcAddr, object_tracker_device_table_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -0700706
707 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
708
709 create_device(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
710
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600711 loader_platform_thread_unlock_mutex(&objLock);
712 return result;
713}
714
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700715VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
716{
Tobin Ehlisec598302015-09-15 15:02:17 -0600717 VkBool32 skipCall = VK_FALSE;
718 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700719 skipCall |= validate_instance(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
Tobin Ehlisec598302015-09-15 15:02:17 -0600720 loader_platform_thread_unlock_mutex(&objLock);
721 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700722 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700723 VkResult result = get_dispatch_table(object_tracker_instance_table_map, instance)->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Tobin Ehlisec598302015-09-15 15:02:17 -0600724 loader_platform_thread_lock_mutex(&objLock);
725 if (result == VK_SUCCESS) {
726 if (pPhysicalDevices) {
727 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700728 create_physical_device(instance, pPhysicalDevices[i], VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT);
Tobin Ehlisec598302015-09-15 15:02:17 -0600729 }
730 }
731 }
732 loader_platform_thread_unlock_mutex(&objLock);
733 return result;
734}
735
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700736void
737explicit_GetDeviceQueue(
738 VkDevice device,
739 uint32_t queueNodeIndex,
740 uint32_t queueIndex,
741 VkQueue *pQueue)
742{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600743 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700744 validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600745 loader_platform_thread_unlock_mutex(&objLock);
746
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700747 get_dispatch_table(object_tracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600748
749 loader_platform_thread_lock_mutex(&objLock);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600750 addQueueInfo(queueNodeIndex, *pQueue);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700751 create_queue(device, *pQueue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600752 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600753}
754
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700755VkResult
756explicit_MapMemory(
757 VkDevice device,
758 VkDeviceMemory mem,
759 VkDeviceSize offset,
760 VkDeviceSize size,
761 VkFlags flags,
762 void **ppData)
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);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700766 skipCall |= set_device_memory_status(device, mem, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, OBJSTATUS_GPU_MEM_MAPPED);
767 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
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)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700770 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600771
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700772 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600773
774 return result;
775}
776
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700777void
778explicit_UnmapMemory(
779 VkDevice device,
780 VkDeviceMemory mem)
781{
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600782 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600783 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700784 skipCall |= reset_device_memory_status(device, mem, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, OBJSTATUS_GPU_MEM_MAPPED);
785 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600786 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisc9ac2b62015-09-11 12:57:55 -0600787 if (skipCall == VK_TRUE)
788 return;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600789
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700790 get_dispatch_table(object_tracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600791}
792
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700793VkResult
794explicit_QueueBindSparse(
795 VkQueue queue,
796 uint32_t bindInfoCount,
797 const VkBindSparseInfo* pBindInfo,
798 VkFence fence)
799{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600800 loader_platform_thread_lock_mutex(&objLock);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800801 validateQueueFlags(queue, "QueueBindSparse");
802
803 for (uint32_t i = 0; i < bindInfoCount; i++) {
804 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700805 validate_buffer(queue, pBindInfo[i].pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800806 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700807 validate_image(queue, pBindInfo[i].pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800808 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700809 validate_image(queue, pBindInfo[i].pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +0800810 }
811
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600812 loader_platform_thread_unlock_mutex(&objLock);
813
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700814 VkResult result = get_dispatch_table(object_tracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski16e8bef2015-07-03 15:58:09 -0600815 return result;
816}
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600817
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700818VkResult
819explicit_AllocateCommandBuffers(
820 VkDevice device,
821 const VkCommandBufferAllocateInfo *pAllocateInfo,
822 VkCommandBuffer* pCommandBuffers)
823{
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700824 VkBool32 skipCall = VK_FALSE;
825 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700826 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
827 skipCall |= validate_command_pool(device, pAllocateInfo->commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700828 loader_platform_thread_unlock_mutex(&objLock);
829
830 if (skipCall) {
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700831 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700832 }
833
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700834 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)->AllocateCommandBuffers(
835 device, pAllocateInfo, pCommandBuffers);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700836
837 loader_platform_thread_lock_mutex(&objLock);
Jon Ashburnf19916e2016-01-11 13:12:43 -0700838 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700839 alloc_command_buffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, pAllocateInfo->level);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700840 }
841 loader_platform_thread_unlock_mutex(&objLock);
842
843 return result;
844}
845
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700846VkResult
847explicit_AllocateDescriptorSets(
848 VkDevice device,
849 const VkDescriptorSetAllocateInfo *pAllocateInfo,
850 VkDescriptorSet *pDescriptorSets)
851{
Tobin Ehlisec598302015-09-15 15:02:17 -0600852 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600853 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700854 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
855 skipCall |= validate_descriptor_pool(device, pAllocateInfo->descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
Jon Ashburnf19916e2016-01-11 13:12:43 -0700856 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700857 skipCall |= validate_descriptor_set_layout(device, pAllocateInfo->pSetLayouts[i], VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
Tobin Ehlisec598302015-09-15 15:02:17 -0600858 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600859 loader_platform_thread_unlock_mutex(&objLock);
Tobin Ehlisec598302015-09-15 15:02:17 -0600860 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700861 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600862
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700863 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)->AllocateDescriptorSets(
864 device, pAllocateInfo, pDescriptorSets);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600865
Chris Forbes539a87c2016-01-22 15:44:40 +1300866 if (VK_SUCCESS == result) {
867 loader_platform_thread_lock_mutex(&objLock);
868 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700869 alloc_descriptor_set(device, pAllocateInfo->descriptorPool, pDescriptorSets[i], VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
Chris Forbes539a87c2016-01-22 15:44:40 +1300870 }
871 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600872 }
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600873
874 return result;
875}
876
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700877void
878explicit_FreeCommandBuffers(
879 VkDevice device,
880 VkCommandPool commandPool,
881 uint32_t commandBufferCount,
882 const VkCommandBuffer *pCommandBuffers)
883{
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700884 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700885 validate_command_pool(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
886 validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700887 loader_platform_thread_unlock_mutex(&objLock);
888
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700889 get_dispatch_table(object_tracker_device_table_map, device)->FreeCommandBuffers(device,
890 commandPool, commandBufferCount, pCommandBuffers);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700891
892 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700893 for (uint32_t i = 0; i < commandBufferCount; i++)
894 {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800895 free_command_buffer(device, commandPool, *pCommandBuffers);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700896 pCommandBuffers++;
897 }
898 loader_platform_thread_unlock_mutex(&objLock);
899}
900
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700901void
902explicit_DestroySwapchainKHR(
903 VkDevice device,
904 VkSwapchainKHR swapchain,
905 const VkAllocationCallbacks *pAllocator)
906{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600907 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700908 // A swapchain's images are implicitly deleted when the swapchain is deleted.
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600909 // Remove this swapchain's images from our map of such images.
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700910 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = swapchainImageMap.begin();
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600911 while (itr != swapchainImageMap.end()) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700912 OBJTRACK_NODE* pNode = (*itr).second;
Mark Young93ecb1d2016-01-13 13:47:16 -0700913 if (pNode->parentObj == (uint64_t)(swapchain)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700914 swapchainImageMap.erase(itr++);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600915 } else {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700916 ++itr;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600917 }
918 }
Tobin Ehlis86684f92016-01-05 10:33:58 -0700919 destroy_swapchain_khr(device, swapchain);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600920 loader_platform_thread_unlock_mutex(&objLock);
921
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700922 get_dispatch_table(object_tracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600923}
924
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700925void
926explicit_FreeMemory(
927 VkDevice device,
928 VkDeviceMemory mem,
929 const VkAllocationCallbacks* pAllocator)
930{
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600931 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700932 validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600933 loader_platform_thread_unlock_mutex(&objLock);
934
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700935 get_dispatch_table(object_tracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600936
937 loader_platform_thread_lock_mutex(&objLock);
Michael Lentine13803dc2015-11-04 14:35:12 -0800938 destroy_device_memory(device, mem);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600939 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinskifae78852015-06-23 11:35:12 -0600940}
Tony Barboura05dbaa2015-07-09 17:31:46 -0600941
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700942VkResult
943explicit_FreeDescriptorSets(
944 VkDevice device,
945 VkDescriptorPool descriptorPool,
946 uint32_t count,
947 const VkDescriptorSet *pDescriptorSets)
948{
Tony Barbour770f80d2015-07-20 10:52:13 -0600949 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700950 validate_descriptor_pool(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
951 validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Tony Barbour770f80d2015-07-20 10:52:13 -0600952 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700953 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
Tony Barbour770f80d2015-07-20 10:52:13 -0600954
955 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700956 for (uint32_t i=0; i<count; i++)
957 {
Michael Lentinefc6aa762015-11-20 12:11:42 -0800958 free_descriptor_set(device, descriptorPool, *pDescriptorSets++);
Tony Barbour770f80d2015-07-20 10:52:13 -0600959 }
960 loader_platform_thread_unlock_mutex(&objLock);
961 return result;
962}
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -0600963
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700964void
965explicit_DestroyDescriptorPool(
966 VkDevice device,
967 VkDescriptorPool descriptorPool,
968 const VkAllocationCallbacks *pAllocator)
969{
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700970 VkBool32 skipCall = VK_FALSE;
971 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700972 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
973 skipCall |= validate_descriptor_pool(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700974 loader_platform_thread_unlock_mutex(&objLock);
975 if (skipCall) {
976 return;
977 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700978 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700979 // Remove this pool's descriptor sets from our descriptorSet map.
980 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700981 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkDescriptorSetMap.begin();
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700982 while (itr != VkDescriptorSetMap.end()) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700983 OBJTRACK_NODE* pNode = (*itr).second;
Mark Lobodzinskib29731a2015-11-18 11:01:02 -0700984 auto del_itr = itr++;
Mark Young93ecb1d2016-01-13 13:47:16 -0700985 if (pNode->parentObj == (uint64_t)(descriptorPool)) {
986 destroy_descriptor_set(device, (VkDescriptorSet)((*del_itr).first));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700987 }
988 }
989 destroy_descriptor_pool(device, descriptorPool);
990 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700991 get_dispatch_table(object_tracker_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -0700992}
993
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700994void
995explicit_DestroyCommandPool(
996 VkDevice device,
997 VkCommandPool commandPool,
998 const VkAllocationCallbacks *pAllocator)
999{
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001000 VkBool32 skipCall = VK_FALSE;
1001 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001002 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
1003 skipCall |= validate_command_pool(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001004 loader_platform_thread_unlock_mutex(&objLock);
1005 if (skipCall) {
1006 return;
1007 }
1008 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001009 // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001010 // Remove this pool's cmdBuffers from our cmd buffer map.
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001011 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator itr = VkCommandBufferMap.begin();
1012 unordered_map<uint64_t, OBJTRACK_NODE*>::iterator del_itr;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001013 while (itr != VkCommandBufferMap.end()) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001014 OBJTRACK_NODE* pNode = (*itr).second;
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001015 del_itr = itr++;
Mark Young93ecb1d2016-01-13 13:47:16 -07001016 if (pNode->parentObj == (uint64_t)(commandPool)) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001017 destroy_command_buffer(reinterpret_cast<VkCommandBuffer>((*del_itr).first),
1018 reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001019 }
1020 }
1021 destroy_command_pool(device, commandPool);
1022 loader_platform_thread_unlock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001023 get_dispatch_table(object_tracker_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
Mark Lobodzinski5f5c0e12015-11-12 16:02:35 -07001024}
1025
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001026VkResult
1027explicit_GetSwapchainImagesKHR(
1028 VkDevice device,
1029 VkSwapchainKHR swapchain,
1030 uint32_t *pCount,
1031 VkImage *pSwapchainImages)
1032{
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001033 VkBool32 skipCall = VK_FALSE;
1034 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001035 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001036 loader_platform_thread_unlock_mutex(&objLock);
1037 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001038 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001039
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001040 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
Mark Lobodzinskie6d3f2c2015-10-14 13:16:33 -06001041
1042 if (pSwapchainImages != NULL) {
1043 loader_platform_thread_lock_mutex(&objLock);
1044 for (uint32_t i = 0; i < *pCount; i++) {
1045 create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
1046 }
1047 loader_platform_thread_unlock_mutex(&objLock);
1048 }
1049 return result;
1050}
1051
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001052// TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
1053VkResult
1054explicit_CreateGraphicsPipelines(
1055 VkDevice device,
1056 VkPipelineCache pipelineCache,
1057 uint32_t createInfoCount,
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001058 const VkGraphicsPipelineCreateInfo *pCreateInfos,
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001059 const VkAllocationCallbacks *pAllocator,
1060 VkPipeline *pPipelines)
1061{
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001062 VkBool32 skipCall = VK_FALSE;
1063 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001064 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001065 if (pCreateInfos) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001066 for (uint32_t idx0=0; idx0<createInfoCount; ++idx0) {
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001067 if (pCreateInfos[idx0].basePipelineHandle) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001068 skipCall |= validate_pipeline(device, pCreateInfos[idx0].basePipelineHandle, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001069 }
1070 if (pCreateInfos[idx0].layout) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001071 skipCall |= validate_pipeline_layout(device, pCreateInfos[idx0].layout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001072 }
1073 if (pCreateInfos[idx0].pStages) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001074 for (uint32_t idx1=0; idx1<pCreateInfos[idx0].stageCount; ++idx1) {
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001075 if (pCreateInfos[idx0].pStages[idx1].module) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001076 skipCall |= validate_shader_module(device, pCreateInfos[idx0].pStages[idx1].module, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001077 }
1078 }
1079 }
1080 if (pCreateInfos[idx0].renderPass) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001081 skipCall |= validate_render_pass(device, pCreateInfos[idx0].renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001082 }
1083 }
1084 }
1085 if (pipelineCache) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001086 skipCall |= validate_pipeline_cache(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001087 }
1088 loader_platform_thread_unlock_mutex(&objLock);
1089 if (skipCall)
1090 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001091 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001092 loader_platform_thread_lock_mutex(&objLock);
1093 if (result == VK_SUCCESS) {
1094 for (uint32_t idx2 = 0; idx2 < createInfoCount; ++idx2) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001095 create_pipeline(device, pPipelines[idx2], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001096 }
1097 }
1098 loader_platform_thread_unlock_mutex(&objLock);
1099 return result;
1100}
1101
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001102// TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
1103VkResult
1104explicit_CreateComputePipelines(
1105 VkDevice device,
1106 VkPipelineCache pipelineCache,
1107 uint32_t createInfoCount,
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001108 const VkComputePipelineCreateInfo *pCreateInfos,
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001109 const VkAllocationCallbacks *pAllocator,
1110 VkPipeline *pPipelines)
1111{
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001112 VkBool32 skipCall = VK_FALSE;
1113 loader_platform_thread_lock_mutex(&objLock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001114 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001115 if (pCreateInfos) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001116 for (uint32_t idx0=0; idx0<createInfoCount; ++idx0) {
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001117 if (pCreateInfos[idx0].basePipelineHandle) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001118 skipCall |= validate_pipeline(device, pCreateInfos[idx0].basePipelineHandle, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001119 }
1120 if (pCreateInfos[idx0].layout) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001121 skipCall |= validate_pipeline_layout(device, pCreateInfos[idx0].layout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001122 }
1123 if (pCreateInfos[idx0].stage.module) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001124 skipCall |= validate_shader_module(device, pCreateInfos[idx0].stage.module, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001125 }
1126 }
1127 }
1128 if (pipelineCache) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001129 skipCall |= validate_pipeline_cache(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001130 }
1131 loader_platform_thread_unlock_mutex(&objLock);
1132 if (skipCall)
1133 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001134 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001135 loader_platform_thread_lock_mutex(&objLock);
1136 if (result == VK_SUCCESS) {
1137 for (uint32_t idx1 = 0; idx1 < createInfoCount; ++idx1) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001138 create_pipeline(device, pPipelines[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
Mark Lobodzinski154329b2016-01-26 09:55:28 -07001139 }
1140 }
1141 loader_platform_thread_unlock_mutex(&objLock);
1142 return result;
1143}