diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2016-07-01 10:53:31 -0600 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2016-07-22 11:32:25 -0600 |
| commit | 4d8dde0dea50100cf2fabd85b7f1c2d2d95311eb (patch) | |
| tree | 53137de0a3a9793dda9fc57e6234ec3438344f02 /layers/object_tracker.h | |
| parent | 1606eb9bdeb72ae5dc1640b66c3936b395936fcd (diff) | |
| download | usermoji-4d8dde0dea50100cf2fabd85b7f1c2d2d95311eb.tar.xz | |
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
Diffstat (limited to 'layers/object_tracker.h')
| -rw-r--r-- | layers/object_tracker.h | 1085 |
1 files changed, 85 insertions, 1000 deletions
diff --git a/layers/object_tracker.h b/layers/object_tracker.h index 18d2cb20..24ed24d3 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 @@ enum ObjectStatusFlagBits { 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 @@ struct instance_extension_enables { 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 createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo 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; -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; -} + // 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; -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; -} -// For each Queue's doubly linked-list of mem refs -struct OT_MEM_INFO { - VkDeviceMemory mem; - OT_MEM_INFO *pNextMI; - OT_MEM_INFO *pPrevMI; + // 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{} {} }; -// 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; +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; + +// 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 |
