VkDebugReportObjectTypeEXT objType; // Object type identifier
ObjectStatusFlags status; // Object state
uint64_t parentObj; // Parent object
+ uint64_t belongsTo; // Object Scope -- owning device/instance
} OBJTRACK_NODE;
// prototype for extension functions
}
//
-// Forward declares of generated routines
+// 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 VkBool32 validate_image(VkQueue dispatchable_object, VkImage object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
static VkBool32 validate_instance(VkInstance dispatchable_object, VkInstance object, VkDebugReportObjectTypeEXT objType, bool null_allowed);
const char *fail_msg);
#endif
extern unordered_map<uint64_t, OBJTRACK_NODE*> VkPhysicalDeviceMap;
+extern unordered_map<uint64_t, OBJTRACK_NODE*> VkDeviceMap;
extern unordered_map<uint64_t, OBJTRACK_NODE*> VkImageMap;
extern unordered_map<uint64_t, OBJTRACK_NODE*> VkQueueMap;
extern unordered_map<uint64_t, OBJTRACK_NODE*> VkDescriptorSetMap;
OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
pNewObjNode->objType = objType;
+ pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
pNewObjNode->status = OBJSTATUS_NONE;
pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
VkPhysicalDeviceMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
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;
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) {
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;
OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;
pNewObjNode->objType = objType;
+ pNewObjNode->belongsTo = (uint64_t)dispatchable_object;
pNewObjNode->status = OBJSTATUS_NONE;
pNewObjNode->vkObj = reinterpret_cast<uint64_t>(vkObj);
VkQueueMap[reinterpret_cast<uint64_t>(vkObj)] = pNewObjNode;
(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;
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
//
createDeviceRegisterExtensions(pCreateInfo, *pDevice);
- create_device(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
+ 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);
+ }
loader_platform_thread_unlock_mutex(&objLock);
return result;
procs_txt.append(' (uint64_t)(vkObj));')
procs_txt.append('')
procs_txt.append(' OBJTRACK_NODE* pNewObjNode = new OBJTRACK_NODE;')
+ procs_txt.append(' pNewObjNode->belongsTo = (uint64_t)dispatchable_object;')
procs_txt.append(' pNewObjNode->objType = objType;')
procs_txt.append(' pNewObjNode->status = OBJSTATUS_NONE;')
procs_txt.append(' pNewObjNode->vkObj = (uint64_t)(vkObj);')
gedi_txt.append('')
gedi_txt.append(' destroy_instance(instance, instance);')
gedi_txt.append(' // Report any remaining objects in LL')
+ gedi_txt.append('')
+ gedi_txt.append(' for (auto iit = VkDeviceMap.begin(); iit != VkDeviceMap.end();) {')
+ gedi_txt.append(' OBJTRACK_NODE* pNode = iit->second;')
+ gedi_txt.append(' if (pNode->belongsTo == (uint64_t)instance) {')
+ gedi_txt.append(' log_msg(mid(instance), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
+ gedi_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
+ gedi_txt.append(' pNode->vkObj);')
for o in vulkan.core.objects:
- if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue']:
+ if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue', 'VkDevice']:
continue
- gedi_txt.append(' for (auto it = %sMap.begin(); it != %sMap.end(); ++it) {' % (o, o))
- gedi_txt.append(' OBJTRACK_NODE* pNode = it->second;')
- gedi_txt.append(' log_msg(mid(instance), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
- gedi_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
- gedi_txt.append(' pNode->vkObj);')
- gedi_txt.append(' }')
- gedi_txt.append(' %sMap.clear();' % (o))
- gedi_txt.append('')
+ gedi_txt.append(' for (auto idt = %sMap.begin(); idt != %sMap.end();) {' % (o, o))
+ gedi_txt.append(' OBJTRACK_NODE* pNode = idt->second;')
+ gedi_txt.append(' if (pNode->belongsTo == iit->first) {')
+ gedi_txt.append(' log_msg(mid(instance), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
+ gedi_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
+ gedi_txt.append(' pNode->vkObj);')
+ gedi_txt.append(' %sMap.erase(idt++);' % o )
+ gedi_txt.append(' } else {')
+ gedi_txt.append(' ++idt;')
+ gedi_txt.append(' }')
+ gedi_txt.append(' }')
+ gedi_txt.append(' VkDeviceMap.erase(iit++);')
+ gedi_txt.append(' } else {')
+ gedi_txt.append(' ++iit;')
+ gedi_txt.append(' }')
+ gedi_txt.append(' }')
+ gedi_txt.append('')
gedi_txt.append(' dispatch_key key = get_dispatch_key(instance);')
gedi_txt.append(' VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(object_tracker_instance_table_map, instance);')
gedi_txt.append(' pInstanceTable->DestroyInstance(instance, pAllocator);')
gedd_txt.append(' validate_device(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);')
gedd_txt.append('')
gedd_txt.append(' destroy_device(device, device);')
- gedd_txt.append(' // Report any remaining objects in LL')
+ gedd_txt.append(' // Report any remaining objects associated with this VkDevice object in LL')
for o in vulkan.core.objects:
# DescriptorSets and Command Buffers are destroyed through their pools, not explicitly
if o in ['VkInstance', 'VkPhysicalDevice', 'VkQueue', 'VkDevice', 'VkDescriptorSet', 'VkCommandBuffer']:
continue
- gedd_txt.append(' for (auto it = %sMap.begin(); it != %sMap.end(); ++it) {' % (o, o))
+ gedd_txt.append(' for (auto it = %sMap.begin(); it != %sMap.end();) {' % (o, o))
gedd_txt.append(' OBJTRACK_NODE* pNode = it->second;')
- gedd_txt.append(' log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
- gedd_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
- gedd_txt.append(' pNode->vkObj);')
+ gedd_txt.append(' if (pNode->belongsTo == (uint64_t)device) {')
+ gedd_txt.append(' log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, pNode->objType, pNode->vkObj, __LINE__, OBJTRACK_OBJECT_LEAK, "OBJTRACK",')
+ gedd_txt.append(' "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.", string_VkDebugReportObjectTypeEXT(pNode->objType),')
+ gedd_txt.append(' pNode->vkObj);')
+ gedd_txt.append(' %sMap.erase(it++);' % o )
+ gedd_txt.append(' } else {')
+ gedd_txt.append(' ++it;')
+ gedd_txt.append(' }')
gedd_txt.append(' }')
- gedd_txt.append(' %sMap.clear();' % (o))
gedd_txt.append('')
gedd_txt.append(" // Clean up Queue's MemRef Linked Lists")
gedd_txt.append(' destroyQueueMemRefLists();')