blob: b2cda909179a537265f21f4cd5db51fde945f94c [file] [log] [blame]
Mark Lobodzinski288e4f72016-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 Ehlisacab8882014-11-14 13:01:02 -07005 *
Mark Lobodzinski288e4f72016-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 Ehlisacab8882014-11-14 13:01:02 -070012 *
Mark Lobodzinski288e4f72016-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 Ehlisacab8882014-11-14 13:01:02 -070015 *
Mark Lobodzinski288e4f72016-02-02 15:55:36 -070016 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Tobin Ehlisacab8882014-11-14 13:01:02 -070017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Mark Lobodzinski288e4f72016-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 Goeltzenleuchter96cd7952015-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 Ehlisacab8882014-11-14 13:01:02 -070028 */
29
Jeremy Hayes241a2db2016-04-13 10:54:17 -060030#include <mutex>
31
David Pinedo329ca9e2015-11-06 12:54:48 -070032#include "vulkan/vk_layer.h"
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -060033#include "vk_layer_extension_utils.h"
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060034#include "vk_enum_string_helper.h"
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -070035#include "vk_layer_table.h"
Mark Lobodzinskid11c4ee2016-03-15 14:21:59 -060036#include "vk_layer_utils.h"
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060037
Tobin Ehlis3c26a542014-11-18 11:28:33 -070038// Object Tracker ERROR codes
Jon Ashburn491a3cd2016-03-08 17:48:44 -070039typedef enum _OBJECT_TRACK_ERROR {
40 OBJTRACK_NONE, // Used for INFO & other non-error messages
41 OBJTRACK_UNKNOWN_OBJECT, // Updating uses of object that's not in global object list
42 OBJTRACK_INTERNAL_ERROR, // Bug with data tracking within the layer
43 OBJTRACK_DESTROY_OBJECT_FAILED, // Couldn't find object to be destroyed
44 OBJTRACK_OBJECT_LEAK, // OBJECT was not correctly freed/destroyed
45 OBJTRACK_OBJCOUNT_MAX_EXCEEDED, // Request for Object data in excess of max obj count
46 OBJTRACK_INVALID_OBJECT, // Object used that has never been created
47 OBJTRACK_DESCRIPTOR_POOL_MISMATCH, // Descriptor Pools specified incorrectly
48 OBJTRACK_COMMAND_POOL_MISMATCH, // Command Pools specified incorrectly
Tobin Ehlis3c26a542014-11-18 11:28:33 -070049} OBJECT_TRACK_ERROR;
50
Tobin Ehlis235c20e2015-01-16 08:56:30 -070051// Object Status -- used to track state of individual objects
Mark Lobodzinski7d2d5ac2015-05-20 17:33:47 -050052typedef VkFlags ObjectStatusFlags;
Jon Ashburn491a3cd2016-03-08 17:48:44 -070053typedef enum _ObjectStatusFlagBits {
54 OBJSTATUS_NONE = 0x00000000, // No status is set
55 OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted
56 OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound
57 OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound
58 OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound
59 OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound
60 OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped
61 OBJSTATUS_COMMAND_BUFFER_SECONDARY = 0x00000040, // Command Buffer is of type SECONDARY
Mark Lobodzinski7d2d5ac2015-05-20 17:33:47 -050062} ObjectStatusFlagBits;
Chia-I Wu5b66aa52015-04-16 22:02:10 +080063
Tobin Ehlisacab8882014-11-14 13:01:02 -070064typedef struct _OBJTRACK_NODE {
Jon Ashburn491a3cd2016-03-08 17:48:44 -070065 uint64_t vkObj; // Object handle
66 VkDebugReportObjectTypeEXT objType; // Object type identifier
67 ObjectStatusFlags status; // Object state
68 uint64_t parentObj; // Parent object
69 uint64_t belongsTo; // Object Scope -- owning device/instance
Tobin Ehlisacab8882014-11-14 13:01:02 -070070} OBJTRACK_NODE;
Mark Lobodzinskie1d3f0c2015-02-09 10:20:53 -060071
Tobin Ehlisacab8882014-11-14 13:01:02 -070072// prototype for extension functions
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060073uint64_t objTrackGetObjectCount(VkDevice device);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070074uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDebugReportObjectTypeEXT type);
Mark Lobodzinskie1d3f0c2015-02-09 10:20:53 -060075
Tobin Ehlis3c26a542014-11-18 11:28:33 -070076// Func ptr typedefs
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060077typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -070078typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDebugReportObjectTypeEXT);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060079
Cody Northrop73bb6572015-09-28 15:09:32 -060080struct layer_data {
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060081 debug_report_data *report_data;
Jon Ashburn491a3cd2016-03-08 17:48:44 -070082 // TODO: put instance data here
Mark Lobodzinskid11c4ee2016-03-15 14:21:59 -060083 std::vector<VkDebugReportCallbackEXT> logging_callback;
Ian Elliottb134e842015-07-06 14:31:32 -060084 bool wsi_enabled;
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -060085 bool objtrack_extensions_enabled;
Cody Northrop73bb6572015-09-28 15:09:32 -060086
Mark Lobodzinskid11c4ee2016-03-15 14:21:59 -060087 layer_data() : report_data(nullptr), wsi_enabled(false), objtrack_extensions_enabled(false){};
Cody Northrop73bb6572015-09-28 15:09:32 -060088};
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060089
Jon Ashburnde4f1102015-09-17 10:00:32 -060090struct instExts {
91 bool wsi_enabled;
92};
93
94static std::unordered_map<void *, struct instExts> instanceExtMap;
Jon Ashburn491a3cd2016-03-08 17:48:44 -070095static std::unordered_map<void *, layer_data *> layer_data_map;
96static device_table_map object_tracker_device_table_map;
97static instance_table_map object_tracker_instance_table_map;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -060098
Mark Lobodzinski9c483302015-10-14 13:16:33 -060099// We need additionally validate image usage using a separate map
100// of swapchain-created images
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700101static unordered_map<uint64_t, OBJTRACK_NODE *> swapchainImageMap;
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600102
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600103static long long unsigned int object_track_index = 0;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600104static std::mutex global_lock;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600105
106// Objects stored in a global map w/ struct containing basic info
Tony Barbour2a199c12015-07-09 17:31:46 -0600107// unordered_map<const void*, OBJTRACK_NODE*> objMap;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600108
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700109#define NUM_OBJECT_TYPES (VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT + 1)
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600110
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700111static uint64_t numObjs[NUM_OBJECT_TYPES] = {0};
112static uint64_t numTotalObjs = 0;
113static VkQueueFamilyProperties *queueInfo = NULL;
114static uint32_t queueCount = 0;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600115
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700116template layer_data *get_my_data_ptr<layer_data>(void *data_key, std::unordered_map<void *, layer_data *> &data_map);
Mark Lobodzinskif993d542015-09-01 08:52:55 -0600117
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600118//
119// Internal Object Tracker Functions
120//
121
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700122static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700123 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
124 VkLayerDispatchTable *pDisp = get_dispatch_table(object_tracker_device_table_map, device);
Jon Ashburn83334db2015-09-16 18:08:32 -0600125 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700126 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
127 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
128 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
129 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
130 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
Ian Elliottb134e842015-07-06 14:31:32 -0600131 my_device_data->wsi_enabled = false;
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700132 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700133 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliottb134e842015-07-06 14:31:32 -0600134 my_device_data->wsi_enabled = true;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600135
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700136 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], "OBJTRACK_EXTENSIONS") == 0)
Courtney Goeltzenleuchter8b0e68d2015-07-05 22:13:43 -0600137 my_device_data->objtrack_extensions_enabled = true;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600138 }
139}
140
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700141static void createInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
Jon Ashburnde4f1102015-09-17 10:00:32 -0600142 uint32_t i;
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700143 VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(object_tracker_instance_table_map, instance);
Jon Ashburnde4f1102015-09-17 10:00:32 -0600144 PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
Michael Lentine90ee20e2016-03-02 17:28:55 -0600145
146 pDisp->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(instance, "vkDestroySurfaceKHR");
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700147 pDisp->GetPhysicalDeviceSurfaceSupportKHR =
148 (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
149 pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR =
150 (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
151 pDisp->GetPhysicalDeviceSurfaceFormatsKHR =
152 (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
153 pDisp->GetPhysicalDeviceSurfacePresentModesKHR =
154 (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
Mark Lobodzinskidc87a3f2015-11-24 15:50:44 -0700155
156#if VK_USE_PLATFORM_WIN32_KHR
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700157 pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(instance, "vkCreateWin32SurfaceKHR");
158 pDisp->GetPhysicalDeviceWin32PresentationSupportKHR =
159 (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
Mark Lobodzinskib3e934d2015-12-10 16:25:21 -0700160#endif // VK_USE_PLATFORM_WIN32_KHR
161#ifdef VK_USE_PLATFORM_XCB_KHR
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700162 pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)gpa(instance, "vkCreateXcbSurfaceKHR");
163 pDisp->GetPhysicalDeviceXcbPresentationSupportKHR =
164 (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
Mark Lobodzinskib3e934d2015-12-10 16:25:21 -0700165#endif // VK_USE_PLATFORM_XCB_KHR
166#ifdef VK_USE_PLATFORM_XLIB_KHR
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700167 pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)gpa(instance, "vkCreateXlibSurfaceKHR");
168 pDisp->GetPhysicalDeviceXlibPresentationSupportKHR =
169 (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
Mark Lobodzinskib3e934d2015-12-10 16:25:21 -0700170#endif // VK_USE_PLATFORM_XLIB_KHR
171#ifdef VK_USE_PLATFORM_MIR_KHR
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700172 pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)gpa(instance, "vkCreateMirSurfaceKHR");
173 pDisp->GetPhysicalDeviceMirPresentationSupportKHR =
174 (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
Mark Lobodzinskib3e934d2015-12-10 16:25:21 -0700175#endif // VK_USE_PLATFORM_MIR_KHR
176#ifdef VK_USE_PLATFORM_WAYLAND_KHR
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700177 pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)gpa(instance, "vkCreateWaylandSurfaceKHR");
178 pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR =
179 (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
Mark Lobodzinskib3e934d2015-12-10 16:25:21 -0700180#endif // VK_USE_PLATFORM_WAYLAND_KHR
181#ifdef VK_USE_PLATFORM_ANDROID_KHR
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700182 pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)gpa(instance, "vkCreateAndroidSurfaceKHR");
Mark Lobodzinskib3e934d2015-12-10 16:25:21 -0700183#endif // VK_USE_PLATFORM_ANDROID_KHR
Mark Lobodzinskidc87a3f2015-11-24 15:50:44 -0700184
Jon Ashburnde4f1102015-09-17 10:00:32 -0600185 instanceExtMap[pDisp].wsi_enabled = false;
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700186 for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700187 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0)
Jon Ashburnde4f1102015-09-17 10:00:32 -0600188 instanceExtMap[pDisp].wsi_enabled = true;
Jon Ashburnde4f1102015-09-17 10:00:32 -0600189 }
190}
191
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600192// Indicate device or instance dispatch table type
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700193typedef enum _DispTableType {
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600194 DISP_TBL_TYPE_INSTANCE,
195 DISP_TBL_TYPE_DEVICE,
196} DispTableType;
197
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700198debug_report_data *mdd(const void *object) {
Mark Lobodzinski14305ad2015-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 Lobodzinski14305ad2015-06-23 11:35:12 -0600201 return my_data->report_data;
202}
203
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700204debug_report_data *mid(VkInstance object) {
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600205 dispatch_key key = get_dispatch_key(object);
206 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600207 return my_data->report_data;
208}
209
210// For each Queue's doubly linked-list of mem refs
211typedef struct _OT_MEM_INFO {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700212 VkDeviceMemory mem;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600213 struct _OT_MEM_INFO *pNextMI;
214 struct _OT_MEM_INFO *pPrevMI;
215
216} OT_MEM_INFO;
217
218// Track Queue information
219typedef struct _OT_QUEUE_INFO {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700220 OT_MEM_INFO *pMemRefList;
221 struct _OT_QUEUE_INFO *pNextQI;
222 uint32_t queueNodeIndex;
223 VkQueue queue;
224 uint32_t refCount;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600225} OT_QUEUE_INFO;
226
227// Global list of QueueInfo structures, one per queue
228static OT_QUEUE_INFO *g_pQueueInfo = NULL;
229
230// Convert an object type enum to an object type array index
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700231static uint32_t objTypeToIndex(uint32_t objType) {
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600232 uint32_t index = objType;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600233 return index;
234}
235
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600236// Add new queue to head of global queue list
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700237static void addQueueInfo(uint32_t queueNodeIndex, VkQueue queue) {
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600238 OT_QUEUE_INFO *pQueueInfo = new OT_QUEUE_INFO;
239
240 if (pQueueInfo != NULL) {
241 memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700242 pQueueInfo->queue = queue;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600243 pQueueInfo->queueNodeIndex = queueNodeIndex;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700244 pQueueInfo->pNextQI = g_pQueueInfo;
245 g_pQueueInfo = pQueueInfo;
246 } else {
247 log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, reinterpret_cast<uint64_t>(queue),
248 __LINE__, OBJTRACK_INTERNAL_ERROR, "OBJTRACK",
249 "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600250 }
251}
252
253// Destroy memRef lists and free all memory
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700254static void destroyQueueMemRefLists(void) {
255 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600256 OT_QUEUE_INFO *pDelQueueInfo = NULL;
257 while (pQueueInfo != NULL) {
258 OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;
259 while (pMemInfo != NULL) {
260 OT_MEM_INFO *pDelMemInfo = pMemInfo;
261 pMemInfo = pMemInfo->pNextMI;
262 delete pDelMemInfo;
263 }
264 pDelQueueInfo = pQueueInfo;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700265 pQueueInfo = pQueueInfo->pNextQI;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600266 delete pDelQueueInfo;
267 }
268 g_pQueueInfo = pQueueInfo;
269}
270
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700271static void setGpuQueueInfoState(uint32_t count, void *pData) {
Tony Barbour426b9052015-06-24 16:06:58 -0600272 queueCount = count;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700273 queueInfo = (VkQueueFamilyProperties *)realloc((void *)queueInfo, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600274 if (queueInfo != NULL) {
Cody Northropef72e2a2015-08-03 17:04:53 -0600275 memcpy(queueInfo, pData, count * sizeof(VkQueueFamilyProperties));
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600276 }
277}
278
279// Check Queue type flags for selected queue operations
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700280static void validateQueueFlags(VkQueue queue, const char *function) {
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600281 OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;
282 while ((pQueueInfo != NULL) && (pQueueInfo->queue != queue)) {
283 pQueueInfo = pQueueInfo->pNextQI;
284 }
285 if (pQueueInfo != NULL) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700286 if ((queueInfo != NULL) && (queueInfo[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700287 log_msg(mdd(queue), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
288 reinterpret_cast<uint64_t>(queue), __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
289 "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600290 }
291 }
292}
293
Tony Barbour2a199c12015-07-09 17:31:46 -0600294/* TODO: Port to new type safety */
295#if 0
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600296// Check object status for selected flag state
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600297static VkBool32
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600298validate_status(
299 VkObject dispatchable_object,
300 VkObject vkObj,
301 VkObjectType objType,
302 ObjectStatusFlags status_mask,
303 ObjectStatusFlags status_flag,
304 VkFlags msg_flags,
305 OBJECT_TRACK_ERROR error_code,
306 const char *fail_msg)
307{
308 if (objMap.find(vkObj) != objMap.end()) {
309 OBJTRACK_NODE* pNode = objMap[vkObj];
310 if ((pNode->status & status_mask) != status_flag) {
311 char str[1024];
Mark Lobodzinski78996602016-01-04 15:48:11 -0700312 log_msg(mdd(dispatchable_object), msg_flags, pNode->objType, vkObj, __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600313 "OBJECT VALIDATION WARNING: %s object 0x%" PRIxLEAST64 ": %s", string_VkObjectType(objType),
Mark Young2acdd152016-01-13 13:47:16 -0700314 static_cast<uint64_t>(vkObj), fail_msg);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600315 return VK_FALSE;
316 }
317 return VK_TRUE;
318 }
319 else {
320 // If we do not find it print an error
Mark Lobodzinski78996602016-01-04 15:48:11 -0700321 log_msg(mdd(dispatchable_object), msg_flags, (VkObjectType) 0, vkObj, __LINE__, OBJTRACK_UNKNOWN_OBJECT, "OBJTRACK",
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600322 "Unable to obtain status for non-existent object 0x%" PRIxLEAST64 " of %s type",
Mark Young2acdd152016-01-13 13:47:16 -0700323 static_cast<uint64_t>(vkObj), string_VkObjectType(objType));
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600324 return VK_FALSE;
325 }
326}
Tony Barbour2a199c12015-07-09 17:31:46 -0600327#endif
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600328
329#include "vk_dispatch_table_helper.h"
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600330
Mark Lobodzinskid11c4ee2016-03-15 14:21:59 -0600331static void init_object_tracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
332
333 layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_object_tracker");
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600334}
335
Tony Barbour2a199c12015-07-09 17:31:46 -0600336//
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700337// Forward declarations
Tony Barbour2a199c12015-07-09 17:31:46 -0600338//
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600339
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700340static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeEXT objType);
341static void create_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType);
342static void create_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700343static void create_device(VkPhysicalDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700344static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeEXT objType);
345static VkBool32 validate_image(VkQueue dispatchable_object, VkImage object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700346static VkBool32 validate_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType,
347 bool null_allowed);
348static VkBool32 validate_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType,
349 bool null_allowed);
350static VkBool32 validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object, VkDebugReportObjectTypeEXT objType,
351 bool null_allowed);
352static VkBool32 validate_descriptor_set_layout(VkDevice dispatchable_object, VkDescriptorSetLayout object,
353 VkDebugReportObjectTypeEXT objType, bool null_allowed);
354static VkBool32 validate_command_pool(VkDevice dispatchable_object, VkCommandPool object, VkDebugReportObjectTypeEXT objType,
355 bool null_allowed);
356static VkBool32 validate_buffer(VkQueue dispatchable_object, VkBuffer object, VkDebugReportObjectTypeEXT objType,
357 bool null_allowed);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700358static void create_pipeline(VkDevice dispatchable_object, VkPipeline vkObj, VkDebugReportObjectTypeEXT objType);
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700359static VkBool32 validate_pipeline_cache(VkDevice dispatchable_object, VkPipelineCache object, VkDebugReportObjectTypeEXT objType,
360 bool null_allowed);
361static VkBool32 validate_render_pass(VkDevice dispatchable_object, VkRenderPass object, VkDebugReportObjectTypeEXT objType,
362 bool null_allowed);
363static VkBool32 validate_shader_module(VkDevice dispatchable_object, VkShaderModule object, VkDebugReportObjectTypeEXT objType,
364 bool null_allowed);
365static VkBool32 validate_pipeline_layout(VkDevice dispatchable_object, VkPipelineLayout object, VkDebugReportObjectTypeEXT objType,
366 bool null_allowed);
367static VkBool32 validate_pipeline(VkDevice dispatchable_object, VkPipeline object, VkDebugReportObjectTypeEXT objType,
368 bool null_allowed);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700369static void destroy_command_pool(VkDevice dispatchable_object, VkCommandPool object);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700370static void destroy_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
371static void destroy_descriptor_set(VkDevice dispatchable_object, VkDescriptorSet object);
372static void destroy_device_memory(VkDevice dispatchable_object, VkDeviceMemory object);
373static void destroy_swapchain_khr(VkDevice dispatchable_object, VkSwapchainKHR object);
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700374static VkBool32 set_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeEXT objType,
375 ObjectStatusFlags status_flag);
376static VkBool32 reset_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeEXT objType,
377 ObjectStatusFlags status_flag);
Tony Barbour2a199c12015-07-09 17:31:46 -0600378#if 0
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700379static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, VkDebugReportObjectTypeEXT objType,
Tony Barbour2a199c12015-07-09 17:31:46 -0600380 ObjectStatusFlags status_mask, ObjectStatusFlags status_flag, VkFlags msg_flags, OBJECT_TRACK_ERROR error_code,
381 const char *fail_msg);
382#endif
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700383extern unordered_map<uint64_t, OBJTRACK_NODE *> VkPhysicalDeviceMap;
384extern unordered_map<uint64_t, OBJTRACK_NODE *> VkDeviceMap;
385extern unordered_map<uint64_t, OBJTRACK_NODE *> VkImageMap;
386extern unordered_map<uint64_t, OBJTRACK_NODE *> VkQueueMap;
387extern unordered_map<uint64_t, OBJTRACK_NODE *> VkDescriptorSetMap;
388extern unordered_map<uint64_t, OBJTRACK_NODE *> VkBufferMap;
389extern unordered_map<uint64_t, OBJTRACK_NODE *> VkFenceMap;
390extern unordered_map<uint64_t, OBJTRACK_NODE *> VkSemaphoreMap;
391extern unordered_map<uint64_t, OBJTRACK_NODE *> VkCommandPoolMap;
392extern unordered_map<uint64_t, OBJTRACK_NODE *> VkCommandBufferMap;
393extern unordered_map<uint64_t, OBJTRACK_NODE *> VkSwapchainKHRMap;
394extern unordered_map<uint64_t, OBJTRACK_NODE *> VkSurfaceKHRMap;
Tony Barbour2a199c12015-07-09 17:31:46 -0600395
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700396static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeEXT objType) {
397 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__,
398 OBJTRACK_NONE, "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
399 string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600400
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700401 OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600402 pNewObjNode->objType = objType;
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700403 pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700404 pNewObjNode->status = OBJSTATUS_NONE;
405 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine1a85aa12015-11-04 14:35:12 -0800406 VkPhysicalDeviceMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600407 uint32_t objIndex = objTypeToIndex(objType);
408 numObjs[objIndex]++;
409 numTotalObjs++;
410}
411
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700412static void create_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR vkObj, VkDebugReportObjectTypeEXT objType) {
Mark Lobodzinski6f92feb2015-11-26 10:59:58 -0700413 // TODO: Add tracking of surface objects
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700414 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE,
415 "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
416 string_VkDebugReportObjectTypeEXT(objType), (uint64_t)(vkObj));
Tobin Ehlisc6a25752016-01-05 10:33:58 -0700417
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700418 OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
Tobin Ehlisc6a25752016-01-05 10:33:58 -0700419 pNewObjNode->objType = objType;
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700420 pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700421 pNewObjNode->status = OBJSTATUS_NONE;
422 pNewObjNode->vkObj = (uint64_t)(vkObj);
Tobin Ehlisc6a25752016-01-05 10:33:58 -0700423 VkSurfaceKHRMap[(uint64_t)vkObj] = pNewObjNode;
424 uint32_t objIndex = objTypeToIndex(objType);
425 numObjs[objIndex]++;
426 numTotalObjs++;
Mark Lobodzinski6f92feb2015-11-26 10:59:58 -0700427}
428
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700429static void destroy_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR object) {
Mark Young2acdd152016-01-13 13:47:16 -0700430 uint64_t object_handle = (uint64_t)(object);
Tobin Ehlisc6a25752016-01-05 10:33:58 -0700431 if (VkSurfaceKHRMap.find(object_handle) != VkSurfaceKHRMap.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700432 OBJTRACK_NODE *pNode = VkSurfaceKHRMap[(uint64_t)object];
Tobin Ehlisc6a25752016-01-05 10:33:58 -0700433 uint32_t objIndex = objTypeToIndex(pNode->objType);
434 assert(numTotalObjs > 0);
435 numTotalObjs--;
436 assert(numObjs[objIndex] > 0);
437 numObjs[objIndex]--;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700438 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__,
439 OBJTRACK_NONE, "OBJTRACK",
440 "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
441 string_VkDebugReportObjectTypeEXT(pNode->objType), (uint64_t)(object), numTotalObjs, numObjs[objIndex],
442 string_VkDebugReportObjectTypeEXT(pNode->objType));
Tobin Ehlisc6a25752016-01-05 10:33:58 -0700443 delete pNode;
444 VkSurfaceKHRMap.erase(object_handle);
445 } else {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700446 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__,
447 OBJTRACK_NONE, "OBJTRACK",
448 "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", object_handle);
Tobin Ehlisc6a25752016-01-05 10:33:58 -0700449 }
Mark Lobodzinski6f92feb2015-11-26 10:59:58 -0700450}
451
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700452static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer vkObj,
453 VkDebugReportObjectTypeEXT objType, VkCommandBufferLevel level) {
454 log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__, OBJTRACK_NONE,
455 "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
456 string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
Tony Barbour2a199c12015-07-09 17:31:46 -0600457
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700458 OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
459 pNewObjNode->objType = objType;
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700460 pNewObjNode->belongsTo = (uint64_t)device;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700461 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
462 pNewObjNode->parentObj = (uint64_t)commandPool;
Mark Lobodzinskif980af42016-01-23 18:31:23 -0700463 if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
464 pNewObjNode->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
465 } else {
466 pNewObjNode->status = OBJSTATUS_NONE;
467 }
Michael Lentine1a85aa12015-11-04 14:35:12 -0800468 VkCommandBufferMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tony Barbour2a199c12015-07-09 17:31:46 -0600469 uint32_t objIndex = objTypeToIndex(objType);
470 numObjs[objIndex]++;
471 numTotalObjs++;
472}
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700473
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700474static void free_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer) {
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700475 uint64_t object_handle = reinterpret_cast<uint64_t>(commandBuffer);
476 if (VkCommandBufferMap.find(object_handle) != VkCommandBufferMap.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700477 OBJTRACK_NODE *pNode = VkCommandBufferMap[(uint64_t)commandBuffer];
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700478
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700479 if (pNode->parentObj != (uint64_t)(commandPool)) {
480 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, object_handle, __LINE__,
481 OBJTRACK_COMMAND_POOL_MISMATCH, "OBJTRACK",
482 "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64
483 " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
484 reinterpret_cast<uint64_t>(commandBuffer), pNode->parentObj, (uint64_t)(commandPool));
485 } else {
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700486
487 uint32_t objIndex = objTypeToIndex(pNode->objType);
488 assert(numTotalObjs > 0);
489 numTotalObjs--;
490 assert(numObjs[objIndex] > 0);
491 numObjs[objIndex]--;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700492 log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_NONE,
493 "OBJTRACK", "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
494 string_VkDebugReportObjectTypeEXT(pNode->objType), reinterpret_cast<uint64_t>(commandBuffer), numTotalObjs,
495 numObjs[objIndex], string_VkDebugReportObjectTypeEXT(pNode->objType));
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700496 delete pNode;
497 VkCommandBufferMap.erase(object_handle);
498 }
499 } else {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700500 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__, OBJTRACK_NONE,
501 "OBJTRACK", "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
502 object_handle);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700503 }
504}
505
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700506static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet vkObj,
507 VkDebugReportObjectTypeEXT objType) {
Mark Lobodzinski5c13d4d2016-02-11 09:26:16 -0700508 log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700509 "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++, string_VkDebugReportObjectTypeEXT(objType),
510 (uint64_t)(vkObj));
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700511
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700512 OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
513 pNewObjNode->objType = objType;
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700514 pNewObjNode->belongsTo = (uint64_t)device;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700515 pNewObjNode->status = OBJSTATUS_NONE;
516 pNewObjNode->vkObj = (uint64_t)(vkObj);
517 pNewObjNode->parentObj = (uint64_t)descriptorPool;
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700518 VkDescriptorSetMap[(uint64_t)vkObj] = pNewObjNode;
519 uint32_t objIndex = objTypeToIndex(objType);
520 numObjs[objIndex]++;
521 numTotalObjs++;
522}
523
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700524static void free_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet descriptorSet) {
Mark Young2acdd152016-01-13 13:47:16 -0700525 uint64_t object_handle = (uint64_t)(descriptorSet);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700526 if (VkDescriptorSetMap.find(object_handle) != VkDescriptorSetMap.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700527 OBJTRACK_NODE *pNode = VkDescriptorSetMap[(uint64_t)descriptorSet];
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700528
Mark Young2acdd152016-01-13 13:47:16 -0700529 if (pNode->parentObj != (uint64_t)(descriptorPool)) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700530 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, object_handle, __LINE__,
531 OBJTRACK_DESCRIPTOR_POOL_MISMATCH, "OBJTRACK",
532 "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64
533 " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
534 (uint64_t)(descriptorSet), pNode->parentObj, (uint64_t)(descriptorPool));
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700535 } else {
536 uint32_t objIndex = objTypeToIndex(pNode->objType);
537 assert(numTotalObjs > 0);
538 numTotalObjs--;
539 assert(numObjs[objIndex] > 0);
540 numObjs[objIndex]--;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700541 log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_NONE,
542 "OBJTRACK", "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
543 string_VkDebugReportObjectTypeEXT(pNode->objType), (uint64_t)(descriptorSet), numTotalObjs, numObjs[objIndex],
544 string_VkDebugReportObjectTypeEXT(pNode->objType));
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700545 delete pNode;
546 VkDescriptorSetMap.erase(object_handle);
547 }
548 } else {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700549 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__, OBJTRACK_NONE,
550 "OBJTRACK", "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
551 object_handle);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700552 }
553}
554
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700555static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeEXT objType) {
556 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__,
557 OBJTRACK_NONE, "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
558 string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600559
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700560 OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600561 pNewObjNode->objType = objType;
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700562 pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700563 pNewObjNode->status = OBJSTATUS_NONE;
564 pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
Michael Lentine1a85aa12015-11-04 14:35:12 -0800565 VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600566 uint32_t objIndex = objTypeToIndex(objType);
567 numObjs[objIndex]++;
568 numTotalObjs++;
569}
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700570static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain) {
571 log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)vkObj,
572 __LINE__, OBJTRACK_NONE, "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
573 "SwapchainImage", (uint64_t)(vkObj));
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600574
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700575 OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
576 pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
577 pNewObjNode->objType = VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT;
578 pNewObjNode->status = OBJSTATUS_NONE;
579 pNewObjNode->vkObj = (uint64_t)vkObj;
580 pNewObjNode->parentObj = (uint64_t)swapchain;
Mark Young2acdd152016-01-13 13:47:16 -0700581 swapchainImageMap[(uint64_t)(vkObj)] = pNewObjNode;
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600582}
583
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700584static void create_device(VkInstance dispatchable_object, VkDevice vkObj, VkDebugReportObjectTypeEXT objType) {
585 log_msg(mid(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE,
586 "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
587 string_VkDebugReportObjectTypeEXT(objType), (uint64_t)(vkObj));
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700588
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700589 OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700590 pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
591 pNewObjNode->objType = objType;
592 pNewObjNode->status = OBJSTATUS_NONE;
593 pNewObjNode->vkObj = (uint64_t)(vkObj);
594 VkDeviceMap[(uint64_t)vkObj] = pNewObjNode;
595 uint32_t objIndex = objTypeToIndex(objType);
596 numObjs[objIndex]++;
597 numTotalObjs++;
598}
599
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600600//
601// Non-auto-generated API functions called by generated code
602//
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700603VkResult explicit_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
604 VkInstance *pInstance) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700605 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
David Pinedo565035c2015-07-31 10:46:25 -0600606
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700607 assert(chain_info->u.pLayerInfo);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700608 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700609 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700610 if (fpCreateInstance == NULL) {
611 return VK_ERROR_INITIALIZATION_FAILED;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600612 }
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700613
614 // Advance the link info for the next element on the chain
615 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
616
617 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
618 if (result != VK_SUCCESS) {
619 return result;
620 }
621
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700622 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
623 initInstanceTable(*pInstance, fpGetInstanceProcAddr, object_tracker_instance_table_map);
624 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, *pInstance);
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700625
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700626 my_data->report_data = debug_report_create_instance(pInstanceTable, *pInstance, pCreateInfo->enabledExtensionCount,
627 pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700628
Mark Lobodzinskid11c4ee2016-03-15 14:21:59 -0600629 init_object_tracker(my_data, pAllocator);
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700630 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
631
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700632 create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700633
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600634 return result;
635}
636
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700637void explicit_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice gpu, uint32_t *pCount, VkQueueFamilyProperties *pProperties) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700638 get_dispatch_table(object_tracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -0600639
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600640 std::lock_guard<std::mutex> lock(global_lock);
641 if (pProperties != NULL) {
Cody Northropef72e2a2015-08-03 17:04:53 -0600642 setGpuQueueInfoState(*pCount, pProperties);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600643 }
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600644}
645
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700646VkResult explicit_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
647 VkDevice *pDevice) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600648 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700649 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700650
651 assert(chain_info->u.pLayerInfo);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700652 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
653 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700654 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700655 if (fpCreateDevice == NULL) {
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700656 return VK_ERROR_INITIALIZATION_FAILED;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600657 }
658
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700659 // Advance the link info for the next element on the chain
660 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
661
662 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
663 if (result != VK_SUCCESS) {
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700664 return result;
665 }
666
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700667 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
668 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
669 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700670
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700671 initDeviceTable(*pDevice, fpGetDeviceProcAddr, object_tracker_device_table_map);
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700672
673 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
674
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700675 if (VkPhysicalDeviceMap.find((uint64_t)gpu) != VkPhysicalDeviceMap.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700676 OBJTRACK_NODE *pNewObjNode = VkPhysicalDeviceMap[(uint64_t)gpu];
Mark Lobodzinskic2470602016-03-08 15:10:00 -0700677 create_device((VkInstance)pNewObjNode->belongsTo, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
678 }
Courtney Goeltzenleuchter2bdf6da2016-01-08 12:18:43 -0700679
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600680 return result;
681}
682
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700683VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
684 VkPhysicalDevice *pPhysicalDevices) {
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600685 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600686 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700687 skipCall |= validate_instance(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600688 lock.unlock();
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600689 if (skipCall)
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -0700690 return VK_ERROR_VALIDATION_FAILED_EXT;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700691 VkResult result = get_dispatch_table(object_tracker_instance_table_map, instance)
692 ->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600693 lock.lock();
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600694 if (result == VK_SUCCESS) {
695 if (pPhysicalDevices) {
696 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700697 create_physical_device(instance, pPhysicalDevices[i], VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT);
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600698 }
699 }
700 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600701 lock.unlock();
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600702 return result;
703}
704
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700705void explicit_GetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue *pQueue) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600706 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700707 validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600708 lock.unlock();
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600709
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700710 get_dispatch_table(object_tracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600711
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600712 lock.lock();
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600713 addQueueInfo(queueNodeIndex, *pQueue);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700714 create_queue(device, *pQueue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600715}
716
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700717VkResult explicit_MapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags,
718 void **ppData) {
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600719 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600720 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700721 skipCall |= set_device_memory_status(device, mem, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, OBJSTATUS_GPU_MEM_MAPPED);
722 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600723 lock.unlock();
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600724 if (skipCall == VK_TRUE)
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -0700725 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600726
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700727 VkResult result =
728 get_dispatch_table(object_tracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600729
730 return result;
731}
732
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700733void explicit_UnmapMemory(VkDevice device, VkDeviceMemory mem) {
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600734 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600735 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700736 skipCall |= reset_device_memory_status(device, mem, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, OBJSTATUS_GPU_MEM_MAPPED);
737 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600738 lock.unlock();
Tobin Ehlisf2f97402015-09-11 12:57:55 -0600739 if (skipCall == VK_TRUE)
740 return;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600741
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700742 get_dispatch_table(object_tracker_device_table_map, device)->UnmapMemory(device, mem);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600743}
744
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700745VkResult explicit_QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600746 std::unique_lock<std::mutex> lock(global_lock);
Chia-I Wu06809d52015-10-26 16:55:27 +0800747 validateQueueFlags(queue, "QueueBindSparse");
748
749 for (uint32_t i = 0; i < bindInfoCount; i++) {
750 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700751 validate_buffer(queue, pBindInfo[i].pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
Chia-I Wu06809d52015-10-26 16:55:27 +0800752 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700753 validate_image(queue, pBindInfo[i].pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
Chia-I Wu06809d52015-10-26 16:55:27 +0800754 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700755 validate_image(queue, pBindInfo[i].pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
Chia-I Wu06809d52015-10-26 16:55:27 +0800756 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600757 lock.unlock();
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600758
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700759 VkResult result =
760 get_dispatch_table(object_tracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -0600761 return result;
762}
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600763
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700764VkResult explicit_AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
765 VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700766 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600767 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700768 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
769 skipCall |= validate_command_pool(device, pAllocateInfo->commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600770 lock.unlock();
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700771
772 if (skipCall) {
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -0700773 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700774 }
775
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700776 VkResult result =
777 get_dispatch_table(object_tracker_device_table_map, device)->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700778
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600779 lock.lock();
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700780 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700781 alloc_command_buffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
782 pAllocateInfo->level);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700783 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600784 lock.unlock();
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700785
786 return result;
787}
788
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700789VkResult explicit_AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
790 VkDescriptorSet *pDescriptorSets) {
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600791 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600792 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700793 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700794 skipCall |=
795 validate_descriptor_pool(device, pAllocateInfo->descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700796 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700797 skipCall |= validate_descriptor_set_layout(device, pAllocateInfo->pSetLayouts[i],
798 VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600799 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600800 lock.unlock();
Tobin Ehlis87f115c2015-09-15 15:02:17 -0600801 if (skipCall)
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -0700802 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600803
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700804 VkResult result =
805 get_dispatch_table(object_tracker_device_table_map, device)->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600806
Chris Forbesae8172b2016-01-22 15:44:40 +1300807 if (VK_SUCCESS == result) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600808 lock.lock();
Chris Forbesae8172b2016-01-22 15:44:40 +1300809 for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700810 alloc_descriptor_set(device, pAllocateInfo->descriptorPool, pDescriptorSets[i],
811 VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
Chris Forbesae8172b2016-01-22 15:44:40 +1300812 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600813 lock.unlock();
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600814 }
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600815
816 return result;
817}
818
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700819void explicit_FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
820 const VkCommandBuffer *pCommandBuffers) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600821 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700822 validate_command_pool(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
823 validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600824 lock.unlock();
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700825
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700826 get_dispatch_table(object_tracker_device_table_map, device)
827 ->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700828
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600829 lock.lock();
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700830 for (uint32_t i = 0; i < commandBufferCount; i++) {
Michael Lentinec53a7572015-11-20 12:11:42 -0800831 free_command_buffer(device, commandPool, *pCommandBuffers);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700832 pCommandBuffers++;
833 }
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700834}
835
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700836void explicit_DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600837 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700838 // A swapchain's images are implicitly deleted when the swapchain is deleted.
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600839 // Remove this swapchain's images from our map of such images.
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700840 unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = swapchainImageMap.begin();
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600841 while (itr != swapchainImageMap.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700842 OBJTRACK_NODE *pNode = (*itr).second;
Mark Young2acdd152016-01-13 13:47:16 -0700843 if (pNode->parentObj == (uint64_t)(swapchain)) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700844 swapchainImageMap.erase(itr++);
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600845 } else {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700846 ++itr;
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600847 }
848 }
Tobin Ehlisc6a25752016-01-05 10:33:58 -0700849 destroy_swapchain_khr(device, swapchain);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600850 lock.unlock();
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600851
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700852 get_dispatch_table(object_tracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600853}
854
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700855void explicit_FreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600856 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700857 validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600858 lock.unlock();
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600859
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700860 get_dispatch_table(object_tracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600861
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600862 lock.lock();
Michael Lentine1a85aa12015-11-04 14:35:12 -0800863 destroy_device_memory(device, mem);
Mark Lobodzinski14305ad2015-06-23 11:35:12 -0600864}
Tony Barbour2a199c12015-07-09 17:31:46 -0600865
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700866VkResult explicit_FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count,
867 const VkDescriptorSet *pDescriptorSets) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600868 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700869 validate_descriptor_pool(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
870 validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600871 lock.unlock();
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700872 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
873 ->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
Tony Barbour912e8152015-07-20 10:52:13 -0600874
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600875 lock.lock();
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700876 for (uint32_t i = 0; i < count; i++) {
Michael Lentinec53a7572015-11-20 12:11:42 -0800877 free_descriptor_set(device, descriptorPool, *pDescriptorSets++);
Tony Barbour912e8152015-07-20 10:52:13 -0600878 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600879 lock.unlock();
Tony Barbour912e8152015-07-20 10:52:13 -0600880 return result;
881}
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600882
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700883void explicit_DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700884 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600885 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700886 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
887 skipCall |= validate_descriptor_pool(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600888 lock.unlock();
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700889 if (skipCall) {
890 return;
891 }
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700892 // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700893 // Remove this pool's descriptor sets from our descriptorSet map.
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600894 lock.lock();
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700895 unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = VkDescriptorSetMap.begin();
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700896 while (itr != VkDescriptorSetMap.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700897 OBJTRACK_NODE *pNode = (*itr).second;
Mark Lobodzinskied888c52015-11-18 11:01:02 -0700898 auto del_itr = itr++;
Mark Young2acdd152016-01-13 13:47:16 -0700899 if (pNode->parentObj == (uint64_t)(descriptorPool)) {
900 destroy_descriptor_set(device, (VkDescriptorSet)((*del_itr).first));
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700901 }
902 }
903 destroy_descriptor_pool(device, descriptorPool);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600904 lock.unlock();
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700905 get_dispatch_table(object_tracker_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700906}
907
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700908void explicit_DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700909 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600910 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700911 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
912 skipCall |= validate_command_pool(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600913 lock.unlock();
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700914 if (skipCall) {
915 return;
916 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600917 lock.lock();
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700918 // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700919 // Remove this pool's cmdBuffers from our cmd buffer map.
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700920 unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = VkCommandBufferMap.begin();
921 unordered_map<uint64_t, OBJTRACK_NODE *>::iterator del_itr;
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700922 while (itr != VkCommandBufferMap.end()) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700923 OBJTRACK_NODE *pNode = (*itr).second;
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700924 del_itr = itr++;
Mark Young2acdd152016-01-13 13:47:16 -0700925 if (pNode->parentObj == (uint64_t)(commandPool)) {
Tobin Ehlis914b7762016-04-18 15:40:59 -0600926 free_command_buffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700927 }
928 }
929 destroy_command_pool(device, commandPool);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600930 lock.unlock();
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700931 get_dispatch_table(object_tracker_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
Mark Lobodzinski60b2b332015-11-12 16:02:35 -0700932}
933
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700934VkResult explicit_GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pCount, VkImage *pSwapchainImages) {
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600935 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600936 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700937 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600938 lock.unlock();
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600939 if (skipCall)
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -0700940 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600941
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700942 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
943 ->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600944
945 if (pSwapchainImages != NULL) {
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600946 lock.lock();
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600947 for (uint32_t i = 0; i < *pCount; i++) {
948 create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
949 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600950 lock.unlock();
Mark Lobodzinski9c483302015-10-14 13:16:33 -0600951 }
952 return result;
953}
954
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700955// TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700956VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
957 const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
958 VkPipeline *pPipelines) {
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700959 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600960 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700961 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700962 if (pCreateInfos) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700963 for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700964 if (pCreateInfos[idx0].basePipelineHandle) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700965 skipCall |= validate_pipeline(device, pCreateInfos[idx0].basePipelineHandle,
966 VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700967 }
968 if (pCreateInfos[idx0].layout) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700969 skipCall |= validate_pipeline_layout(device, pCreateInfos[idx0].layout,
970 VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700971 }
972 if (pCreateInfos[idx0].pStages) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700973 for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700974 if (pCreateInfos[idx0].pStages[idx1].module) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700975 skipCall |= validate_shader_module(device, pCreateInfos[idx0].pStages[idx1].module,
976 VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700977 }
978 }
979 }
980 if (pCreateInfos[idx0].renderPass) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700981 skipCall |=
982 validate_render_pass(device, pCreateInfos[idx0].renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700983 }
984 }
985 }
986 if (pipelineCache) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700987 skipCall |= validate_pipeline_cache(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700988 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600989 lock.unlock();
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700990 if (skipCall)
991 return VK_ERROR_VALIDATION_FAILED_EXT;
Jon Ashburn491a3cd2016-03-08 17:48:44 -0700992 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
993 ->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
Jeremy Hayes241a2db2016-04-13 10:54:17 -0600994 lock.lock();
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700995 if (result == VK_SUCCESS) {
996 for (uint32_t idx2 = 0; idx2 < createInfoCount; ++idx2) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -0700997 create_pipeline(device, pPipelines[idx2], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -0700998 }
999 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -06001000 lock.unlock();
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001001 return result;
1002}
1003
Mark Lobodzinskib838dc02016-02-03 09:57:14 -07001004// TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
Jon Ashburn491a3cd2016-03-08 17:48:44 -07001005VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
1006 const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
1007 VkPipeline *pPipelines) {
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001008 VkBool32 skipCall = VK_FALSE;
Jeremy Hayes241a2db2016-04-13 10:54:17 -06001009 std::unique_lock<std::mutex> lock(global_lock);
Mark Lobodzinskib838dc02016-02-03 09:57:14 -07001010 skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001011 if (pCreateInfos) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -07001012 for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001013 if (pCreateInfos[idx0].basePipelineHandle) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -07001014 skipCall |= validate_pipeline(device, pCreateInfos[idx0].basePipelineHandle,
1015 VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001016 }
1017 if (pCreateInfos[idx0].layout) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -07001018 skipCall |= validate_pipeline_layout(device, pCreateInfos[idx0].layout,
1019 VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001020 }
1021 if (pCreateInfos[idx0].stage.module) {
Jon Ashburn491a3cd2016-03-08 17:48:44 -07001022 skipCall |= validate_shader_module(device, pCreateInfos[idx0].stage.module,
1023 VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001024 }
1025 }
1026 }
1027 if (pipelineCache) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -07001028 skipCall |= validate_pipeline_cache(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001029 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -06001030 lock.unlock();
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001031 if (skipCall)
1032 return VK_ERROR_VALIDATION_FAILED_EXT;
Jon Ashburn491a3cd2016-03-08 17:48:44 -07001033 VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
1034 ->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
Jeremy Hayes241a2db2016-04-13 10:54:17 -06001035 lock.lock();
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001036 if (result == VK_SUCCESS) {
1037 for (uint32_t idx1 = 0; idx1 < createInfoCount; ++idx1) {
Mark Lobodzinskib838dc02016-02-03 09:57:14 -07001038 create_pipeline(device, pPipelines[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001039 }
1040 }
Jeremy Hayes241a2db2016-04-13 10:54:17 -06001041 lock.unlock();
Mark Lobodzinski884f0b62016-01-26 09:55:28 -07001042 return result;
1043}