layers: Update object_tracker layer

Removed dead code, added per-instance and per-device object tracking,
(this was broken in codegen'd version with no cross-device
validation), updated for new layer architectures and coding standards,
removed OT-related codegen -- it is now a standalone cpp file.

Change-Id: I64464b855e1b4841c8e3a581387e0e9065b006f7
diff --git a/layers/object_tracker.h b/layers/object_tracker.h
index 18d2cb2..24ed24d 100644
--- a/layers/object_tracker.h
+++ b/layers/object_tracker.h
@@ -15,18 +15,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * Author: Jon Ashburn <jon@lunarg.com>
  * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
  * Author: Tobin Ehlis <tobin@lunarg.com>
  */
 
 #include <mutex>
 
-#include "vulkan/vk_layer.h"
-#include "vk_layer_extension_utils.h"
 #include "vk_enum_string_helper.h"
+#include "vk_layer_extension_utils.h"
 #include "vk_layer_table.h"
 #include "vk_layer_utils.h"
+#include "vulkan/vk_layer.h"
 
 namespace object_tracker {
 
@@ -54,41 +54,23 @@
     OBJSTATUS_COMMAND_BUFFER_SECONDARY = 0x00000040, // Command Buffer is of type SECONDARY
 };
 
+// Object and state information structure
 struct OBJTRACK_NODE {
-    uint64_t vkObj;                     // Object handle
-    VkDebugReportObjectTypeEXT objType; // Object type identifier
-    ObjectStatusFlags status;           // Object state
-    uint64_t parentObj;                 // Parent object
-    uint64_t belongsTo;                 // Object Scope -- owning device/instance
+    uint64_t handle;                        // Object handle (new)
+    VkDebugReportObjectTypeEXT object_type; // Object type identifier
+    ObjectStatusFlags status;               // Object state
+    uint64_t parent_object;                 // Parent object
 };
 
-// prototype for extension functions
-uint64_t objTrackGetObjectCount(VkDevice device);
-uint64_t objTrackGetObjectsOfTypeCount(VkDevice, VkDebugReportObjectTypeEXT type);
-
-// Func ptr typedefs
-typedef uint64_t (*OBJ_TRACK_GET_OBJECT_COUNT)(VkDevice);
-typedef uint64_t (*OBJ_TRACK_GET_OBJECTS_OF_TYPE_COUNT)(VkDevice, VkDebugReportObjectTypeEXT);
-
-struct layer_data {
-    VkInstance instance;
-
-    debug_report_data *report_data;
-    // TODO: put instance data here
-    std::vector<VkDebugReportCallbackEXT> logging_callback;
-    bool wsi_enabled;
-    bool objtrack_extensions_enabled;
-    // The following are for keeping track of the temporary callbacks that can
-    // be used in vkCreateInstance and vkDestroyInstance:
-    uint32_t num_tmp_callbacks;
-    VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
-    VkDebugReportCallbackEXT *tmp_callbacks;
-
-    layer_data()
-        : report_data(nullptr), wsi_enabled(false), objtrack_extensions_enabled(false), num_tmp_callbacks(0),
-          tmp_dbg_create_infos(nullptr), tmp_callbacks(nullptr){};
+// Track Queue information
+struct OT_QUEUE_INFO {
+    uint32_t queue_node_index;
+    VkQueue queue;
 };
 
+// Layer name string to be logged with validation messages.
+const char LayerName[] = "ObjectTracker";
+
 struct instance_extension_enables {
     bool wsi_enabled;
     bool xlib_enabled;
@@ -99,11 +81,8 @@
     bool win32_enabled;
 };
 
-static std::unordered_map<void *, struct instance_extension_enables> instanceExtMap;
-static std::unordered_map<void *, layer_data *> layer_data_map;
-static device_table_map object_tracker_device_table_map;
-static instance_table_map object_tracker_instance_table_map;
-
+/* LUGMAL
+<<<<<<< 373469f006399d6b5204ee05db3b56beb168b36f
 // We need additionally validate image usage using a separate map
 // of swapchain-created images
 static std::unordered_map<uint64_t, OBJTRACK_NODE *> swapchainImageMap;
@@ -136,979 +115,85 @@
 
 static void createInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
     VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(object_tracker_instance_table_map, instance);
+=======
+*/
+struct layer_data {
+    VkInstance instance;
+    VkPhysicalDevice physical_device;
 
-    instanceExtMap[pDisp] = {};
+    uint64_t num_objects[VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT + 1];
+    uint64_t num_total_objects;
 
-    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].wsi_enabled = true;
-        }
-#ifdef VK_USE_PLATFORM_XLIB_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].xlib_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_XCB_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].xcb_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_WAYLAND_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].wayland_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_MIR_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].mir_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].android_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].win32_enabled = true;
-        }
-#endif
-    }
+    debug_report_data *report_data;
+    std::vector<VkDebugReportCallbackEXT> logging_callback;
+    bool wsi_enabled;
+    bool objtrack_extensions_enabled;
 
-}
+    // The following are for keeping track of the temporary callbacks that can
+    // be used in vkCreateInstance and vkDestroyInstance:
+    uint32_t num_tmp_callbacks;
+    VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
+    VkDebugReportCallbackEXT *tmp_callbacks;
 
-// Indicate device or instance dispatch table type
-enum DispTableType {
-    DISP_TBL_TYPE_INSTANCE,
-    DISP_TBL_TYPE_DEVICE,
+    std::vector<VkQueueFamilyProperties> queue_family_properties;
+
+    // Array of unordered_maps per object type to hold OBJTRACK_NODE info
+    std::unordered_map<uint64_t, OBJTRACK_NODE *> object_map[VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT + 1];
+    // Special-case map for swapchain images
+    std::unordered_map<uint64_t, OBJTRACK_NODE *> swapchainImageMap;
+    // Map of queue information structures, one per queue
+    std::unordered_map<VkQueue, OT_QUEUE_INFO *> queue_info_map;
+    // Preinitialized array of name strings for object types
+    // LUGMAL std::unordered_map<VkDebugReportObjectTypeEXT, std::string> object_name;
+
+
+    // Default constructor
+    layer_data()
+        : instance(nullptr), physical_device(nullptr), num_objects{}, num_total_objects(0), report_data(nullptr),
+          wsi_enabled(false), objtrack_extensions_enabled(false), num_tmp_callbacks(0), tmp_dbg_create_infos(nullptr),
+          tmp_callbacks(nullptr), object_map{} {}
 };
 
-debug_report_data *mdd(const void *object) {
-    dispatch_key key = get_dispatch_key(object);
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    return my_data->report_data;
-}
 
-debug_report_data *mid(VkInstance object) {
-    dispatch_key key = get_dispatch_key(object);
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    return my_data->report_data;
-}
+static std::unordered_map<void *, struct instance_extension_enables> instanceExtMap;
+static std::unordered_map<void *, layer_data *> layer_data_map;
+static device_table_map ot_device_table_map;
+static instance_table_map ot_instance_table_map;
+static std::mutex global_lock;
+static uint64_t object_track_index = 0;
 
-// For each Queue's doubly linked-list of mem refs
-struct OT_MEM_INFO {
-    VkDeviceMemory mem;
-    OT_MEM_INFO *pNextMI;
-    OT_MEM_INFO *pPrevMI;
-};
-
-// Track Queue information
-struct OT_QUEUE_INFO {
-    OT_MEM_INFO *pMemRefList;
-    uint32_t queueNodeIndex;
-    VkQueue queue;
-    uint32_t refCount;
-};
-
-// Global map of structures, one per queue
-std::unordered_map<VkQueue, OT_QUEUE_INFO *> queue_info_map;
+// Array of object name strings for OBJECT_TYPE enum conversion
+static const char *object_name[VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT] = {
+    "Unknown",               // VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN
+    "Instance",              // VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT
+    "Physical Device",       // VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT
+    "Device",                // VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT
+    "Queue",                 // VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT
+    "Semaphore",             // VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT
+    "Command Buffer",        // VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT
+    "Fence",                 // VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT
+    "Device Memory",         // VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT
+    "Buffer",                // VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT
+    "Image",                 // VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT
+    "Event",                 // VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT
+    "Query Pool",            // VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT
+    "Buffer View",           // VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT
+    "Image View",            // VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT
+    "Shader Module",         // VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT
+    "Pipeline Cache",        // VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT
+    "Pipeline Layout",       // VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT
+    "Render Pass",           // VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT
+    "Pipeline",              // VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT
+    "Descriptor Set Layout", // VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT
+    "Sampler",               // VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT
+    "Descriptor Pool",       // VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT
+    "Descriptor Set",        // VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT
+    "Framebuffer",           // VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT
+    "Command Pool",          // VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT
+    "SurfaceKHR",            // VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT
+    "SwapchainKHR",          // VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT
+    "Debug Report" };        // VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT
 
 #include "vk_dispatch_table_helper.h"
 
-static void init_object_tracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
-
-    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_object_tracker");
-}
-
-//
-// Forward declarations
-//
-
-static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDevice vkObj, VkDebugReportObjectTypeEXT objType);
-static void create_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType);
-static void create_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
-static void create_device(VkPhysicalDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType);
-static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugReportObjectTypeEXT objType);
-static void create_display_khr(VkPhysicalDevice dispatchable_object, VkDisplayKHR vkObj, VkDebugReportObjectTypeEXT objType);
-static void create_display_mode_khr(VkPhysicalDevice dispatchable_object, VkDisplayModeKHR vkObj, VkDebugReportObjectTypeEXT objType);
-static bool validate_image(VkQueue dispatchable_object, VkImage object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
-static bool validate_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType,
-                                  bool null_allowed);
-static bool validate_physical_device(VkPhysicalDevice dispatchable_object, VkPhysicalDevice object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
-static bool validate_device(VkDevice dispatchable_object, VkDevice object, VkDebugReportObjectTypeEXT objType,
-                                bool null_allowed);
-static bool validate_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object, VkDebugReportObjectTypeEXT objType,
-                                         bool null_allowed);
-static bool validate_descriptor_set_layout(VkDevice dispatchable_object, VkDescriptorSetLayout object,
-                                               VkDebugReportObjectTypeEXT objType, bool null_allowed);
-static bool validate_command_pool(VkDevice dispatchable_object, VkCommandPool object, VkDebugReportObjectTypeEXT objType,
-                                      bool null_allowed);
-static bool validate_buffer(VkQueue dispatchable_object, VkBuffer object, VkDebugReportObjectTypeEXT objType,
-                                bool null_allowed);
-static void create_pipeline(VkDevice dispatchable_object, VkPipeline vkObj, VkDebugReportObjectTypeEXT objType);
-static bool validate_pipeline_cache(VkDevice dispatchable_object, VkPipelineCache object, VkDebugReportObjectTypeEXT objType,
-                                        bool null_allowed);
-static bool validate_render_pass(VkDevice dispatchable_object, VkRenderPass object, VkDebugReportObjectTypeEXT objType,
-                                     bool null_allowed);
-static bool validate_shader_module(VkDevice dispatchable_object, VkShaderModule object, VkDebugReportObjectTypeEXT objType,
-                                       bool null_allowed);
-static bool validate_pipeline_layout(VkDevice dispatchable_object, VkPipelineLayout object, VkDebugReportObjectTypeEXT objType,
-                                         bool null_allowed);
-static bool validate_pipeline(VkDevice dispatchable_object, VkPipeline object, VkDebugReportObjectTypeEXT objType,
-                                  bool null_allowed);
-static bool validate_display_khr(VkPhysicalDevice dispatchable_object, VkDisplayKHR object, VkDebugReportObjectTypeEXT objType,
-                                  bool null_allowed);
-static bool validate_display_mode_khr(VkInstance dispatchable_object, VkDisplayModeKHR object, VkDebugReportObjectTypeEXT objType,
-                                  bool null_allowed);
-static void destroy_command_pool(VkDevice dispatchable_object, VkCommandPool object);
-static void destroy_descriptor_pool(VkDevice dispatchable_object, VkDescriptorPool object);
-static void destroy_descriptor_set(VkDevice dispatchable_object, VkDescriptorSet object);
-static void destroy_device_memory(VkDevice dispatchable_object, VkDeviceMemory object);
-static void destroy_swapchain_khr(VkDevice dispatchable_object, VkSwapchainKHR object);
-static bool set_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeEXT objType,
-                                         ObjectStatusFlags status_flag);
-static bool reset_device_memory_status(VkDevice dispatchable_object, VkDeviceMemory object, VkDebugReportObjectTypeEXT objType,
-                                           ObjectStatusFlags status_flag);
-static void destroy_queue(VkQueue dispatchable_object, VkQueue object);
-
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkPhysicalDeviceMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkDeviceMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkImageMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkQueueMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkDescriptorSetMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkBufferMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkFenceMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkSemaphoreMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkCommandPoolMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkCommandBufferMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkSwapchainKHRMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkSurfaceKHRMap;
-extern std::unordered_map<uint64_t, OBJTRACK_NODE *> VkQueueMap;
-
-// Convert an object type enum to an object type array index
-static uint32_t objTypeToIndex(uint32_t objType) {
-    uint32_t index = objType;
-    return index;
-}
-
-// Add new queue to head of global queue list
-static void addQueueInfo(uint32_t queueNodeIndex, VkQueue queue) {
-    auto queueItem = queue_info_map.find(queue);
-    if (queueItem == queue_info_map.end()) {
-        OT_QUEUE_INFO *p_queue_info = new OT_QUEUE_INFO;
-        if (p_queue_info != NULL) {
-            memset(p_queue_info, 0, sizeof(OT_QUEUE_INFO));
-            p_queue_info->queue = queue;
-            p_queue_info->queueNodeIndex = queueNodeIndex;
-            queue_info_map[queue] = p_queue_info;
-        } else {
-            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",
-                    "ERROR:  VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
-        }
-    }
-}
-
-// Destroy memRef lists and free all memory
-static void destroyQueueMemRefLists() {
-    for (auto queue_item : queue_info_map) {
-        OT_MEM_INFO *p_mem_info = queue_item.second->pMemRefList;
-        while (p_mem_info != NULL) {
-            OT_MEM_INFO *p_del_mem_info = p_mem_info;
-            p_mem_info = p_mem_info->pNextMI;
-            delete p_del_mem_info;
-        }
-        delete queue_item.second;
-    }
-    queue_info_map.clear();
-
-    // Destroy the items in the queue map
-    auto queue = VkQueueMap.begin();
-    while (queue != VkQueueMap.end()) {
-        uint32_t obj_index = objTypeToIndex(queue->second->objType);
-        assert(numTotalObjs > 0);
-        numTotalObjs--;
-        assert(numObjs[obj_index] > 0);
-        numObjs[obj_index]--;
-        log_msg(mdd(reinterpret_cast<VkQueue>(queue->second->vkObj)), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, queue->second->objType,
-                queue->second->vkObj, __LINE__, OBJTRACK_NONE, "OBJTRACK",
-                "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
-                string_VkDebugReportObjectTypeEXT(queue->second->objType), queue->second->vkObj, numTotalObjs, numObjs[obj_index],
-                string_VkDebugReportObjectTypeEXT(queue->second->objType));
-        delete queue->second;
-        queue = VkQueueMap.erase(queue);
-    }
-}
-
-// Check Queue type flags for selected queue operations
-static void validateQueueFlags(VkQueue queue, const char *function) {
-
-    auto queue_item = queue_info_map.find(queue);
-    if (queue_item != queue_info_map.end()) {
-        OT_QUEUE_INFO *pQueueInfo = queue_item->second;
-        if (pQueueInfo != NULL) {
-            if ((queue_family_properties[pQueueInfo->queueNodeIndex].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
-                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",
-                        "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set", function);
-            }
-        }
-    }
-}
-
-static void create_physical_device(VkInstance instance, VkPhysicalDevice vkObj, VkDebugReportObjectTypeEXT objType) {
-    log_msg(mdd(instance), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__,
-            OBJTRACK_NONE, "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
-
-    uint64_t physical_device_handle = reinterpret_cast<uint64_t>(vkObj);
-    auto pd_item = VkPhysicalDeviceMap.find(physical_device_handle);
-    if (pd_item == VkPhysicalDeviceMap.end()) {
-        OBJTRACK_NODE *p_new_obj_node = new OBJTRACK_NODE;
-        p_new_obj_node->objType = objType;
-        p_new_obj_node->belongsTo = reinterpret_cast<uint64_t>(instance);
-        p_new_obj_node->status = OBJSTATUS_NONE;
-        p_new_obj_node->vkObj = physical_device_handle;
-        VkPhysicalDeviceMap[physical_device_handle] = p_new_obj_node;
-        uint32_t objIndex = objTypeToIndex(objType);
-        numObjs[objIndex]++;
-        numTotalObjs++;
-    }
-}
-
-static void create_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR vkObj, VkDebugReportObjectTypeEXT objType) {
-    // TODO: Add tracking of surface objects
-    log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), (uint64_t)(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->objType = objType;
-    pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->vkObj = (uint64_t)(vkObj);
-    VkSurfaceKHRMap[(uint64_t)vkObj] = pNewObjNode;
-    uint32_t objIndex = objTypeToIndex(objType);
-    numObjs[objIndex]++;
-    numTotalObjs++;
-}
-
-static void destroy_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR object) {
-    uint64_t object_handle = (uint64_t)(object);
-    if (VkSurfaceKHRMap.find(object_handle) != VkSurfaceKHRMap.end()) {
-        OBJTRACK_NODE *pNode = VkSurfaceKHRMap[(uint64_t)object];
-        uint32_t objIndex = objTypeToIndex(pNode->objType);
-        assert(numTotalObjs > 0);
-        numTotalObjs--;
-        assert(numObjs[objIndex] > 0);
-        numObjs[objIndex]--;
-        log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType, object_handle, __LINE__,
-                OBJTRACK_NONE, "OBJTRACK",
-                "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (0x%" PRIx64 " total objs remain & 0x%" PRIx64 " %s objs).",
-                string_VkDebugReportObjectTypeEXT(pNode->objType), (uint64_t)(object), numTotalObjs, numObjs[objIndex],
-                string_VkDebugReportObjectTypeEXT(pNode->objType));
-        delete pNode;
-        VkSurfaceKHRMap.erase(object_handle);
-    } else {
-        log_msg(mdd(dispatchable_object), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__,
-                OBJTRACK_NONE, "OBJTRACK",
-                "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", object_handle);
-    }
-}
-
-static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer vkObj,
-                                 VkDebugReportObjectTypeEXT objType, VkCommandBufferLevel level) {
-    log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->objType = objType;
-    pNewObjNode->belongsTo = (uint64_t)device;
-    pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
-    pNewObjNode->parentObj = (uint64_t)commandPool;
-    if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
-        pNewObjNode->status = OBJSTATUS_COMMAND_BUFFER_SECONDARY;
-    } else {
-        pNewObjNode->status = OBJSTATUS_NONE;
-    }
-    VkCommandBufferMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
-    uint32_t objIndex = objTypeToIndex(objType);
-    numObjs[objIndex]++;
-    numTotalObjs++;
-}
-
-static bool validate_command_buffer(VkDevice device, VkCommandPool commandPool, VkCommandBuffer commandBuffer) {
-    bool skipCall = false;
-    uint64_t object_handle = reinterpret_cast<uint64_t>(commandBuffer);
-    if (VkCommandBufferMap.find(object_handle) != VkCommandBufferMap.end()) {
-        OBJTRACK_NODE *pNode = VkCommandBufferMap[(uint64_t)commandBuffer];
-
-        if (pNode->parentObj != (uint64_t)(commandPool)) {
-            skipCall |= log_msg(
-                mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, object_handle, __LINE__, OBJTRACK_COMMAND_POOL_MISMATCH,
-                "OBJTRACK", "FreeCommandBuffers is attempting to free Command Buffer 0x%" PRIxLEAST64
-                            " belonging to Command Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
-                reinterpret_cast<uint64_t>(commandBuffer), pNode->parentObj, reinterpret_cast<uint64_t &>(commandPool));
-        }
-    } else {
-        skipCall |= log_msg(
-            mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", object_handle);
-    }
-    return skipCall;
-}
-
-static bool free_command_buffer(VkDevice device, VkCommandBuffer commandBuffer) {
-    bool skipCall = false;
-    auto cbItem = VkCommandBufferMap.find(reinterpret_cast<uint64_t>(commandBuffer));
-    if (cbItem != VkCommandBufferMap.end()) {
-        OBJTRACK_NODE *pNode = cbItem->second;
-        uint32_t objIndex = objTypeToIndex(pNode->objType);
-        assert(numTotalObjs > 0);
-        numTotalObjs--;
-        assert(numObjs[objIndex] > 0);
-        numObjs[objIndex]--;
-        skipCall |= log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType,
-                            reinterpret_cast<uint64_t>(commandBuffer), __LINE__, OBJTRACK_NONE, "OBJTRACK",
-                            "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
-                            string_VkDebugReportObjectTypeEXT(pNode->objType), reinterpret_cast<uint64_t>(commandBuffer),
-                            numTotalObjs, numObjs[objIndex], string_VkDebugReportObjectTypeEXT(pNode->objType));
-        delete pNode;
-        VkCommandBufferMap.erase(cbItem);
-    }
-    return skipCall;
-}
-
-static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet vkObj,
-                                 VkDebugReportObjectTypeEXT objType) {
-    log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE, "OBJTRACK",
-            "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++, string_VkDebugReportObjectTypeEXT(objType),
-            (uint64_t)(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->objType = objType;
-    pNewObjNode->belongsTo = (uint64_t)device;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->vkObj = (uint64_t)(vkObj);
-    pNewObjNode->parentObj = (uint64_t)descriptorPool;
-    VkDescriptorSetMap[(uint64_t)vkObj] = pNewObjNode;
-    uint32_t objIndex = objTypeToIndex(objType);
-    numObjs[objIndex]++;
-    numTotalObjs++;
-}
-
-static bool validate_descriptor_set(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSet descriptorSet) {
-    bool skipCall = false;
-    uint64_t object_handle = reinterpret_cast<uint64_t &>(descriptorSet);
-    auto dsItem = VkDescriptorSetMap.find(object_handle);
-    if (dsItem != VkDescriptorSetMap.end()) {
-        OBJTRACK_NODE *pNode = dsItem->second;
-
-        if (pNode->parentObj != reinterpret_cast<uint64_t &>(descriptorPool)) {
-            skipCall |= log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, object_handle, __LINE__,
-                                OBJTRACK_DESCRIPTOR_POOL_MISMATCH, "OBJTRACK",
-                                "FreeDescriptorSets is attempting to free descriptorSet 0x%" PRIxLEAST64
-                                " belonging to Descriptor Pool 0x%" PRIxLEAST64 " from pool 0x%" PRIxLEAST64 ").",
-                                reinterpret_cast<uint64_t &>(descriptorSet), pNode->parentObj,
-                                reinterpret_cast<uint64_t &>(descriptorPool));
-        }
-    } else {
-        skipCall |= log_msg(
-            mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "Unable to remove obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", object_handle);
-    }
-    return skipCall;
-}
-
-static bool free_descriptor_set(VkDevice device, VkDescriptorSet descriptorSet) {
-    bool skipCall = false;
-    auto dsItem = VkDescriptorSetMap.find(reinterpret_cast<uint64_t &>(descriptorSet));
-    if (dsItem != VkDescriptorSetMap.end()) {
-        OBJTRACK_NODE *pNode = dsItem->second;
-        uint32_t objIndex = objTypeToIndex(pNode->objType);
-        assert(numTotalObjs > 0);
-        numTotalObjs--;
-        assert(numObjs[objIndex] > 0);
-        numObjs[objIndex]--;
-        skipCall |= log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->objType,
-                            reinterpret_cast<uint64_t &>(descriptorSet), __LINE__, OBJTRACK_NONE, "OBJTRACK",
-                            "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
-                            string_VkDebugReportObjectTypeEXT(pNode->objType), reinterpret_cast<uint64_t &>(descriptorSet),
-                            numTotalObjs, numObjs[objIndex], string_VkDebugReportObjectTypeEXT(pNode->objType));
-        delete pNode;
-        VkDescriptorSetMap.erase(dsItem);
-    }
-    return skipCall;
-}
-
-static void create_queue(VkDevice device, VkQueue vkObj, VkDebugReportObjectTypeEXT objType) {
-
-    log_msg(mdd(device), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, reinterpret_cast<uint64_t>(vkObj), __LINE__,
-            OBJTRACK_NONE, "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), reinterpret_cast<uint64_t>(vkObj));
-
-    OBJTRACK_NODE *p_obj_node = NULL;
-    auto queue_item = VkQueueMap.find(reinterpret_cast<uint64_t>(vkObj));
-    if (queue_item == VkQueueMap.end()) {
-        p_obj_node = new OBJTRACK_NODE;
-        VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = p_obj_node;
-        uint32_t objIndex = objTypeToIndex(objType);
-        numObjs[objIndex]++;
-        numTotalObjs++;
-    } else {
-        p_obj_node = queue_item->second;
-    }
-    p_obj_node->objType = objType;
-    p_obj_node->belongsTo = reinterpret_cast<uint64_t>(device);
-    p_obj_node->status = OBJSTATUS_NONE;
-    p_obj_node->vkObj = reinterpret_cast<uint64_t>(vkObj);
-}
-
-static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkObj, VkSwapchainKHR swapchain) {
-    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", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            "SwapchainImage", (uint64_t)(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
-    pNewObjNode->objType = VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->vkObj = (uint64_t)vkObj;
-    pNewObjNode->parentObj = (uint64_t)swapchain;
-    swapchainImageMap[(uint64_t)(vkObj)] = pNewObjNode;
-}
-
-static void create_device(VkInstance dispatchable_object, VkDevice vkObj, VkDebugReportObjectTypeEXT objType) {
-    log_msg(mid(dispatchable_object), VK_DEBUG_REPORT_INFORMATION_BIT_EXT, objType, (uint64_t)(vkObj), __LINE__, OBJTRACK_NONE,
-            "OBJTRACK", "OBJ[%llu] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            string_VkDebugReportObjectTypeEXT(objType), (uint64_t)(vkObj));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
-    pNewObjNode->objType = objType;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->vkObj = (uint64_t)(vkObj);
-    VkDeviceMap[(uint64_t)vkObj] = pNewObjNode;
-    uint32_t objIndex = objTypeToIndex(objType);
-    numObjs[objIndex]++;
-    numTotalObjs++;
-}
-
-//
-// Non-auto-generated API functions called by generated code
-//
-VkResult explicit_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
-                                 VkInstance *pInstance) {
-    VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
-
-    assert(chain_info->u.pLayerInfo);
-    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
-    if (fpCreateInstance == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    // Advance the link info for the next element on the chain
-    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
-
-    VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
-    if (result != VK_SUCCESS) {
-        return result;
-    }
-
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
-    my_data->instance = *pInstance;
-    initInstanceTable(*pInstance, fpGetInstanceProcAddr, object_tracker_instance_table_map);
-    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, *pInstance);
-
-    // Look for one or more debug report create info structures, and copy the
-    // callback(s) for each one found (for use by vkDestroyInstance)
-    layer_copy_tmp_callbacks(pCreateInfo->pNext, &my_data->num_tmp_callbacks, &my_data->tmp_dbg_create_infos,
-                             &my_data->tmp_callbacks);
-
-    my_data->report_data = debug_report_create_instance(pInstanceTable, *pInstance, pCreateInfo->enabledExtensionCount,
-                                                        pCreateInfo->ppEnabledExtensionNames);
-
-    init_object_tracker(my_data, pAllocator);
-    createInstanceRegisterExtensions(pCreateInfo, *pInstance);
-
-    create_instance(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
-
-    return result;
-}
-
-void explicit_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice gpu, uint32_t *pCount, VkQueueFamilyProperties *pProperties) {
-    get_dispatch_table(object_tracker_instance_table_map, gpu)->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);
-
-    std::lock_guard<std::mutex> lock(global_lock);
-    if (pProperties != NULL) {
-        for (uint32_t i = 0; i < *pCount; i++) {
-            queue_family_properties.emplace_back(pProperties[i]);
-        }
-    }
-}
-
-VkResult explicit_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
-                               VkDevice *pDevice) {
-    std::lock_guard<std::mutex> lock(global_lock);
-    layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
-    VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
-
-    assert(chain_info->u.pLayerInfo);
-    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
-    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
-    if (fpCreateDevice == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    // Advance the link info for the next element on the chain
-    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
-
-    VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
-    if (result != VK_SUCCESS) {
-        return result;
-    }
-
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
-    my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
-
-    initDeviceTable(*pDevice, fpGetDeviceProcAddr, object_tracker_device_table_map);
-
-    createDeviceRegisterExtensions(pCreateInfo, *pDevice);
-
-    if (VkPhysicalDeviceMap.find((uint64_t)gpu) != VkPhysicalDeviceMap.end()) {
-        OBJTRACK_NODE *pNewObjNode = VkPhysicalDeviceMap[(uint64_t)gpu];
-        create_device((VkInstance)pNewObjNode->belongsTo, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
-    }
-
-    return result;
-}
-
-VkResult explicit_EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
-                                           VkPhysicalDevice *pPhysicalDevices) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_instance(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
-    lock.unlock();
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = get_dispatch_table(object_tracker_instance_table_map, instance)
-                          ->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
-    lock.lock();
-    if (result == VK_SUCCESS) {
-        if (pPhysicalDevices) {
-            for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
-                create_physical_device(instance, pPhysicalDevices[i], VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT);
-            }
-        }
-    }
-    lock.unlock();
-    return result;
-}
-
-void explicit_GetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue *pQueue) {
-    std::unique_lock<std::mutex> lock(global_lock);
-    validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-
-    get_dispatch_table(object_tracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
-
-    lock.lock();
-
-    create_queue(device, *pQueue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT);
-    addQueueInfo(queueNodeIndex, *pQueue);
-}
-
-VkResult explicit_MapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags,
-                            void **ppData) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-    if (skipCall == VK_TRUE)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-
-    VkResult result =
-        get_dispatch_table(object_tracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
-
-    return result;
-}
-
-void explicit_UnmapMemory(VkDevice device, VkDeviceMemory mem) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-    if (skipCall == VK_TRUE)
-        return;
-
-    get_dispatch_table(object_tracker_device_table_map, device)->UnmapMemory(device, mem);
-}
-
-VkResult explicit_QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence) {
-    std::unique_lock<std::mutex> lock(global_lock);
-    validateQueueFlags(queue, "QueueBindSparse");
-
-    for (uint32_t i = 0; i < bindInfoCount; i++) {
-        for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
-            validate_buffer(queue, pBindInfo[i].pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
-            validate_image(queue, pBindInfo[i].pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-        for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
-            validate_image(queue, pBindInfo[i].pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-    }
-    lock.unlock();
-
-    VkResult result =
-        get_dispatch_table(object_tracker_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
-    return result;
-}
-
-VkResult explicit_AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo,
-                                         VkCommandBuffer *pCommandBuffers) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skipCall |= validate_command_pool(device, pAllocateInfo->commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
-    lock.unlock();
-
-    if (skipCall) {
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    }
-
-    VkResult result =
-        get_dispatch_table(object_tracker_device_table_map, device)->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
-
-    lock.lock();
-    for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
-        alloc_command_buffer(device, pAllocateInfo->commandPool, pCommandBuffers[i], VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                             pAllocateInfo->level);
-    }
-    lock.unlock();
-
-    return result;
-}
-
-VkResult explicit_AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
-                                         VkDescriptorSet *pDescriptorSets) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skipCall |=
-        validate_descriptor_pool(device, pAllocateInfo->descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
-    for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
-        skipCall |= validate_descriptor_set_layout(device, pAllocateInfo->pSetLayouts[i],
-                                                   VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
-    }
-    lock.unlock();
-    if (skipCall) {
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    }
-
-    VkResult result =
-        get_dispatch_table(object_tracker_device_table_map, device)->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
-
-    if (VK_SUCCESS == result) {
-        lock.lock();
-        for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
-            alloc_descriptor_set(device, pAllocateInfo->descriptorPool, pDescriptorSets[i],
-                                 VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
-        }
-        lock.unlock();
-    }
-
-    return result;
-}
-
-void explicit_FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
-                                 const VkCommandBuffer *pCommandBuffers) {
-    bool skipCall = false;
-    std::unique_lock<std::mutex> lock(global_lock);
-    validate_command_pool(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
-    validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    for (uint32_t i = 0; i < commandBufferCount; i++) {
-        skipCall |= validate_command_buffer(device, commandPool, pCommandBuffers[i]);
-    }
-
-    lock.unlock();
-    if (!skipCall) {
-        get_dispatch_table(object_tracker_device_table_map, device)
-            ->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
-    }
-
-    lock.lock();
-    for (uint32_t i = 0; i < commandBufferCount; i++) {
-        free_command_buffer(device, pCommandBuffers[i]);
-    }
-}
-
-void explicit_DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
-    std::unique_lock<std::mutex> lock(global_lock);
-    // A swapchain's images are implicitly deleted when the swapchain is deleted.
-    // Remove this swapchain's images from our map of such images.
-    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = swapchainImageMap.begin();
-    while (itr != swapchainImageMap.end()) {
-        OBJTRACK_NODE *pNode = (*itr).second;
-        if (pNode->parentObj == reinterpret_cast<uint64_t &>(swapchain)) {
-            delete pNode;
-            swapchainImageMap.erase(itr++);
-        } else {
-            ++itr;
-        }
-    }
-    destroy_swapchain_khr(device, swapchain);
-    lock.unlock();
-
-    get_dispatch_table(object_tracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
-}
-
-void explicit_FreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
-    std::unique_lock<std::mutex> lock(global_lock);
-    validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-
-    get_dispatch_table(object_tracker_device_table_map, device)->FreeMemory(device, mem, pAllocator);
-
-    lock.lock();
-    destroy_device_memory(device, mem);
-}
-
-VkResult explicit_FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count,
-                                     const VkDescriptorSet *pDescriptorSets) {
-    bool skipCall = false;
-    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_descriptor_pool(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    for (uint32_t i = 0; i < count; i++) {
-        skipCall |= validate_descriptor_set(device, descriptorPool, pDescriptorSets[i]);
-    }
-
-    lock.unlock();
-    if (!skipCall) {
-        result = get_dispatch_table(object_tracker_device_table_map, device)
-                     ->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
-    }
-
-    lock.lock();
-    for (uint32_t i = 0; i < count; i++) {
-        free_descriptor_set(device, pDescriptorSets[i]);
-    }
-    return result;
-}
-
-void explicit_DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skipCall |= validate_descriptor_pool(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
-    lock.unlock();
-    if (skipCall) {
-        return;
-    }
-    // A DescriptorPool's descriptor sets are implicitly deleted when the pool is deleted.
-    // Remove this pool's descriptor sets from our descriptorSet map.
-    lock.lock();
-    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = VkDescriptorSetMap.begin();
-    while (itr != VkDescriptorSetMap.end()) {
-        OBJTRACK_NODE *pNode = (*itr).second;
-        auto del_itr = itr++;
-        if (pNode->parentObj == (uint64_t)(descriptorPool)) {
-            destroy_descriptor_set(device, (VkDescriptorSet)((*del_itr).first));
-        }
-    }
-    destroy_descriptor_pool(device, descriptorPool);
-    lock.unlock();
-    get_dispatch_table(object_tracker_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
-}
-
-void explicit_DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
-    bool skipCall = false;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skipCall |= validate_command_pool(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
-    lock.unlock();
-    if (skipCall) {
-        return;
-    }
-    lock.lock();
-    // A CommandPool's command buffers are implicitly deleted when the pool is deleted.
-    // Remove this pool's cmdBuffers from our cmd buffer map.
-    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator itr = VkCommandBufferMap.begin();
-    std::unordered_map<uint64_t, OBJTRACK_NODE *>::iterator del_itr;
-    while (itr != VkCommandBufferMap.end()) {
-        OBJTRACK_NODE *pNode = (*itr).second;
-        del_itr = itr++;
-        if (pNode->parentObj == (uint64_t)(commandPool)) {
-            skipCall |= validate_command_buffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
-            free_command_buffer(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
-        }
-    }
-    destroy_command_pool(device, commandPool);
-    lock.unlock();
-    get_dispatch_table(object_tracker_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
-}
-
-VkResult explicit_GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pCount, VkImage *pSwapchainImages) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    lock.unlock();
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-
-    VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
-                          ->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
-
-    if (pSwapchainImages != NULL) {
-        lock.lock();
-        for (uint32_t i = 0; i < *pCount; i++) {
-            create_swapchain_image_obj(device, pSwapchainImages[i], swapchain);
-        }
-        lock.unlock();
-    }
-    return result;
-}
-
-#ifndef __ANDROID__
-VkResult explicit_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties)
-{
-    bool skipCall = false;
-    {
-        std::lock_guard<std::mutex> lock(global_lock);
-        if (physicalDevice) {
-            skipCall |= validate_physical_device(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
-        }
-    }
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = get_dispatch_table(object_tracker_instance_table_map, physicalDevice)->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
-        if (VK_SUCCESS == result && pProperties) {
-            std::lock_guard<std::mutex> lock(global_lock);
-            for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
-                if (pProperties[idx0].display) {
-                    create_display_khr(physicalDevice, pProperties[idx0].display, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT);
-                }
-            }
-        }
-    return result;
-}
-
-VkResult explicit_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties)
-{
-    bool skipCall = false;
-    {
-        std::lock_guard<std::mutex> lock(global_lock);
-        skipCall |= validate_display_khr(physicalDevice, display, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, false);
-        if (physicalDevice) {
-            skipCall |= validate_physical_device(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
-        }
-    }
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = get_dispatch_table(object_tracker_instance_table_map, physicalDevice)->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
-    if (VK_SUCCESS == result && pProperties) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
-            if (pProperties[idx0].displayMode) {
-                create_display_mode_khr(physicalDevice, pProperties[idx0].displayMode, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT);
-            }
-        }
-    }
-    return result;
-}
-#endif
-
-// TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
-VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
-                                          const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
-                                          VkPipeline *pPipelines) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    if (pCreateInfos) {
-        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
-            if (pCreateInfos[idx0].basePipelineHandle) {
-                skipCall |= validate_pipeline(device, pCreateInfos[idx0].basePipelineHandle,
-                                              VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
-            }
-            if (pCreateInfos[idx0].layout) {
-                skipCall |= validate_pipeline_layout(device, pCreateInfos[idx0].layout,
-                                                     VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
-            }
-            if (pCreateInfos[idx0].pStages) {
-                for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
-                    if (pCreateInfos[idx0].pStages[idx1].module) {
-                        skipCall |= validate_shader_module(device, pCreateInfos[idx0].pStages[idx1].module,
-                                                           VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
-                    }
-                }
-            }
-            if (pCreateInfos[idx0].renderPass) {
-                skipCall |=
-                    validate_render_pass(device, pCreateInfos[idx0].renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
-            }
-        }
-    }
-    if (pipelineCache) {
-        skipCall |= validate_pipeline_cache(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
-    }
-    lock.unlock();
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
-                          ->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
-    lock.lock();
-    if (result == VK_SUCCESS) {
-        for (uint32_t idx2 = 0; idx2 < createInfoCount; ++idx2) {
-            create_pipeline(device, pPipelines[idx2], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
-        }
-    }
-    lock.unlock();
-    return result;
-}
-
-// TODO: Add special case to codegen to cover validating all the pipelines instead of just the first
-VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
-                                         const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
-                                         VkPipeline *pPipelines) {
-    bool skipCall = VK_FALSE;
-    std::unique_lock<std::mutex> lock(global_lock);
-    skipCall |= validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    if (pCreateInfos) {
-        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
-            if (pCreateInfos[idx0].basePipelineHandle) {
-                skipCall |= validate_pipeline(device, pCreateInfos[idx0].basePipelineHandle,
-                                              VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
-            }
-            if (pCreateInfos[idx0].layout) {
-                skipCall |= validate_pipeline_layout(device, pCreateInfos[idx0].layout,
-                                                     VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
-            }
-            if (pCreateInfos[idx0].stage.module) {
-                skipCall |= validate_shader_module(device, pCreateInfos[idx0].stage.module,
-                                                   VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
-            }
-        }
-    }
-    if (pipelineCache) {
-        skipCall |= validate_pipeline_cache(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
-    }
-    lock.unlock();
-    if (skipCall)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = get_dispatch_table(object_tracker_device_table_map, device)
-                          ->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
-    lock.lock();
-    if (result == VK_SUCCESS) {
-        for (uint32_t idx1 = 0; idx1 < createInfoCount; ++idx1) {
-            create_pipeline(device, pPipelines[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
-        }
-    }
-    lock.unlock();
-    return result;
-}
-
 } // namespace object_tracker