for (uint32_t j = 0; j < rectCount; j++) {
// The rectangular region specified by a given element of pRects must be contained within the render area of
// the current render pass instance
- // TODO: This check should be moved to CmdExecuteCommands or QueueSubmit to cover secondary CB cases
- if ((cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) &&
- (false == ContainsRect(cb_node->activeRenderPassBeginInfo.renderArea, pRects[j].rect))) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
+ if (false == ContainsRect(cb_node->activeRenderPassBeginInfo.renderArea, pRects[j].rect)) {
+ skip |=
+ log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_18600020, "DS",
"vkCmdClearAttachments(): The area defined by pRects[%d] is not contained in the area of "
"the current render pass instance. %s",
j, validation_error_map[VALIDATION_ERROR_18600020]);
+ }
+ } else {
+ cb_node->cmd_execute_commands_functions.emplace_back([=](GLOBAL_CB_NODE *prim_cb, VkFramebuffer fb) {
+ if (false == ContainsRect(prim_cb->activeRenderPassBeginInfo.renderArea, pRects[j].rect)) {
+ return log_msg(
+ report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+ HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_18600020, "DS",
+ "vkCmdClearAttachments(): The area defined by pRects[%d] is not contained in the area of "
+ "the current render pass instance. %s",
+ j, validation_error_map[VALIDATION_ERROR_18600020]);
+ }
+ return false;
+ });
}
// The layers specified by a given element of pRects must be contained within every attachment that
// pAttachments refers to
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([=](VkFramebuffer fb) {
+ cb_state->cmd_execute_commands_functions.emplace_back([=](GLOBAL_CB_NODE *primary_cb, VkFramebuffer fb) {
return ValidateImageBarrierImage(device_data, funcName, cb_state, fb, active_subpass, sub_desc, rp_handle, i,
img_barrier);
});
// If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB
skip |=
validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB, "vkCmdExecuteCommands()");
- if (VK_NULL_HANDLE == pSubCB->activeFramebuffer) {
+ if (!pSubCB->cmd_execute_commands_functions.empty()) {
// Inherit primary's activeFramebuffer and while running validate functions
for (auto &function : pSubCB->cmd_execute_commands_functions) {
- skip |= function(pCB->activeFramebuffer);
+ skip |= function(pCB, pCB->activeFramebuffer);
}
}
}
// 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(VkFramebuffer)>> cmd_execute_commands_functions;
+ std::vector<std::function<bool(GLOBAL_CB_NODE *, VkFramebuffer)>> cmd_execute_commands_functions;
std::unordered_set<VkDeviceMemory> memObjs;
std::vector<std::function<bool(VkQueue)>> eventUpdates;
std::vector<std::function<bool(VkQueue)>> queryUpdates;