layers: Improve in flight cmd buffer validation
Validation in flight cmd buffers are not reset.
Validate cmd buffer is not in use when freed.
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 38afa39..5ccf56e 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -3755,8 +3755,14 @@
{
layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+ bool skip_call = false;
for (uint32_t i = 0; i < count; i++) {
loader_platform_thread_lock_mutex(&globalLock);
+ if (dev_data->globalInFlightCmdBuffers.count(pCommandBuffers[i])) {
+ skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ reinterpret_cast<uint64_t>(pCommandBuffers[i]), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, "DS",
+ "Attempt to free command buffer (%#" PRIxLEAST64 ") which is in use.", reinterpret_cast<uint64_t>(pCommandBuffers[i]));
+ }
// Delete CB information structure, and remove from commandBufferMap
auto cb = dev_data->commandBufferMap.find(pCommandBuffers[i]);
if (cb != dev_data->commandBufferMap.end()) {
@@ -3771,7 +3777,8 @@
loader_platform_thread_unlock_mutex(&globalLock);
}
- dev_data->device_dispatch_table->FreeCommandBuffers(device, commandPool, count, pCommandBuffers);
+ if (!skip_call)
+ dev_data->device_dispatch_table->FreeCommandBuffers(device, commandPool, count, pCommandBuffers);
}
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool)
@@ -4433,6 +4440,11 @@
"Attempt to reset command buffer (%#" PRIxLEAST64 ") created from command pool (%#" PRIxLEAST64 ") that does NOT have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set.",
(uint64_t) commandBuffer, (uint64_t) cmdPool);
}
+ if (dev_data->globalInFlightCmdBuffers.count(commandBuffer)) {
+ skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t) commandBuffer,
+ __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, "DS",
+ "Attempt to reset command buffer (%#" PRIxLEAST64 ") which is in use.", reinterpret_cast<uint64_t>(commandBuffer));
+ }
if (skipCall != VK_FALSE)
return VK_ERROR_VALIDATION_FAILED_EXT;
VkResult result = dev_data->device_dispatch_table->ResetCommandBuffer(commandBuffer, flags);
diff --git a/layers/draw_state.h b/layers/draw_state.h
index 1a3d9fe..43106d8 100755
--- a/layers/draw_state.h
+++ b/layers/draw_state.h
@@ -94,7 +94,7 @@
DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, // Clear cmd issued before any Draw in CommandBuffer, should use RenderPass Ops instead
DRAWSTATE_BEGIN_CB_INVALID_STATE, // CB state at Begin call is bad. Can be Primary/Secondary CB created with mismatched FB/RP information or CB in RECORDING state
DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, // CmdBuffer is being used in violation of VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT rules (i.e. simultaneous use w/o that bit set)
- DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, // Attempting to call Reset (or Begin on recorded cmdBuffer) that was allocated from Pool w/o VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set
+ DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, // Attempting to call Reset (or Begin on recorded cmdBuffer) that was allocated from Pool w/o VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set. Can also happen when the command buffer is being reset (or freed) when in use.
DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, // Count for viewports and scissors mismatch and/or state doesn't match count
DRAWSTATE_INVALID_IMAGE_ASPECT, // Image aspect is invalid for the current operation
DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, // Attachment reference must be present in active subpass