From 31d9f4a475cdff6bd6d0a08cacacea57fb733dfa Mon Sep 17 00:00:00 2001 From: Tobin Ehlis Date: Wed, 7 Sep 2016 11:09:01 -0600 Subject: [PATCH] layers: Update bound object increment and decrement functions Unify the handling of in-use increment/decrement for QueryPool, Pipeline, Image, Buffer, and Event objects. --- layers/core_validation.cpp | 111 ++++++++++++++++++++++++++++------ layers/core_validation_error_enums.h | 2 + layers/vk_validation_layer_details.md | 2 + 3 files changed, 96 insertions(+), 19 deletions(-) diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 5d8ac64..1fb8197 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -4493,7 +4493,7 @@ static bool ValidateCmdBufImageLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB // Loop through bound objects and increment their in_use counts // For any unknown objects, flag an error -static bool ValidateAndIncrementBoundObjects(layer_data const *dev_data, GLOBAL_CB_NODE const *cb_node) { +static bool ValidateAndIncrementBoundObjects(layer_data *dev_data, GLOBAL_CB_NODE const *cb_node) { bool skip_call = false; for (auto obj : cb_node->object_bindings) { switch (obj.type) { @@ -4520,6 +4520,61 @@ static bool ValidateAndIncrementBoundObjects(layer_data const *dev_data, GLOBAL_ } break; } + case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: { + auto qp_node = getQueryPoolNode(dev_data, reinterpret_cast(obj.handle)); + if (!qp_node) { + skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, obj.handle, __LINE__, MEMTRACK_INVALID_OBJECT, + "DS", "Cannot submit cmd buffer using deleted query pool 0x%" PRIx64 ".", obj.handle); + } else { + qp_node->in_use.fetch_add(1); + } + break; + } + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: { + auto pipe_node = getPipeline(dev_data, reinterpret_cast(obj.handle)); + if (!pipe_node) { + skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, + obj.handle, __LINE__, DRAWSTATE_INVALID_PIPELINE, "DS", + "Cannot submit cmd buffer using deleted pipeline 0x%" PRIx64 ".", obj.handle); + } else { + pipe_node->in_use.fetch_add(1); + } + break; + } + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: { + auto buff_node = getBufferNode(dev_data, reinterpret_cast(obj.handle)); + if (!buff_node) { + skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, + obj.handle, __LINE__, DRAWSTATE_INVALID_BUFFER, "DS", + "Cannot submit cmd buffer using deleted buffer 0x%" PRIx64 ".", obj.handle); + } else { + buff_node->in_use.fetch_add(1); + } + break; + } + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: { + auto image_node = getImageNode(dev_data, reinterpret_cast(obj.handle)); + if (!image_node) { + skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, + obj.handle, __LINE__, DRAWSTATE_INVALID_IMAGE, "DS", + "Cannot submit cmd buffer using deleted image 0x%" PRIx64 ".", obj.handle); + } else { + image_node->in_use.fetch_add(1); + } + break; + } + case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: { + auto event_node = getEventNode(dev_data, reinterpret_cast(obj.handle)); + if (!event_node) { + skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, + obj.handle, __LINE__, DRAWSTATE_INVALID_EVENT, "DS", + "Cannot submit cmd buffer using deleted event 0x%" PRIx64 ".", obj.handle); + } else { + event_node->in_use.fetch_add(1); + } + break; + } default: // TODO : Merge handling of other objects types into this code break; @@ -4552,17 +4607,6 @@ static bool validateAndIncrementResources(layer_data *dev_data, GLOBAL_CB_NODE * } } } - for (auto event : cb_node->events) { - auto event_node = getEventNode(dev_data, event); - if (!event_node) { - skip_call |= - log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, - reinterpret_cast(event), __LINE__, DRAWSTATE_INVALID_EVENT, "DS", - "Cannot submit cmd buffer using deleted event 0x%" PRIx64 ".", reinterpret_cast(event)); - } else { - event_node->in_use.fetch_add(1); - } - } for (auto event : cb_node->writeEventsBeforeWait) { auto event_node = getEventNode(dev_data, event); if (event_node) @@ -4605,7 +4649,7 @@ static inline void removeInFlightCmdBuffer(layer_data *dev_data, VkCommandBuffer } // Decrement in-use count for objects bound to command buffer -static void DecrementBoundResources(layer_data const *dev_data, GLOBAL_CB_NODE const *cb_node) { +static void DecrementBoundResources(layer_data *dev_data, GLOBAL_CB_NODE const *cb_node) { for (auto obj : cb_node->object_bindings) { switch (obj.type) { case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: { @@ -4622,6 +4666,41 @@ static void DecrementBoundResources(layer_data const *dev_data, GLOBAL_CB_NODE c } break; } + case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: { + auto qp_node = getQueryPoolNode(dev_data, reinterpret_cast(obj.handle)); + if (qp_node) { + qp_node->in_use.fetch_sub(1); + } + break; + } + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: { + auto pipe_node = getPipeline(dev_data, reinterpret_cast(obj.handle)); + if (pipe_node) { + pipe_node->in_use.fetch_sub(1); + } + break; + } + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: { + auto buff_node = getBufferNode(dev_data, reinterpret_cast(obj.handle)); + if (buff_node) { + buff_node->in_use.fetch_sub(1); + } + break; + } + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: { + auto image_node = getImageNode(dev_data, reinterpret_cast(obj.handle)); + if (image_node) { + image_node->in_use.fetch_sub(1); + } + break; + } + case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: { + auto event_node = getEventNode(dev_data, reinterpret_cast(obj.handle)); + if (event_node) { + event_node->in_use.fetch_sub(1); + } + break; + } default: // TODO : Merge handling of other objects types into this code break; @@ -4662,12 +4741,6 @@ static bool RetireWorkOnQueue(layer_data *dev_data, QUEUE_NODE *pQueue, uint64_t } } } - for (auto event : cb_node->events) { - auto eventNode = dev_data->eventMap.find(event); - if (eventNode != dev_data->eventMap.end()) { - eventNode->second.in_use.fetch_sub(1); - } - } for (auto event : cb_node->writeEventsBeforeWait) { auto eventNode = dev_data->eventMap.find(event); if (eventNode != dev_data->eventMap.end()) { diff --git a/layers/core_validation_error_enums.h b/layers/core_validation_error_enums.h index a736a5a..e55ef3a 100644 --- a/layers/core_validation_error_enums.h +++ b/layers/core_validation_error_enums.h @@ -61,7 +61,9 @@ enum DRAW_STATE_ERROR { DRAWSTATE_INVALID_COMMAND_BUFFER, // Invalid CommandBuffer referenced DRAWSTATE_INVALID_BARRIER, // Invalid Barrier DRAWSTATE_INVALID_BUFFER, // Invalid Buffer + DRAWSTATE_INVALID_IMAGE, // Invalid Image DRAWSTATE_INVALID_QUERY, // Invalid Query + DRAWSTATE_INVALID_QUERY_POOL, // Invalid QueryPool DRAWSTATE_INVALID_FENCE, // Invalid Fence DRAWSTATE_INVALID_EVENT, // Invalid Event DRAWSTATE_INVALID_SAMPLER, // Invalid Sampler diff --git a/layers/vk_validation_layer_details.md b/layers/vk_validation_layer_details.md index 80ae89a..fdc132b 100644 --- a/layers/vk_validation_layer_details.md +++ b/layers/vk_validation_layer_details.md @@ -89,6 +89,8 @@ The Draw State portion of the core validation layer tracks state leading into Dr | Verify Image Layouts | Validate correct image layouts for presents, image transitions, command buffers and renderpasses | INVALID_IMAGE_LAYOUT | vkCreateRenderPass vkMapMemory vkQueuePresentKHR vkQueueSubmit vkCmdCopyImage vkCmdCopyImageToBuffer vkCmdWaitEvents VkCmdPipelineBarrier | InvalidImageLayout MapMemWithoutHostVisibleBit | None | | Verify Memory Access Flags/Memory Barriers | Validate correct access flags for memory barriers | INVALID_BARRIER | vkCmdWaitEvents vkCmdPipelineBarrier | InvalidBarriers | None | | Verify Memory Buffer Not Deleted | Validate Command Buffer not submitted with deleted memory buffer | INVALID_BUFFER | vkQueueSubmit | VertexBufferInvalid | None | +| Verify Image Not Deleted | Validate Command Buffer not submitted with deleted image | INVALID_IMAGE | vkQueueSubmit | TODO | Write test (or record here if we already have one) | +| Verify Query Pool Not Deleted | Validate Command Buffer not submitted with deleted query pool | INVALID_QUERY_POOL | vkQueueSubmit | TODO | Write test (or record here if we already have one) | | Verify Memory Buffer Destroy | Validate memory buffers are not destroyed more than once | DOUBLE_DESTROY | vkDestroyBuffer | VertexBufferInvalid | None | | Verify Object Not In Use | Validate that object being freed or modified is not in use | OBJECT_INUSE | vkDestroyBuffer vkFreeDescriptorSets vkUpdateDescriptorSets vkDestroySemaphore | InUseDestroyedSignaled InvalidCmdBufferDescriptorSetImageSamplerDestroyed | NA | | Verify Get Queries| Validate that queries are properly setup, initialized and synchronized | INVALID_QUERY | vkGetFenceStatus vkQueueWaitIdle vkWaitForFences vkDeviceWaitIdle vkCmdBeginQuery vkCmdEndQuery | InvalidQueueIndexInvalidQuery | May need to check existing case against object_tracker and remove any redundant checks. Then write tests for remaining case. Currently there are 8 cases for this check with 1 each in cleanInFlightCmdBuffer(), EndCommandBuffer(), CmdEndQuery(), validateQuery(), and 4 cases in GetQueryPoolResults() | -- 2.7.4