aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Lobodzinski <mark@lunarg.com>2016-03-08 15:10:00 -0700
committerMark Lobodzinski <mark@lunarg.com>2016-03-08 16:56:22 -0700
commitb5fb36d28a5d0401ab90b839b21cb46e8af5acad (patch)
treee36d1387cdcfc05f8034c2d62fc368c33e65e897
parent63df733ca24c5633a1ad02dc85d120458bd72383 (diff)
downloadusermoji-b5fb36d28a5d0401ab90b839b21cb46e8af5acad.tar.xz
layers: LX430, Modfiy object_tracker to handle multiple instances
Upon DestroyInstance, OT indicated that all objects in all maps were not properly destroyed. Made this reporting work on a per-instance basis. Change-Id: I9b4eae4364a24597cb449610a31bf9b872c45225
-rw-r--r--layers/object_tracker.h33
-rwxr-xr-xvk-layer-generate.py51
2 files changed, 67 insertions, 17 deletions
diff --git a/layers/object_tracker.h b/layers/object_tracker.h
index 179d4bd4..4d570686 100644
--- a/layers/object_tracker.h
+++ b/layers/object_tracker.h
@@ -65,6 +65,7 @@ typedef struct _OBJTRACK_NODE {
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
@@ -385,12 +386,13 @@ initObjectTracker(
}
//
-// 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);
@@ -419,6 +421,7 @@ static VkBool32 validate_status(VkDevice dispatchable_object, VkFence object, Vk
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;
@@ -438,6 +441,7 @@ static void create_physical_device(VkInstance dispatchable_object, VkPhysicalDev
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;
@@ -455,6 +459,7 @@ static void create_surface_khr(VkInstance dispatchable_object, VkSurfaceKHR vkOb
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;
@@ -494,6 +499,7 @@ static void alloc_command_buffer(VkDevice device, VkCommandPool commandPool, VkC
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) {
@@ -546,6 +552,7 @@ static void alloc_descriptor_set(VkDevice device, VkDescriptorPool descriptorPoo
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;
@@ -593,6 +600,7 @@ static void create_queue(VkDevice dispatchable_object, VkQueue vkObj, VkDebugRep
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;
@@ -607,6 +615,7 @@ static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkO
(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;
@@ -614,6 +623,23 @@ static void create_swapchain_image_obj(VkDevice dispatchable_object, VkImage vkO
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
//
@@ -708,7 +734,10 @@ explicit_CreateDevice(
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;
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
index 6e4fb4bd..d9ed3157 100755
--- a/vk-layer-generate.py
+++ b/vk-layer-generate.py
@@ -856,6 +856,7 @@ class ObjectTrackerSubcommand(Subcommand):
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);')
@@ -1026,17 +1027,33 @@ class ObjectTrackerSubcommand(Subcommand):
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);')
@@ -1074,18 +1091,22 @@ class ObjectTrackerSubcommand(Subcommand):
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();')