layers: Add Secondary Command Buffer Validation.
Merge Request 51
Conflicts:
layers/draw_state.cpp
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
old mode 100755
new mode 100644
index d96794f..55ae040
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -1324,9 +1324,25 @@
return log_msg(dev_data->report_data, VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NO_BEGIN_COMMAND_BUFFER, "DS",
"You must call vkBeginCommandBuffer() before this call to %s", (void*)caller_name);
}
+
+bool validateCmdsInCmdBuffer(const layer_data* dev_data, const GLOBAL_CB_NODE* pCB, const CMD_TYPE cmd_type) {
+ bool skip_call = false;
+ for (auto cmd : pCB->pCmds) {
+ if (cmd_type == CMD_EXECUTECOMMANDS && cmd->type != CMD_EXECUTECOMMANDS) {
+ skip_call |= log_msg(dev_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
+ "vkCmdExecuteCommands() cannot be called on a cmd buffer with exsiting commands.");
+ }
+ if (cmd_type != CMD_EXECUTECOMMANDS && cmd->type == CMD_EXECUTECOMMANDS) {
+ skip_call |= log_msg(dev_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
+ "Commands cannot be added to a cmd buffer with exsiting secondary commands.");
+ }
+ }
+ return skip_call;
+}
+
static VkBool32 addCmd(const layer_data* my_data, GLOBAL_CB_NODE* pCB, const CMD_TYPE cmd)
{
- VkBool32 skipCall = VK_FALSE;
+ VkBool32 skipCall = validateCmdsInCmdBuffer(my_data, pCB, cmd);
CMD_NODE* pCmd = new CMD_NODE;
if (pCmd) {
// init cmd node and append to end of cmd LL
@@ -3961,7 +3977,7 @@
}
}
}
- if ((subpass.pDepthStencilAttachment != NULL) &&
+ if ((subpass.pDepthStencilAttachment != NULL) &&
(subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) {
const VkImageView& image_view = pFramebufferInfo->pAttachments[subpass.pDepthStencilAttachment->attachment];
auto image_view_data = dev_data->imageViewMap.find(image_view);
@@ -3974,6 +3990,15 @@
}
}
+bool validatePrimaryCommandBuffer(const layer_data* my_data, const GLOBAL_CB_NODE* pCB, const std::string& cmd_name) {
+ bool skip_call = false;
+ if (pCB->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
+ skip_call |= log_msg(my_data->report_data, VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType)0, 0, 0, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
+ "Cannot execute command %s on a secondary command buffer.", cmd_name.c_str());
+ }
+ return skip_call;
+}
+
void TransitionFinalSubpassLayouts(VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin) {
layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
@@ -4009,6 +4034,7 @@
skipCall |= VerifyFramebufferAndRenderPassLayouts(commandBuffer, pRenderPassBegin);
skipCall |= insideRenderPass(dev_data, pCB, "vkCmdBeginRenderPass");
updateCBTracking(pCB);
+ skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdBeginRenderPass");
skipCall |= addCmd(dev_data, pCB, CMD_BEGINRENDERPASS);
pCB->activeRenderPass = pRenderPassBegin->renderPass;
// This is a shallow copy as that is all that is needed for now
@@ -4039,6 +4065,7 @@
TransitionSubpassLayouts(commandBuffer, &dev_data->renderPassBeginInfo, ++dev_data->currentSubpass);
if (pCB) {
updateCBTracking(pCB);
+ skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdNextSubpass");
skipCall |= addCmd(dev_data, pCB, CMD_NEXTSUBPASS);
pCB->activeSubpass++;
TransitionSubpassLayouts(commandBuffer, &pCB->activeRenderPassBeginInfo, ++pCB->activeSubpass);
@@ -4058,8 +4085,9 @@
GLOBAL_CB_NODE* pCB = getCBNode(dev_data, commandBuffer);
TransitionFinalSubpassLayouts(commandBuffer, &dev_data->renderPassBeginInfo);
if (pCB) {
- skipCall |= outsideRenderPass(dev_data, pCB, "vkEndRenderpass");
+ skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdEndRenderpass");
updateCBTracking(pCB);
+ skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdEndRenderPass");
skipCall |= addCmd(dev_data, pCB, CMD_ENDRENDERPASS);
TransitionFinalSubpassLayouts(commandBuffer, &pCB->activeRenderPassBeginInfo);
pCB->activeRenderPass = 0;
@@ -4087,6 +4115,7 @@
}
}
updateCBTracking(pCB);
+ skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdExecuteComands");
skipCall |= addCmd(dev_data, pCB, CMD_EXECUTECOMMANDS);
}
if (VK_FALSE == skipCall)