aboutsummaryrefslogtreecommitdiff
path: root/layers/object_tracker_utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layers/object_tracker_utils.cpp')
-rw-r--r--layers/object_tracker_utils.cpp270
1 files changed, 117 insertions, 153 deletions
diff --git a/layers/object_tracker_utils.cpp b/layers/object_tracker_utils.cpp
index 964f6e6f1..1b0eff903 100644
--- a/layers/object_tracker_utils.cpp
+++ b/layers/object_tracker_utils.cpp
@@ -34,56 +34,17 @@ VulkanTypedHandle ObjTrackStateTypedHandle(const ObjTrackState &track_state) {
return typed_handle;
}
-// Add new queue to head of global queue list
-void ObjectLifetimes::AddQueueInfo(VkDevice device, uint32_t queue_node_index, VkQueue queue) {
- auto queueItem = queue_info_map.find(queue);
- if (queueItem == queue_info_map.end()) {
- ObjTrackQueueInfo *p_queue_info = new ObjTrackQueueInfo;
- if (p_queue_info != NULL) {
- memset(p_queue_info, 0, sizeof(ObjTrackQueueInfo));
- p_queue_info->queue = queue;
- p_queue_info->queue_node_index = queue_node_index;
- queue_info_map[queue] = p_queue_info;
- } else {
- log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, HandleToUint64(queue),
- kVUID_ObjectTracker_InternalError,
- "ERROR: VK_ERROR_OUT_OF_HOST_MEMORY -- could not allocate memory for Queue Information");
- }
- }
-}
-
// Destroy memRef lists and free all memory
void ObjectLifetimes::DestroyQueueDataStructures(VkDevice device) {
- for (auto queue_item : queue_info_map) {
- delete queue_item.second;
- }
- queue_info_map.clear();
-
// Destroy the items in the queue map
- auto queue = object_map[kVulkanObjectTypeQueue].begin();
- while (queue != object_map[kVulkanObjectTypeQueue].end()) {
- uint32_t obj_index = queue->second->object_type;
+ auto snapshot = object_map[kVulkanObjectTypeQueue].snapshot();
+ for (const auto &queue : snapshot) {
+ uint32_t obj_index = queue.second->object_type;
assert(num_total_objects > 0);
num_total_objects--;
assert(num_objects[obj_index] > 0);
num_objects[obj_index]--;
- delete queue->second;
- queue = object_map[kVulkanObjectTypeQueue].erase(queue);
- }
-}
-
-// Check Queue type flags for selected queue operations
-void ObjectLifetimes::ValidateQueueFlags(VkQueue queue, const char *function) {
- auto queue_item = queue_info_map.find(queue);
- if (queue_item != queue_info_map.end()) {
- ObjTrackQueueInfo *pQueueInfo = queue_item->second;
- if (pQueueInfo != NULL) {
- if ((queue_family_properties[pQueueInfo->queue_node_index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) == 0) {
- log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, HandleToUint64(queue),
- "VUID-vkQueueBindSparse-queuetype",
- "Attempting %s on a non-memory-management capable queue -- VK_QUEUE_SPARSE_BINDING_BIT not set.", function);
- }
- }
+ object_map[kVulkanObjectTypeQueue].erase(queue.first);
}
}
@@ -94,8 +55,8 @@ bool ObjectLifetimes::ValidateDeviceObject(const VulkanTypedHandle &device_typed
const char *wrong_device_code) {
auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
auto instance_object_lifetime_data = GetObjectLifetimeData(instance_data->object_dispatch);
- for (auto object : instance_object_lifetime_data->object_map[kVulkanObjectTypeDevice]) {
- if (object.second->handle == device_typed.handle) return false;
+ if (instance_object_lifetime_data->object_map[kVulkanObjectTypeDevice].contains(device_typed.handle)) {
+ return false;
}
return log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device_typed.handle,
invalid_handle_code, "Invalid %s.", report_data->FormatHandle(device_typed).c_str());
@@ -103,7 +64,7 @@ bool ObjectLifetimes::ValidateDeviceObject(const VulkanTypedHandle &device_typed
void ObjectLifetimes::AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, const VkCommandBuffer command_buffer,
VkCommandBufferLevel level) {
- ObjTrackState *pNewObjNode = new ObjTrackState;
+ auto pNewObjNode = std::make_shared<ObjTrackState>();
pNewObjNode->object_type = kVulkanObjectTypeCommandBuffer;
pNewObjNode->handle = HandleToUint64(command_buffer);
pNewObjNode->parent_object = HandleToUint64(command_pool);
@@ -112,7 +73,8 @@ void ObjectLifetimes::AllocateCommandBuffer(VkDevice device, const VkCommandPool
} else {
pNewObjNode->status = OBJSTATUS_NONE;
}
- object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)] = pNewObjNode;
+ InsertObject(object_map[kVulkanObjectTypeCommandBuffer], HandleToUint64(command_buffer), kVulkanObjectTypeCommandBuffer,
+ pNewObjNode);
num_objects[kVulkanObjectTypeCommandBuffer]++;
num_total_objects++;
}
@@ -120,8 +82,9 @@ void ObjectLifetimes::AllocateCommandBuffer(VkDevice device, const VkCommandPool
bool ObjectLifetimes::ValidateCommandBuffer(VkDevice device, VkCommandPool command_pool, VkCommandBuffer command_buffer) {
bool skip = false;
uint64_t object_handle = HandleToUint64(command_buffer);
- if (object_map[kVulkanObjectTypeCommandBuffer].find(object_handle) != object_map[kVulkanObjectTypeCommandBuffer].end()) {
- ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
+ auto iter = object_map[kVulkanObjectTypeCommandBuffer].find(object_handle);
+ if (iter != object_map[kVulkanObjectTypeCommandBuffer].end()) {
+ auto pNode = iter->second;
if (pNode->parent_object != HandleToUint64(command_pool)) {
// We know that the parent *must* be a command pool
@@ -141,19 +104,19 @@ bool ObjectLifetimes::ValidateCommandBuffer(VkDevice device, VkCommandPool comma
}
void ObjectLifetimes::AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set) {
- ObjTrackState *pNewObjNode = new ObjTrackState;
+ auto pNewObjNode = std::make_shared<ObjTrackState>();
pNewObjNode->object_type = kVulkanObjectTypeDescriptorSet;
pNewObjNode->status = OBJSTATUS_NONE;
pNewObjNode->handle = HandleToUint64(descriptor_set);
pNewObjNode->parent_object = HandleToUint64(descriptor_pool);
- object_map[kVulkanObjectTypeDescriptorSet][HandleToUint64(descriptor_set)] = pNewObjNode;
+ InsertObject(object_map[kVulkanObjectTypeDescriptorSet], HandleToUint64(descriptor_set), kVulkanObjectTypeDescriptorSet,
+ pNewObjNode);
num_objects[kVulkanObjectTypeDescriptorSet]++;
num_total_objects++;
auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptor_pool));
if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
- ObjTrackState *pPoolNode = itr->second;
- pPoolNode->child_objects->insert(HandleToUint64(descriptor_set));
+ itr->second->child_objects->insert(HandleToUint64(descriptor_set));
}
}
@@ -162,11 +125,9 @@ bool ObjectLifetimes::ValidateDescriptorSet(VkDevice device, VkDescriptorPool de
uint64_t object_handle = HandleToUint64(descriptor_set);
auto dsItem = object_map[kVulkanObjectTypeDescriptorSet].find(object_handle);
if (dsItem != object_map[kVulkanObjectTypeDescriptorSet].end()) {
- ObjTrackState *pNode = dsItem->second;
-
- if (pNode->parent_object != HandleToUint64(descriptor_pool)) {
+ if (dsItem->second->parent_object != HandleToUint64(descriptor_pool)) {
// We know that the parent *must* be a descriptor pool
- const auto parent_pool = CastFromUint64<VkDescriptorPool>(pNode->parent_object);
+ const auto parent_pool = CastFromUint64<VkDescriptorPool>(dsItem->second->parent_object);
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
object_handle, "VUID-vkFreeDescriptorSets-pDescriptorSets-parent",
"FreeDescriptorSets is attempting to free %s"
@@ -240,11 +201,11 @@ bool ObjectLifetimes::PreCallValidateCmdPushDescriptorSetKHR(VkCommandBuffer com
}
void ObjectLifetimes::CreateQueue(VkDevice device, VkQueue vkObj) {
- ObjTrackState *p_obj_node = NULL;
+ std::shared_ptr<ObjTrackState> p_obj_node = NULL;
auto queue_item = object_map[kVulkanObjectTypeQueue].find(HandleToUint64(vkObj));
if (queue_item == object_map[kVulkanObjectTypeQueue].end()) {
- p_obj_node = new ObjTrackState;
- object_map[kVulkanObjectTypeQueue][HandleToUint64(vkObj)] = p_obj_node;
+ p_obj_node = std::make_shared<ObjTrackState>();
+ InsertObject(object_map[kVulkanObjectTypeQueue], HandleToUint64(vkObj), kVulkanObjectTypeQueue, p_obj_node);
num_objects[kVulkanObjectTypeQueue]++;
num_total_objects++;
} else {
@@ -256,18 +217,22 @@ void ObjectLifetimes::CreateQueue(VkDevice device, VkQueue vkObj) {
}
void ObjectLifetimes::CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain) {
- ObjTrackState *pNewObjNode = new ObjTrackState;
- pNewObjNode->object_type = kVulkanObjectTypeImage;
- pNewObjNode->status = OBJSTATUS_NONE;
- pNewObjNode->handle = HandleToUint64(swapchain_image);
- pNewObjNode->parent_object = HandleToUint64(swapchain);
- swapchainImageMap[HandleToUint64(swapchain_image)] = pNewObjNode;
+ if (!swapchainImageMap.contains(HandleToUint64(swapchain_image))) {
+ auto pNewObjNode = std::make_shared<ObjTrackState>();
+ pNewObjNode->object_type = kVulkanObjectTypeImage;
+ pNewObjNode->status = OBJSTATUS_NONE;
+ pNewObjNode->handle = HandleToUint64(swapchain_image);
+ pNewObjNode->parent_object = HandleToUint64(swapchain);
+ InsertObject(swapchainImageMap, HandleToUint64(swapchain_image), kVulkanObjectTypeImage, pNewObjNode);
+ }
}
bool ObjectLifetimes::DeviceReportUndestroyedObjects(VkDevice device, VulkanObjectType object_type, const std::string &error_code) {
bool skip = false;
- for (const auto &item : object_map[object_type]) {
- const ObjTrackState *object_info = item.second;
+
+ auto snapshot = object_map[object_type].snapshot();
+ for (const auto &item : snapshot) {
+ const auto object_info = item.second;
skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object_type], object_info->handle,
error_code, "OBJ ERROR : For %s, %s has not been destroyed.", report_data->FormatHandle(device).c_str(),
report_data->FormatHandle(ObjTrackStateTypedHandle(*object_info)).c_str());
@@ -276,10 +241,9 @@ bool ObjectLifetimes::DeviceReportUndestroyedObjects(VkDevice device, VulkanObje
}
void ObjectLifetimes::DeviceDestroyUndestroyedObjects(VkDevice device, VulkanObjectType object_type) {
- while (!object_map[object_type].empty()) {
- auto item = object_map[object_type].begin();
-
- ObjTrackState *object_info = item->second;
+ auto snapshot = object_map[object_type].snapshot();
+ for (const auto &item : snapshot) {
+ auto object_info = item.second;
DestroyObjectSilently(object_info->handle, object_type);
}
}
@@ -292,8 +256,9 @@ bool ObjectLifetimes::PreCallValidateDestroyInstance(VkInstance instance, const
kVUIDUndefined);
// Validate that child devices have been destroyed
- for (const auto &iit : object_map[kVulkanObjectTypeDevice]) {
- ObjTrackState *pNode = iit.second;
+ auto snapshot = object_map[kVulkanObjectTypeDevice].snapshot();
+ for (const auto &iit : snapshot) {
+ auto pNode = iit.second;
VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[pNode->object_type];
@@ -335,25 +300,22 @@ void ObjectLifetimes::PostCallRecordEnumeratePhysicalDevices(VkInstance instance
void ObjectLifetimes::PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
// Destroy physical devices
- for (auto iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
- iit != object_map[kVulkanObjectTypePhysicalDevice].end();) {
- ObjTrackState *pNode = iit->second;
+ auto snapshot = object_map[kVulkanObjectTypePhysicalDevice].snapshot();
+ for (const auto &iit : snapshot) {
+ auto pNode = iit.second;
VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(pNode->handle);
RecordDestroyObject(instance, physical_device, kVulkanObjectTypePhysicalDevice);
- iit = object_map[kVulkanObjectTypePhysicalDevice].begin();
}
// Destroy child devices
- for (auto iit = object_map[kVulkanObjectTypeDevice].begin(); iit != object_map[kVulkanObjectTypeDevice].end();) {
- ObjTrackState *pNode = iit->second;
+ auto snapshot2 = object_map[kVulkanObjectTypeDevice].snapshot();
+ for (const auto &iit : snapshot2) {
+ auto pNode = iit.second;
VkDevice device = reinterpret_cast<VkDevice>(pNode->handle);
DestroyUndestroyedObjects(device);
RecordDestroyObject(instance, device, kVulkanObjectTypeDevice);
- iit = object_map[kVulkanObjectTypeDevice].begin();
}
-
- object_map[kVulkanObjectTypeDevice].clear();
}
void ObjectLifetimes::PostCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
@@ -392,8 +354,8 @@ bool ObjectLifetimes::PreCallValidateGetDeviceQueue(VkDevice device, uint32_t qu
void ObjectLifetimes::PostCallRecordGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
VkQueue *pQueue) {
+ auto lock = write_shared_lock();
CreateQueue(device, *pQueue);
- AddQueueInfo(device, queueFamilyIndex, *pQueue);
}
bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
@@ -402,8 +364,8 @@ bool ObjectLifetimes::PreCallValidateGetDeviceQueue2(VkDevice device, const VkDe
}
void ObjectLifetimes::PostCallRecordGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
+ auto lock = write_shared_lock();
CreateQueue(device, *pQueue);
- AddQueueInfo(device, pQueueInfo->queueFamilyIndex, *pQueue);
}
bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
@@ -436,6 +398,7 @@ bool ObjectLifetimes::PreCallValidateUpdateDescriptorSets(VkDevice device, uint3
bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
VkDescriptorPoolResetFlags flags) {
bool skip = false;
+ auto lock = read_shared_lock();
skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkResetDescriptorPool-device-parameter",
kVUIDUndefined);
@@ -445,7 +408,7 @@ bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDesc
auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
- ObjTrackState *pPoolNode = itr->second;
+ auto pPoolNode = itr->second;
for (auto set : *pPoolNode->child_objects) {
skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
kVUIDUndefined);
@@ -456,11 +419,12 @@ bool ObjectLifetimes::PreCallValidateResetDescriptorPool(VkDevice device, VkDesc
void ObjectLifetimes::PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
VkDescriptorPoolResetFlags flags) {
+ auto lock = write_shared_lock();
// A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset. Remove this pool's descriptor sets from
// our descriptorSet map.
auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
- ObjTrackState *pPoolNode = itr->second;
+ auto pPoolNode = itr->second;
for (auto set : *pPoolNode->child_objects) {
RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
}
@@ -474,13 +438,18 @@ bool ObjectLifetimes::PreCallValidateBeginCommandBuffer(VkCommandBuffer command_
skip |= ValidateObject(command_buffer, command_buffer, kVulkanObjectTypeCommandBuffer, false,
"VUID-vkBeginCommandBuffer-commandBuffer-parameter", kVUIDUndefined);
if (begin_info) {
- ObjTrackState *pNode = object_map[kVulkanObjectTypeCommandBuffer][HandleToUint64(command_buffer)];
- if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
- (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
- skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
+ auto iter = object_map[kVulkanObjectTypeCommandBuffer].find(HandleToUint64(command_buffer));
+ if (iter != object_map[kVulkanObjectTypeCommandBuffer].end()) {
+ auto pNode = iter->second;
+ if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY) &&
+ (begin_info->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
+ skip |=
+ ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer, kVulkanObjectTypeFramebuffer, true,
"VUID-VkCommandBufferBeginInfo-flags-00055", "VUID-VkCommandBufferInheritanceInfo-commonparent");
- skip |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
+ skip |=
+ ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass, kVulkanObjectTypeRenderPass, false,
"VUID-VkCommandBufferBeginInfo-flags-00053", "VUID-VkCommandBufferInheritanceInfo-commonparent");
+ }
}
}
return skip;
@@ -499,6 +468,7 @@ bool ObjectLifetimes::PreCallValidateGetSwapchainImagesKHR(VkDevice device, VkSw
void ObjectLifetimes::PostCallRecordGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
VkImage *pSwapchainImages, VkResult result) {
if ((result != VK_SUCCESS) && (result != VK_INCOMPLETE)) return;
+ auto lock = write_shared_lock();
if (pSwapchainImages != NULL) {
for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
CreateSwapchainImageObject(device, pSwapchainImages[i], swapchain);
@@ -584,16 +554,7 @@ bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties(VkPh
void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
uint32_t *pQueueFamilyPropertyCount,
- VkQueueFamilyProperties *pQueueFamilyProperties) {
- if (pQueueFamilyProperties != NULL) {
- if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
- queue_family_properties.resize(*pQueueFamilyPropertyCount);
- }
- for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
- queue_family_properties[i] = pQueueFamilyProperties[i];
- }
- }
-}
+ VkQueueFamilyProperties *pQueueFamilyProperties) {}
void ObjectLifetimes::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
VkInstance *pInstance, VkResult result) {
@@ -622,6 +583,7 @@ void ObjectLifetimes::PostCallRecordAllocateCommandBuffers(VkDevice device, cons
bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
VkDescriptorSet *pDescriptorSets) {
bool skip = false;
+ auto lock = read_shared_lock();
skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkAllocateDescriptorSets-device-parameter",
kVUIDUndefined);
skip |= ValidateObject(device, pAllocateInfo->descriptorPool, kVulkanObjectTypeDescriptorPool, false,
@@ -638,6 +600,7 @@ bool ObjectLifetimes::PreCallValidateAllocateDescriptorSets(VkDevice device, con
void ObjectLifetimes::PostCallRecordAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
VkDescriptorSet *pDescriptorSets, VkResult result) {
if (result != VK_SUCCESS) return;
+ auto lock = write_shared_lock();
for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
AllocateDescriptorSet(device, pAllocateInfo->descriptorPool, pDescriptorSets[i]);
}
@@ -676,21 +639,17 @@ bool ObjectLifetimes::PreCallValidateDestroySwapchainKHR(VkDevice device, VkSwap
void ObjectLifetimes::PreCallRecordDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
const VkAllocationCallbacks *pAllocator) {
RecordDestroyObject(device, swapchain, kVulkanObjectTypeSwapchainKHR);
- std::unordered_map<uint64_t, ObjTrackState *>::iterator itr = swapchainImageMap.begin();
- while (itr != swapchainImageMap.end()) {
- ObjTrackState *pNode = (*itr).second;
- if (pNode->parent_object == HandleToUint64(swapchain)) {
- delete pNode;
- auto delete_item = itr++;
- swapchainImageMap.erase(delete_item);
- } else {
- ++itr;
- }
+
+ auto snapshot = swapchainImageMap.snapshot(
+ [swapchain](std::shared_ptr<ObjTrackState> pNode) { return pNode->parent_object == HandleToUint64(swapchain); });
+ for (const auto &itr : snapshot) {
+ swapchainImageMap.erase(itr.first);
}
}
bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets) {
+ auto lock = read_shared_lock();
bool skip = false;
skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkFreeDescriptorSets-device-parameter",
kVUIDUndefined);
@@ -707,7 +666,8 @@ bool ObjectLifetimes::PreCallValidateFreeDescriptorSets(VkDevice device, VkDescr
}
void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
const VkDescriptorSet *pDescriptorSets) {
- ObjTrackState *pPoolNode = nullptr;
+ auto lock = write_shared_lock();
+ std::shared_ptr<ObjTrackState> pPoolNode = nullptr;
auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
pPoolNode = itr->second;
@@ -722,6 +682,7 @@ void ObjectLifetimes::PreCallRecordFreeDescriptorSets(VkDevice device, VkDescrip
bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
const VkAllocationCallbacks *pAllocator) {
+ auto lock = read_shared_lock();
bool skip = false;
skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkDestroyDescriptorPool-device-parameter",
kVUIDUndefined);
@@ -731,7 +692,7 @@ bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDe
auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
- ObjTrackState *pPoolNode = itr->second;
+ auto pPoolNode = itr->second;
for (auto set : *pPoolNode->child_objects) {
skip |= ValidateDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet, nullptr, kVUIDUndefined,
kVUIDUndefined);
@@ -744,9 +705,10 @@ bool ObjectLifetimes::PreCallValidateDestroyDescriptorPool(VkDevice device, VkDe
}
void ObjectLifetimes::PreCallRecordDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
const VkAllocationCallbacks *pAllocator) {
+ auto lock = write_shared_lock();
auto itr = object_map[kVulkanObjectTypeDescriptorPool].find(HandleToUint64(descriptorPool));
if (itr != object_map[kVulkanObjectTypeDescriptorPool].end()) {
- ObjTrackState *pPoolNode = itr->second;
+ auto pPoolNode = itr->second;
for (auto set : *pPoolNode->child_objects) {
RecordDestroyObject(device, (VkDescriptorSet)set, kVulkanObjectTypeDescriptorSet);
}
@@ -762,16 +724,14 @@ bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkComma
kVUIDUndefined);
skip |= ValidateObject(device, commandPool, kVulkanObjectTypeCommandPool, true,
"VUID-vkDestroyCommandPool-commandPool-parameter", "VUID-vkDestroyCommandPool-commandPool-parent");
- auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
- auto del_itr = itr;
- while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
- ObjTrackState *pNode = (*itr).second;
- del_itr = itr++;
- if (pNode->parent_object == HandleToUint64(commandPool)) {
- skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
- skip |= ValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
- kVulkanObjectTypeCommandBuffer, nullptr, kVUIDUndefined, kVUIDUndefined);
- }
+
+ auto snapshot = object_map[kVulkanObjectTypeCommandBuffer].snapshot(
+ [commandPool](std::shared_ptr<ObjTrackState> pNode) { return pNode->parent_object == HandleToUint64(commandPool); });
+ for (const auto &itr : snapshot) {
+ auto pNode = itr.second;
+ skip |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>(itr.first));
+ skip |= ValidateDestroyObject(device, reinterpret_cast<VkCommandBuffer>(itr.first), kVulkanObjectTypeCommandBuffer, nullptr,
+ kVUIDUndefined, kVUIDUndefined);
}
skip |= ValidateDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool, pAllocator,
"VUID-vkDestroyCommandPool-commandPool-00042", "VUID-vkDestroyCommandPool-commandPool-00043");
@@ -780,15 +740,11 @@ bool ObjectLifetimes::PreCallValidateDestroyCommandPool(VkDevice device, VkComma
void ObjectLifetimes::PreCallRecordDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
const VkAllocationCallbacks *pAllocator) {
- auto itr = object_map[kVulkanObjectTypeCommandBuffer].begin();
- auto del_itr = itr;
+ auto snapshot = object_map[kVulkanObjectTypeCommandBuffer].snapshot(
+ [commandPool](std::shared_ptr<ObjTrackState> pNode) { return pNode->parent_object == HandleToUint64(commandPool); });
// A CommandPool's cmd buffers are implicitly deleted when pool is deleted. Remove this pool's cmdBuffers from cmd buffer map.
- while (itr != object_map[kVulkanObjectTypeCommandBuffer].end()) {
- ObjTrackState *pNode = (*itr).second;
- del_itr = itr++;
- if (pNode->parent_object == HandleToUint64(commandPool)) {
- RecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first), kVulkanObjectTypeCommandBuffer);
- }
+ for (const auto &itr : snapshot) {
+ RecordDestroyObject(device, reinterpret_cast<VkCommandBuffer>(itr.first), kVulkanObjectTypeCommandBuffer);
}
RecordDestroyObject(device, commandPool, kVulkanObjectTypeCommandPool);
}
@@ -809,28 +765,10 @@ bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(
void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
uint32_t *pQueueFamilyPropertyCount,
- VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
- if (pQueueFamilyProperties != NULL) {
- if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
- queue_family_properties.resize(*pQueueFamilyPropertyCount);
- }
- for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
- queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
- }
- }
-}
+ VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {}
void ObjectLifetimes::PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(
- VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
- if (pQueueFamilyProperties != NULL) {
- if (queue_family_properties.size() < *pQueueFamilyPropertyCount) {
- queue_family_properties.resize(*pQueueFamilyPropertyCount);
- }
- for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; i++) {
- queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
- }
- }
-}
+ VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {}
bool ObjectLifetimes::PreCallValidateGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
@@ -938,3 +876,29 @@ bool ObjectLifetimes::PreCallValidateQueueSetPerformanceConfigurationINTEL(VkQue
return skip;
}
+
+bool ObjectLifetimes::PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) {
+ bool skip = false;
+ skip |=
+ ValidateObject(device, device, kVulkanObjectTypeDevice, false, "VUID-vkCreateFramebuffer-device-parameter", kVUIDUndefined);
+ if (pCreateInfo) {
+ skip |= ValidateObject(device, pCreateInfo->renderPass, kVulkanObjectTypeRenderPass, false,
+ "VUID-VkFramebufferCreateInfo-renderPass-parameter", "VUID-VkFramebufferCreateInfo-commonparent");
+ if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR) == 0) {
+ for (uint32_t index1 = 0; index1 < pCreateInfo->attachmentCount; ++index1) {
+ skip |= ValidateObject(device, pCreateInfo->pAttachments[index1], kVulkanObjectTypeImageView, true, kVUIDUndefined,
+ "VUID-VkFramebufferCreateInfo-commonparent");
+ }
+ }
+ }
+
+ return skip;
+}
+
+void ObjectLifetimes::PostCallRecordCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer,
+ VkResult result) {
+ if (result != VK_SUCCESS) return;
+ CreateObject(device, *pFramebuffer, kVulkanObjectTypeFramebuffer, pAllocator);
+}