layers: Tolerate null handles in destroy and free routines
Several CTS tests call destroy routines with null pointers. This
keeps validation layers from crashing or reporting false positives
Change-Id: I95a3bee21902598dffc0df28e53f5ff253cb6207
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 016c5c1..3df40a8 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -3437,9 +3437,6 @@
GLOBAL_CB_NODE *getCBNode(layer_data const *my_data, const VkCommandBuffer cb) {
auto it = my_data->commandBufferMap.find(cb);
if (it == my_data->commandBufferMap.end()) {
- log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
- reinterpret_cast<const uint64_t &>(cb), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
- "Attempt to use CommandBuffer 0x%p that doesn't exist!", cb);
return NULL;
}
return it->second;
@@ -4761,7 +4758,9 @@
lock.unlock();
dev_data->dispatch_table.FreeMemory(device, mem, pAllocator);
lock.lock();
- PostCallRecordFreeMemory(dev_data, mem, mem_info, obj_struct);
+ if (mem != VK_NULL_HANDLE) {
+ PostCallRecordFreeMemory(dev_data, mem, mem_info, obj_struct);
+ }
}
}
@@ -5137,7 +5136,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyEvent(device, event, pAllocator);
lock.lock();
- PostCallRecordDestroyEvent(dev_data, event, event_state, obj_struct);
+ if (event != VK_NULL_HANDLE) {
+ PostCallRecordDestroyEvent(dev_data, event, event_state, obj_struct);
+ }
}
}
@@ -5169,7 +5170,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyQueryPool(device, queryPool, pAllocator);
lock.lock();
- PostCallRecordDestroyQueryPool(dev_data, queryPool, qp_state, obj_struct);
+ if (queryPool != VK_NULL_HANDLE) {
+ PostCallRecordDestroyQueryPool(dev_data, queryPool, qp_state, obj_struct);
+ }
}
}
static bool PreCallValidateGetQueryPoolResults(layer_data *dev_data, VkQueryPool query_pool, uint32_t first_query,
@@ -5469,7 +5472,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyBuffer(device, buffer, pAllocator);
lock.lock();
- PostCallRecordDestroyBuffer(dev_data, buffer, buffer_state, obj_struct);
+ if (buffer != VK_NULL_HANDLE) {
+ PostCallRecordDestroyBuffer(dev_data, buffer, buffer_state, obj_struct);
+ }
}
}
@@ -5504,7 +5509,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyBufferView(device, bufferView, pAllocator);
lock.lock();
- PostCallRecordDestroyBufferView(dev_data, bufferView, buffer_view_state, obj_struct);
+ if (bufferView != VK_NULL_HANDLE) {
+ PostCallRecordDestroyBufferView(dev_data, bufferView, buffer_view_state, obj_struct);
+ }
}
}
@@ -5518,7 +5525,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyImage(device, image, pAllocator);
lock.lock();
- PostCallRecordDestroyImage(dev_data, image, image_state, obj_struct);
+ if (image != VK_NULL_HANDLE) {
+ PostCallRecordDestroyImage(dev_data, image, image_state, obj_struct);
+ }
}
}
@@ -5675,7 +5684,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyImageView(device, imageView, pAllocator);
lock.lock();
- PostCallRecordDestroyImageView(dev_data, imageView, image_view_state, obj_struct);
+ if (imageView != VK_NULL_HANDLE) {
+ PostCallRecordDestroyImageView(dev_data, imageView, image_view_state, obj_struct);
+ }
}
}
@@ -5719,7 +5730,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyPipeline(device, pipeline, pAllocator);
lock.lock();
- PostCallRecordDestroyPipeline(dev_data, pipeline, pipeline_state, obj_struct);
+ if (pipeline != VK_NULL_HANDLE) {
+ PostCallRecordDestroyPipeline(dev_data, pipeline, pipeline_state, obj_struct);
+ }
}
}
@@ -5762,7 +5775,9 @@
lock.unlock();
dev_data->dispatch_table.DestroySampler(device, sampler, pAllocator);
lock.lock();
- PostCallRecordDestroySampler(dev_data, sampler, sampler_state, obj_struct);
+ if (sampler != VK_NULL_HANDLE) {
+ PostCallRecordDestroySampler(dev_data, sampler, sampler_state, obj_struct);
+ }
}
}
@@ -5812,7 +5827,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator);
lock.lock();
- PostCallRecordDestroyDescriptorPool(dev_data, descriptorPool, desc_pool_state, obj_struct);
+ if (descriptorPool != VK_NULL_HANDLE) {
+ PostCallRecordDestroyDescriptorPool(dev_data, descriptorPool, desc_pool_state, obj_struct);
+ }
}
}
// Verify cmdBuffer in given cb_node is not in global in-flight set, and return skip_call result
@@ -5972,7 +5989,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyCommandPool(device, commandPool, pAllocator);
lock.lock();
- PostCallRecordDestroyCommandPool(dev_data, commandPool, cp_state);
+ if (commandPool != VK_NULL_HANDLE) {
+ PostCallRecordDestroyCommandPool(dev_data, commandPool, cp_state);
+ }
}
}
@@ -6075,7 +6094,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyFramebuffer(device, framebuffer, pAllocator);
lock.lock();
- PostCallRecordDestroyFramebuffer(dev_data, framebuffer, framebuffer_state, obj_struct);
+ if (framebuffer != VK_NULL_HANDLE) {
+ PostCallRecordDestroyFramebuffer(dev_data, framebuffer, framebuffer_state, obj_struct);
+ }
}
}
@@ -6107,7 +6128,9 @@
lock.unlock();
dev_data->dispatch_table.DestroyRenderPass(device, renderPass, pAllocator);
lock.lock();
- PostCallRecordDestroyRenderPass(dev_data, renderPass, rp_state, obj_struct);
+ if (renderPass != VK_NULL_HANDLE) {
+ PostCallRecordDestroyRenderPass(dev_data, renderPass, rp_state, obj_struct);
+ }
}
}
@@ -6844,8 +6867,11 @@
if (dev_data->instance_data->disabled.free_descriptor_sets) return false;
bool skip_call = false;
// First make sure sets being destroyed are not currently in-use
- for (uint32_t i = 0; i < count; ++i)
- skip_call |= validateIdleDescriptorSet(dev_data, descriptor_sets[i], "vkFreeDescriptorSets");
+ for (uint32_t i = 0; i < count; ++i) {
+ if (descriptor_sets[i] != VK_NULL_HANDLE) {
+ skip_call |= validateIdleDescriptorSet(dev_data, descriptor_sets[i], "vkFreeDescriptorSets");
+ }
+ }
DESCRIPTOR_POOL_STATE *pool_state = getDescriptorPoolState(dev_data, pool);
if (pool_state && !(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT & pool_state->createInfo.flags)) {
@@ -6867,15 +6893,17 @@
// For each freed descriptor add its resources back into the pool as available and remove from pool and setMap
for (uint32_t i = 0; i < count; ++i) {
- auto descriptor_set = dev_data->setMap[descriptor_sets[i]];
- uint32_t type_index = 0, descriptor_count = 0;
- for (uint32_t j = 0; j < descriptor_set->GetBindingCount(); ++j) {
- type_index = static_cast<uint32_t>(descriptor_set->GetTypeFromIndex(j));
- descriptor_count = descriptor_set->GetDescriptorCountFromIndex(j);
- pool_state->availableDescriptorTypeCount[type_index] += descriptor_count;
+ if (descriptor_sets[i] != VK_NULL_HANDLE) {
+ auto descriptor_set = dev_data->setMap[descriptor_sets[i]];
+ uint32_t type_index = 0, descriptor_count = 0;
+ for (uint32_t j = 0; j < descriptor_set->GetBindingCount(); ++j) {
+ type_index = static_cast<uint32_t>(descriptor_set->GetTypeFromIndex(j));
+ descriptor_count = descriptor_set->GetDescriptorCountFromIndex(j);
+ pool_state->availableDescriptorTypeCount[type_index] += descriptor_count;
+ }
+ freeDescriptorSet(dev_data, descriptor_set);
+ pool_state->sets.erase(descriptor_set);
}
- freeDescriptorSet(dev_data, descriptor_set);
- pool_state->sets.erase(descriptor_set);
}
}
diff --git a/layers/object_tracker.cpp b/layers/object_tracker.cpp
index f4acbe3..41811e9 100644
--- a/layers/object_tracker.cpp
+++ b/layers/object_tracker.cpp
@@ -3475,7 +3475,9 @@
ValidateObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false, VALIDATION_ERROR_00099);
ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00098);
for (uint32_t i = 0; i < commandBufferCount; i++) {
- skip_call |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
+ if (pCommandBuffers[i] != VK_NULL_HANDLE) {
+ skip_call |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
+ }
}
for (uint32_t i = 0; i < commandBufferCount; i++) {
@@ -3521,7 +3523,9 @@
ValidateObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false, VALIDATION_ERROR_00924);
skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00923);
for (uint32_t i = 0; i < descriptorSetCount; i++) {
- skip_call |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
+ if (pDescriptorSets[i] != VK_NULL_HANDLE) {
+ skip_call |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
+ }
}
for (uint32_t i = 0; i < descriptorSetCount; i++) {