aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Zulauf <jzulauf@lunarg.com>2019-08-13 15:39:58 -0600
committerJohn Zulauf <32470354+jzulauf-lunarg@users.noreply.github.com>2019-08-23 08:32:38 -0600
commitf1640d150b5a53f59667a785f987cd1f9d98337f (patch)
tree1d1ddf5c1b0eeecc1320dddaa00cbad9deace3c7
parentdadc5a0ce594636977b40f865cafec4b427e2c51 (diff)
downloadvulkan-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.cpp2
-rw-r--r--layers/core_validation.cpp45
-rw-r--r--layers/core_validation.h6
-rw-r--r--layers/core_validation_types.h2
-rw-r--r--tests/vklayertests_command.cpp4
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);