diff options
author | John Zulauf <jzulauf@lunarg.com> | 2019-08-13 15:39:58 -0600 |
---|---|---|
committer | John Zulauf <32470354+jzulauf-lunarg@users.noreply.github.com> | 2019-08-23 08:32:38 -0600 |
commit | f1640d150b5a53f59667a785f987cd1f9d98337f (patch) | |
tree | 1d1ddf5c1b0eeecc1320dddaa00cbad9deace3c7 | |
parent | dadc5a0ce594636977b40f865cafec4b427e2c51 (diff) | |
download | vulkan-validation-layers-f1640d150b5a53f59667a785f987cd1f9d98337f.tar.gz |
layers: VST refactor CmdExecuteCommands
Segregate state tracking and validation, including const clean up of
validation, which in turn required a disentangle of three commingled
VUID tests.
CmdExecuteCommands
Change-Id: I3fb416795dc0694706a70e03d9ebe26e6913a3c9
-rw-r--r-- | layers/buffer_validation.cpp | 2 | ||||
-rw-r--r-- | layers/core_validation.cpp | 45 | ||||
-rw-r--r-- | layers/core_validation.h | 6 | ||||
-rw-r--r-- | layers/core_validation_types.h | 2 | ||||
-rw-r--r-- | tests/vklayertests_command.cpp | 4 |
5 files changed, 40 insertions, 19 deletions
diff --git a/layers/buffer_validation.cpp b/layers/buffer_validation.cpp index f9e8d900f..6c5545ce6 100644 --- a/layers/buffer_validation.cpp +++ b/layers/buffer_validation.cpp @@ -2952,7 +2952,7 @@ void CoreChecks::PreCallRecordCmdClearAttachments(VkCommandBuffer commandBuffer, // if a secondary level command buffer inherits the framebuffer from the primary command buffer // (see VkCommandBufferInheritanceInfo), this validation must be deferred until queue submit time auto val_fn = [this, commandBuffer, attachment_index, fb_attachment, rectCount, clear_rect_copy]( - CMD_BUFFER_STATE *prim_cb, VkFramebuffer fb) { + const CMD_BUFFER_STATE *prim_cb, VkFramebuffer fb) { assert(rectCount == clear_rect_copy->size()); const FRAMEBUFFER_STATE *framebuffer = GetFramebufferState(fb); const auto &render_area = prim_cb->activeRenderPassBeginInfo.renderArea; diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index f77f530ef..928ca409a 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -8170,7 +8170,7 @@ bool CoreChecks::ValidateRenderPassImageBarriers(const char *funcName, CMD_BUFFE if (VK_NULL_HANDLE == cb_state->activeFramebuffer) { assert(VK_COMMAND_BUFFER_LEVEL_SECONDARY == cb_state->createInfo.level); // Secondary CB case w/o FB specified delay validation - cb_state->cmd_execute_commands_functions.emplace_back([=](CMD_BUFFER_STATE *primary_cb, VkFramebuffer fb) { + cb_state->cmd_execute_commands_functions.emplace_back([=](const CMD_BUFFER_STATE *primary_cb, VkFramebuffer fb) { return ValidateImageBarrierImage(funcName, cb_state, fb, active_subpass, sub_desc, rp_handle, i, img_barrier); }); } else { @@ -11468,7 +11468,7 @@ bool CoreChecks::ValidateFramebuffer(VkCommandBuffer primaryBuffer, const CMD_BU return skip; } -bool CoreChecks::ValidateSecondaryCommandBufferState(CMD_BUFFER_STATE *pCB, CMD_BUFFER_STATE *pSubCB) { +bool CoreChecks::ValidateSecondaryCommandBufferState(const CMD_BUFFER_STATE *pCB, const CMD_BUFFER_STATE *pSubCB) { bool skip = false; unordered_set<int> activeTypes; if (!disabled.query_validation) { @@ -11520,11 +11520,11 @@ bool CoreChecks::ValidateSecondaryCommandBufferState(CMD_BUFFER_STATE *pCB, CMD_ bool CoreChecks::PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, const VkCommandBuffer *pCommandBuffers) { - CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer); + const CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer); assert(cb_state); bool skip = false; - CMD_BUFFER_STATE *sub_cb_state = NULL; - std::unordered_set<CMD_BUFFER_STATE *> linked_command_buffers = cb_state->linkedCommandBuffers; + const CMD_BUFFER_STATE *sub_cb_state = NULL; + std::unordered_set<const CMD_BUFFER_STATE *> linked_command_buffers; for (uint32_t i = 0; i < commandBuffersCount; i++) { sub_cb_state = GetCBState(pCommandBuffers[i]); @@ -11537,7 +11537,7 @@ bool CoreChecks::PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer report_data->FormatHandle(pCommandBuffers[i]).c_str(), i); } else if (VK_COMMAND_BUFFER_LEVEL_SECONDARY == sub_cb_state->createInfo.level) { if (sub_cb_state->beginInfo.pInheritanceInfo != nullptr) { - auto secondary_rp_state = GetRenderPassState(sub_cb_state->beginInfo.pInheritanceInfo->renderPass); + const auto secondary_rp_state = GetRenderPassState(sub_cb_state->beginInfo.pInheritanceInfo->renderPass); if (cb_state->activeRenderPass && !(sub_cb_state->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, @@ -11583,12 +11583,31 @@ bool CoreChecks::PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer skip |= ValidateCommandBufferState(sub_cb_state, "vkCmdExecuteCommands()", 0, "VUID-vkCmdExecuteCommands-pCommandBuffers-00089"); if (!(sub_cb_state->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { - if (sub_cb_state->in_use.load() || linked_command_buffers.count(sub_cb_state)) { + if (sub_cb_state->in_use.load()) { + // TODO: Find some way to differentiate between the -00090 and -00091 conditions skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_state->commandBuffer), "VUID-vkCmdExecuteCommands-pCommandBuffers-00090", - "Attempt to simultaneously execute %s without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!", + "Cannot execute pending %s without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set.", + report_data->FormatHandle(sub_cb_state->commandBuffer).c_str()); + } + // We use an const_cast, because one cannot query a container keyed on a non-const pointer using a const pointer + if (cb_state->linkedCommandBuffers.count(const_cast<CMD_BUFFER_STATE *>(sub_cb_state))) { + skip |= log_msg( + report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, + HandleToUint64(cb_state->commandBuffer), "VUID-vkCmdExecuteCommands-pCommandBuffers-00092", + "Cannot execute %s without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set if previously executed in %s", + report_data->FormatHandle(sub_cb_state->commandBuffer).c_str(), + report_data->FormatHandle(cb_state->commandBuffer).c_str()); + } + + const auto insert_pair = linked_command_buffers.insert(sub_cb_state); + if (!insert_pair.second) { + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, + HandleToUint64(cb_state->commandBuffer), "VUID-vkCmdExecuteCommands-pCommandBuffers-00093", + "Cannot duplicate %s in pCommandBuffers without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set.", report_data->FormatHandle(cb_state->commandBuffer).c_str()); } + if (cb_state->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) { // Warn that non-simultaneous secondary cmd buffer renders primary non-simultaneous skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, @@ -11647,9 +11666,8 @@ bool CoreChecks::PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer } } } - - linked_command_buffers.insert(sub_cb_state); } + skip |= ValidatePrimaryCommandBuffer(cb_state, "vkCmdExecuteCommands()", "VUID-vkCmdExecuteCommands-bufferlevel"); skip |= ValidateCmdQueueFlags(cb_state, "vkCmdExecuteCommands()", VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, @@ -11658,8 +11676,8 @@ bool CoreChecks::PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer return skip; } -void CoreChecks::PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, - const VkCommandBuffer *pCommandBuffers) { +void ValidationStateTracker::PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, + const VkCommandBuffer *pCommandBuffers) { CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer); CMD_BUFFER_STATE *sub_cb_state = NULL; @@ -11675,6 +11693,9 @@ void CoreChecks::PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, } // Propagate inital layout and current layout state to the primary cmd buffer + // NOTE: The update/population of the image_layout_map is done in CoreChecks, but for other classes derived from + // ValidationStateTracker these maps will be empty, so leaving the propagation in the the state tracker should be a no-op + // for those other classes. for (const auto &sub_layout_map_entry : sub_cb_state->image_layout_map) { const auto image = sub_layout_map_entry.first; const auto *image_state = GetImageState(image); diff --git a/layers/core_validation.h b/layers/core_validation.h index 31598da13..3e2c043d0 100644 --- a/layers/core_validation.h +++ b/layers/core_validation.h @@ -667,6 +667,8 @@ class ValidationStateTracker : public ValidationObject { void PostCallRecordCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index); void PostCallRecordCmdEndRenderPass(VkCommandBuffer commandBuffer); void PostCallRecordCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo); + void PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, + const VkCommandBuffer* pCommandBuffers); void PreCallRecordCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); void PreCallRecordCmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); @@ -969,7 +971,7 @@ class CoreChecks : public ValidationStateTracker { const safe_VkSubpassDependency2KHR* dependencies, const std::vector<uint32_t>& self_dependencies, uint32_t image_mem_barrier_count, const VkImageMemoryBarrier* image_barriers); - bool ValidateSecondaryCommandBufferState(CMD_BUFFER_STATE* pCB, CMD_BUFFER_STATE* pSubCB); + bool ValidateSecondaryCommandBufferState(const CMD_BUFFER_STATE* pCB, const CMD_BUFFER_STATE* pSubCB); bool ValidateFramebuffer(VkCommandBuffer primaryBuffer, const CMD_BUFFER_STATE* pCB, VkCommandBuffer secondaryBuffer, const CMD_BUFFER_STATE* pSubCB, const char* caller); bool ValidateDescriptorUpdateTemplate(const char* func_name, const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo); @@ -1845,8 +1847,6 @@ class CoreChecks : public ValidationStateTracker { void PostCallRecordCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo); bool PreCallValidateCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, const VkCommandBuffer* pCommandBuffers); - void PreCallRecordCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, - const VkCommandBuffer* pCommandBuffers); bool PreCallValidateMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags, void** ppData); void PostCallRecordMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags, diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index a8ec77da1..f4b2239e1 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -1464,7 +1464,7 @@ struct CMD_BUFFER_STATE : public BASE_NODE { // Validation functions run at primary CB queue submit time std::vector<std::function<bool()>> queue_submit_functions; // Validation functions run when secondary CB is executed in primary - std::vector<std::function<bool(CMD_BUFFER_STATE *, VkFramebuffer)>> cmd_execute_commands_functions; + std::vector<std::function<bool(const CMD_BUFFER_STATE *, VkFramebuffer)>> cmd_execute_commands_functions; std::unordered_set<VkDeviceMemory> memObjs; std::vector<std::function<bool(VkQueue)>> eventUpdates; std::vector<std::function<bool(VkQueue)>> queryUpdates; diff --git a/tests/vklayertests_command.cpp b/tests/vklayertests_command.cpp index 3724cc878..3c44562bd 100644 --- a/tests/vklayertests_command.cpp +++ b/tests/vklayertests_command.cpp @@ -928,7 +928,7 @@ TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) { TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) { ASSERT_NO_FATAL_FAILURE(Init()); - const char *simultaneous_use_message = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!"; + const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00092"; VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); @@ -955,7 +955,7 @@ TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) { // variation on previous test executing the same CB twice in the same // CmdExecuteCommands call - const char *simultaneous_use_message = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!"; + const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00093"; VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |