17b06221f2c4cb2205e0363afe1ce59b81aa144a1Mark Young/* Copyright (c) 2015-2017 The Khronos Group Inc. 27b06221f2c4cb2205e0363afe1ce59b81aa144a1Mark Young * Copyright (c) 2015-2017 Valve Corporation 37b06221f2c4cb2205e0363afe1ce59b81aa144a1Mark Young * Copyright (c) 2015-2017 LunarG, Inc. 47b06221f2c4cb2205e0363afe1ce59b81aa144a1Mark Young * Copyright (C) 2015-2017 Google Inc. 5acab8885d3e8c1fdcbfb8ebf9c52168148da63b5Tobin Ehlis * 643b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Licensed under the Apache License, Version 2.0 (the "License"); 743b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * you may not use this file except in compliance with the License. 843b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * You may obtain a copy of the License at 9acab8885d3e8c1fdcbfb8ebf9c52168148da63b5Tobin Ehlis * 1043b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * http://www.apache.org/licenses/LICENSE-2.0 11acab8885d3e8c1fdcbfb8ebf9c52168148da63b5Tobin Ehlis * 1243b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Unless required by applicable law or agreed to in writing, software 1343b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * distributed under the License is distributed on an "AS IS" BASIS, 1443b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1543b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * See the License for the specific language governing permissions and 1643b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * limitations under the License. 1796cd795bb585711057cd90d37a2251419384c937Courtney Goeltzenleuchter * 1896cd795bb585711057cd90d37a2251419384c937Courtney Goeltzenleuchter * Author: Mark Lobodzinski <mark@lunarg.com> 192faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski * Author: Jon Ashburn <jon@lunarg.com> 2096cd795bb585711057cd90d37a2251419384c937Courtney Goeltzenleuchter * Author: Tobin Ehlis <tobin@lunarg.com> 21acab8885d3e8c1fdcbfb8ebf9c52168148da63b5Tobin Ehlis */ 22acab8885d3e8c1fdcbfb8ebf9c52168148da63b5Tobin Ehlis 23241a2dbc046af61b3af566c7429f3e42aa49b286Jeremy Hayes#include <mutex> 2454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include <cinttypes> 2554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include <stdio.h> 2654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include <stdlib.h> 2754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include <string.h> 2854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include <unordered_map> 29241a2dbc046af61b3af566c7429f3e42aa49b286Jeremy Hayes 3054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_loader_platform.h" 3154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vulkan/vulkan.h" 3254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_layer_config.h" 3354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_layer_data.h" 3454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_layer_logging.h" 3554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_layer_table.h" 3654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_object_types.h" 3754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vulkan/vk_layer.h" 3854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_object_types.h" 391c7c65d3f9d68d5869da97ceb1a365a739623fe9Courtney Goeltzenleuchter#include "vk_enum_string_helper.h" 402faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski#include "vk_layer_extension_utils.h" 412bdf6da2d55b916479f90c87797ff20ddbb14fd9Courtney Goeltzenleuchter#include "vk_layer_table.h" 42d11c4ee2bd2a5672093d76630d895e824ee1a571Mark Lobodzinski#include "vk_layer_utils.h" 432faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski#include "vulkan/vk_layer.h" 4454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_dispatch_table_helper.h" 4554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski#include "vk_validation_error_messages.h" 4614305ad4363dd22e47118a76bc89376e5b291645Mark Lobodzinski 471c0b73114010d6eb49ff34243fa9474493ef6eaeChia-I Wunamespace object_tracker { 481c0b73114010d6eb49ff34243fa9474493ef6eaeChia-I Wu 493c26a547b82bacdf9a378eb5bff0a5e7782f9379Tobin Ehlis// Object Tracker ERROR codes 50da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinskienum ObjectTrackerError { 5154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski OBJTRACK_NONE, // Used for INFO & other non-error messages 5254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski OBJTRACK_UNKNOWN_OBJECT, // Updating uses of object that's not in global object list 5354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski OBJTRACK_INTERNAL_ERROR, // Bug with data tracking within the layer 5454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski OBJTRACK_OBJECT_LEAK, // OBJECT was not correctly freed/destroyed 556cb97f9b4cb894c01e9efbc065ef11fc9f6221b6Mark Lobodzinski}; 563c26a547b82bacdf9a378eb5bff0a5e7782f9379Tobin Ehlis 57235c20eeb60a1b09c15001ff90c48b89012eb0b9Tobin Ehlis// Object Status -- used to track state of individual objects 587d2d5ac7de9151a23b866b0b1e1380d184b41e69Mark Lobodzinskitypedef VkFlags ObjectStatusFlags; 596cb97f9b4cb894c01e9efbc065ef11fc9f6221b6Mark Lobodzinskienum ObjectStatusFlagBits { 60cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_NONE = 0x00000000, // No status is set 61cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_FENCE_IS_SUBMITTED = 0x00000001, // Fence has been submitted 62cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_VIEWPORT_BOUND = 0x00000002, // Viewport state object has been bound 63cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_RASTER_BOUND = 0x00000004, // Viewport state object has been bound 64cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_COLOR_BLEND_BOUND = 0x00000008, // Viewport state object has been bound 65cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010, // Viewport state object has been bound 66cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_GPU_MEM_MAPPED = 0x00000020, // Memory object is currently mapped 67cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_COMMAND_BUFFER_SECONDARY = 0x00000040, // Command Buffer is of type SECONDARY 68cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski OBJSTATUS_CUSTOM_ALLOCATOR = 0x00000080, // Allocated with custom allocator 696cb97f9b4cb894c01e9efbc065ef11fc9f6221b6Mark Lobodzinski}; 70acab8885d3e8c1fdcbfb8ebf9c52168148da63b5Tobin Ehlis 712faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski// Object and state information structure 72da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinskistruct ObjTrackState { 7354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski uint64_t handle; // Object handle (new) 7454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski VulkanObjectType object_type; // Object type identifier 7554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski ObjectStatusFlags status; // Object state 7654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski uint64_t parent_object; // Parent object 776cb97f9b4cb894c01e9efbc065ef11fc9f6221b6Mark Lobodzinski}; 78e1d3f0c689c3697d2e8b316fef899d7c7cb75faeMark Lobodzinski 792faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski// Track Queue information 80da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinskistruct ObjTrackQueueInfo { 812faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski uint32_t queue_node_index; 822faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski VkQueue queue; 8373bb657499347bd40990c742af60e63bb03426f3Cody Northrop}; 8414305ad4363dd22e47118a76bc89376e5b291645Mark Lobodzinski 852faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski// Layer name string to be logged with validation messages. 862faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinskiconst char LayerName[] = "ObjectTracker"; 872faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski 88da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinskitypedef std::unordered_map<uint64_t, ObjTrackState *> object_map_type; 89c90f49426aa0ce60a0c381ebc3bef68da91f67a2Mark Lobodzinski 902faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinskistruct layer_data { 912faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski VkInstance instance; 922faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski VkPhysicalDevice physical_device; 93dc87a3ff47dee440b96bdfb385d90d2e271188d9Mark Lobodzinski 94b8a5f6bc08c0c75977f64e212bf6b81432556f3aMark Lobodzinski uint64_t num_objects[kVulkanObjectTypeMax + 1]; 952faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski uint64_t num_total_objects; 9661d505ea40b189b7ae63f311e2f13210eef219d2Mark Lobodzinski 972faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski debug_report_data *report_data; 982faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski std::vector<VkDebugReportCallbackEXT> logging_callback; 992faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski // The following are for keeping track of the temporary callbacks that can 1002faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski // be used in vkCreateInstance and vkDestroyInstance: 1012faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski uint32_t num_tmp_callbacks; 1022faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos; 1032faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski VkDebugReportCallbackEXT *tmp_callbacks; 104de4f1108f0a360ea02bfa0cc5e0fa0df8cf35927Jon Ashburn 1052faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski std::vector<VkQueueFamilyProperties> queue_family_properties; 10614305ad4363dd22e47118a76bc89376e5b291645Mark Lobodzinski 107da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinski // Vector of unordered_maps per object type to hold ObjTrackState info 1085c4c68c37fbd5e01b931fb47ff2ba31c896bcbeeTobin Ehlis std::vector<object_map_type> object_map; 1092faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski // Special-case map for swapchain images 110da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinski std::unordered_map<uint64_t, ObjTrackState *> swapchainImageMap; 1112faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski // Map of queue information structures, one per queue 112da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinski std::unordered_map<VkQueue, ObjTrackQueueInfo *> queue_info_map; 11314305ad4363dd22e47118a76bc89376e5b291645Mark Lobodzinski 1147b0f9d703b1f9b2a05f52ec6778941216e7598a3Tobin Ehlis VkLayerDispatchTable dispatch_table; 1152faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski // Default constructor 1162faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski layer_data() 117cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski : instance(nullptr), 118cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski physical_device(nullptr), 119cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski num_objects{}, 120cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski num_total_objects(0), 121cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski report_data(nullptr), 122cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski num_tmp_callbacks(0), 123cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski tmp_dbg_create_infos(nullptr), 124cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski tmp_callbacks(nullptr), 125cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski object_map{}, 126cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski dispatch_table{} { 127b8a5f6bc08c0c75977f64e212bf6b81432556f3aMark Lobodzinski object_map.resize(kVulkanObjectTypeMax + 1); 1285c4c68c37fbd5e01b931fb47ff2ba31c896bcbeeTobin Ehlis } 1296cb97f9b4cb894c01e9efbc065ef11fc9f6221b6Mark Lobodzinski}; 13014305ad4363dd22e47118a76bc89376e5b291645Mark Lobodzinski 13154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskiextern std::unordered_map<void *, layer_data *> layer_data_map; 13254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskiextern device_table_map ot_device_table_map; 13354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskiextern instance_table_map ot_instance_table_map; 13454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskiextern std::mutex global_lock; 13554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskiextern uint64_t object_track_index; 13654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskiextern uint32_t loader_layer_if_version; 13754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskiextern const std::unordered_map<std::string, void *> name_to_funcptr_map; 1382faa21475b11e094bb4a82cb7d370b9da1609623Mark Lobodzinski 13954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid DeviceReportUndestroyedObjects(VkDevice device, VulkanObjectType object_type, enum UNIQUE_VALIDATION_ERROR_CODE error_code); 14054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid CreateQueue(VkDevice device, VkQueue vkObj); 14154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid AddQueueInfo(VkDevice device, uint32_t queue_node_index, VkQueue queue); 14254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid ValidateQueueFlags(VkQueue queue, const char *function); 14354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, const VkCommandBuffer command_buffer, 14454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski VkCommandBufferLevel level); 14554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set); 14654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain); 147da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinskivoid ReportUndestroyedObjects(VkDevice device, UNIQUE_VALIDATION_ERROR_CODE error_code); 148040ab669b8b9a0bcd49a55d9405b1bec72c572b3Mark Lobodzinskibool ValidateDeviceObject(uint64_t device_handle, enum UNIQUE_VALIDATION_ERROR_CODE invalid_handle_code, 149040ab669b8b9a0bcd49a55d9405b1bec72c572b3Mark Lobodzinski enum UNIQUE_VALIDATION_ERROR_CODE wrong_device_code); 15054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 15154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskitemplate <typename T1, typename T2> 15254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskibool ValidateObject(T1 dispatchable_object, T2 object, VulkanObjectType object_type, bool null_allowed, 15354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski enum UNIQUE_VALIDATION_ERROR_CODE invalid_handle_code, enum UNIQUE_VALIDATION_ERROR_CODE wrong_device_code) { 15454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if (null_allowed && (object == VK_NULL_HANDLE)) { 15554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski return false; 15654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 15754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski auto object_handle = HandleToUint64(object); 158040ab669b8b9a0bcd49a55d9405b1bec72c572b3Mark Lobodzinski 159040ab669b8b9a0bcd49a55d9405b1bec72c572b3Mark Lobodzinski if (object_type == kVulkanObjectTypeDevice) { 160040ab669b8b9a0bcd49a55d9405b1bec72c572b3Mark Lobodzinski return ValidateDeviceObject(object_handle, invalid_handle_code, wrong_device_code); 161040ab669b8b9a0bcd49a55d9405b1bec72c572b3Mark Lobodzinski } 162040ab669b8b9a0bcd49a55d9405b1bec72c572b3Mark Lobodzinski 16354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[object_type]; 16454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 16554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(dispatchable_object), layer_data_map); 16654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski // Look for object in device object map 16754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if (device_data->object_map[object_type].find(object_handle) == device_data->object_map[object_type].end()) { 16854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski // If object is an image, also look for it in the swapchain image map 16954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if ((object_type != kVulkanObjectTypeImage) || 17054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski (device_data->swapchainImageMap.find(object_handle) == device_data->swapchainImageMap.end())) { 17154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski // Object not found, look for it in other device object maps 17254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski for (auto other_device_data : layer_data_map) { 17354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if (other_device_data.second != device_data) { 17454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if (other_device_data.second->object_map[object_type].find(object_handle) != 17554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski other_device_data.second->object_map[object_type].end() || 17654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski (object_type == kVulkanObjectTypeImage && other_device_data.second->swapchainImageMap.find(object_handle) != 17754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski other_device_data.second->swapchainImageMap.end())) { 17854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski // Object found on other device, report an error if object has a device parent error code 179ffadaf34580ea434addcaf710016382b34a4e71fMark Lobodzinski if ((wrong_device_code != VALIDATION_ERROR_UNDEFINED) && (object_type != kVulkanObjectTypeSurfaceKHR)) { 18054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski return log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, 18154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski object_handle, __LINE__, wrong_device_code, LayerName, 18254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski "Object 0x%" PRIxLEAST64 18354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski " was not created, allocated or retrieved from the correct device. %s", 18454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski object_handle, validation_error_map[wrong_device_code]); 18554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } else { 18654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski return false; 18754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 18854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 18954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 19054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 19154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski // Report an error if object was not found anywhere 19254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski return log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, object_handle, __LINE__, 19354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski invalid_handle_code, LayerName, "Invalid %s Object 0x%" PRIxLEAST64 ". %s", object_string[object_type], 19454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski object_handle, validation_error_map[invalid_handle_code]); 19554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 19654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 19754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski return false; 19854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski} 19954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 20054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskitemplate <typename T1, typename T2> 20154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid CreateObject(T1 dispatchable_object, T2 object, VulkanObjectType object_type, const VkAllocationCallbacks *pAllocator) { 20254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(dispatchable_object), layer_data_map); 20354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 20454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski auto object_handle = HandleToUint64(object); 20554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski bool custom_allocator = pAllocator != nullptr; 20654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 20754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if (!instance_data->object_map[object_type].count(object_handle)) { 20854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[object_type]; 20954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski log_msg(instance_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, debug_object_type, object_handle, __LINE__, 21054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski OBJTRACK_NONE, LayerName, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++, 21154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski object_string[object_type], object_handle); 21254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 213da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinski ObjTrackState *pNewObjNode = new ObjTrackState; 21454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski pNewObjNode->object_type = object_type; 21554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski pNewObjNode->status = custom_allocator ? OBJSTATUS_CUSTOM_ALLOCATOR : OBJSTATUS_NONE; 21654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski pNewObjNode->handle = object_handle; 21754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 21854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski instance_data->object_map[object_type][object_handle] = pNewObjNode; 21954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski instance_data->num_objects[object_type]++; 22054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski instance_data->num_total_objects++; 22154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 22254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski} 22354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 22454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskitemplate <typename T1, typename T2> 22554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinskivoid DestroyObject(T1 dispatchable_object, T2 object, VulkanObjectType object_type, const VkAllocationCallbacks *pAllocator, 22654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski enum UNIQUE_VALIDATION_ERROR_CODE expected_custom_allocator_code, 22754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski enum UNIQUE_VALIDATION_ERROR_CODE expected_default_allocator_code) { 22854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(dispatchable_object), layer_data_map); 22954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 23054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski auto object_handle = HandleToUint64(object); 23154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski bool custom_allocator = pAllocator != nullptr; 23254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[object_type]; 23354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 23454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if (object_handle != VK_NULL_HANDLE) { 23554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski auto item = device_data->object_map[object_type].find(object_handle); 23654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if (item != device_data->object_map[object_type].end()) { 237da749ff6870f075c25543313c2a2bcabfeb3e605Mark Lobodzinski ObjTrackState *pNode = item->second; 23854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski assert(device_data->num_total_objects > 0); 23954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski device_data->num_total_objects--; 24054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski assert(device_data->num_objects[pNode->object_type] > 0); 24154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski device_data->num_objects[pNode->object_type]--; 24254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 24354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, debug_object_type, object_handle, __LINE__, 24454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski OBJTRACK_NONE, LayerName, 24554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).", 24654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski object_string[object_type], HandleToUint64(object), device_data->num_total_objects, 24754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski device_data->num_objects[pNode->object_type], object_string[object_type]); 24854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 24954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski auto allocated_with_custom = (pNode->status & OBJSTATUS_CUSTOM_ALLOCATOR) ? true : false; 25054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski if (allocated_with_custom && !custom_allocator && expected_custom_allocator_code != VALIDATION_ERROR_UNDEFINED) { 25154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski // This check only verifies that custom allocation callbacks were provided to both Create and Destroy calls, 25254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski // it cannot verify that these allocation callbacks are compatible with each other. 25354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, object_handle, __LINE__, 25454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski expected_custom_allocator_code, LayerName, 25554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski "Custom allocator not specified while destroying %s obj 0x%" PRIxLEAST64 " but specified at creation. %s", 25654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski object_string[object_type], object_handle, validation_error_map[expected_custom_allocator_code]); 25754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } else if (!allocated_with_custom && custom_allocator && 25854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski expected_default_allocator_code != VALIDATION_ERROR_UNDEFINED) { 25954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, debug_object_type, object_handle, __LINE__, 26054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski expected_default_allocator_code, LayerName, 26154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski "Custom allocator specified while destroying %s obj 0x%" PRIxLEAST64 " but not specified at creation. %s", 26254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski object_string[object_type], object_handle, validation_error_map[expected_default_allocator_code]); 26354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 26454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski 26554ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski delete pNode; 26654ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski device_data->object_map[object_type].erase(item); 26754ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } else { 26854ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, object_handle, 26954ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski __LINE__, OBJTRACK_UNKNOWN_OBJECT, LayerName, 27054ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski "Unable to remove %s obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?", 27154ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski object_string[object_type], object_handle); 27254ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 27354ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski } 27454ccc4c2675072b5eb7fb23693d955d9501ddd58Mark Lobodzinski} 275d11c4ee2bd2a5672093d76630d895e824ee1a571Mark Lobodzinski 276cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski} // namespace object_tracker 277