@@ -867,8 +867,9 @@ static bool validateSubpassCompatibility(layer_data const *dev_data, const char
867867 if (i < secondary_desc.inputAttachmentCount) {
868868 secondary_input_attach = secondary_desc.pInputAttachments[i].attachment;
869869 }
870- skip |= validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_input_attach,
871- secondary_input_attach, caller, error_code);
870+ if (validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_input_attach,
871+ secondary_input_attach, caller, error_code))
872+ return true;
872873 }
873874 uint32_t maxColorAttachmentCount = std::max(primary_desc.colorAttachmentCount, secondary_desc.colorAttachmentCount);
874875 for (uint32_t i = 0; i < maxColorAttachmentCount; ++i) {
@@ -879,17 +880,20 @@ static bool validateSubpassCompatibility(layer_data const *dev_data, const char
879880 if (i < secondary_desc.colorAttachmentCount) {
880881 secondary_color_attach = secondary_desc.pColorAttachments[i].attachment;
881882 }
882- skip |= validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_color_attach,
883- secondary_color_attach, caller, error_code);
883+ if (validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_color_attach,
884+ secondary_color_attach, caller, error_code))
885+ return true;
886+
884887 uint32_t primary_resolve_attach = VK_ATTACHMENT_UNUSED, secondary_resolve_attach = VK_ATTACHMENT_UNUSED;
885888 if (i < primary_desc.colorAttachmentCount && primary_desc.pResolveAttachments) {
886889 primary_resolve_attach = primary_desc.pResolveAttachments[i].attachment;
887890 }
888891 if (i < secondary_desc.colorAttachmentCount && secondary_desc.pResolveAttachments) {
889892 secondary_resolve_attach = secondary_desc.pResolveAttachments[i].attachment;
890893 }
891- skip |= validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_resolve_attach,
892- secondary_resolve_attach, caller, error_code);
894+ if (validateAttachmentCompatibility(dev_data, type1_string, rp1_state, type2_string, rp2_state, primary_resolve_attach,
895+ secondary_resolve_attach, caller, error_code))
896+ return true;
893897 }
894898 uint32_t primary_depthstencil_attach = VK_ATTACHMENT_UNUSED, secondary_depthstencil_attach = VK_ATTACHMENT_UNUSED;
895899 if (primary_desc.pDepthStencilAttachment) {
@@ -8051,87 +8055,90 @@ VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, con
80518055 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
80528056 unique_lock_t lock(global_lock);
80538057 GLOBAL_CB_NODE *cb_node = GetCBNode(dev_data, commandBuffer);
8054- auto render_pass_state = pRenderPassBegin ? GetRenderPassState(dev_data, pRenderPassBegin->renderPass) : nullptr;
8055- auto framebuffer = pRenderPassBegin ? GetFramebufferState(dev_data, pRenderPassBegin->framebuffer) : nullptr;
8056- if (cb_node) {
8057- if (render_pass_state) {
8058- uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
8059- cb_node->activeFramebuffer = pRenderPassBegin->framebuffer;
8060- for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) {
8061- MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
8062- auto pAttachment = &render_pass_state->createInfo.pAttachments[i];
8063- if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8064- VK_ATTACHMENT_LOAD_OP_CLEAR)) {
8065- clear_op_size = static_cast<uint32_t>(i) + 1;
8066- std::function<bool()> function = [=]() {
8067- SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), true);
8068- return false;
8069- };
8070- cb_node->queue_submit_functions.push_back(function);
8071- } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
8072- pAttachment->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
8073- std::function<bool()> function = [=]() {
8074- SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), false);
8075- return false;
8076- };
8077- cb_node->queue_submit_functions.push_back(function);
8078- } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
8079- pAttachment->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_LOAD)) {
8080- std::function<bool()> function = [=]() {
8081- return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image),
8082- "vkCmdBeginRenderPass()");
8083- };
8084- cb_node->queue_submit_functions.push_back(function);
8085- }
8086- if (render_pass_state->attachment_first_read[i]) {
8087- std::function<bool()> function = [=]() {
8088- return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image),
8089- "vkCmdBeginRenderPass()");
8090- };
8091- cb_node->queue_submit_functions.push_back(function);
8092- }
8093- }
8094- if (clear_op_size > pRenderPassBegin->clearValueCount) {
8095- skip |= log_msg(
8096- dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
8097- HandleToUint64(render_pass_state->renderPass), __LINE__, VALIDATION_ERROR_1200070c, "DS",
8098- "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there must "
8099- "be at least %u entries in pClearValues array to account for the highest index attachment in renderPass "
8100- "0x%" PRIx64
8101- " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array "
8102- "is indexed by attachment number so even if some pClearValues entries between 0 and %u correspond to "
8103- "attachments that aren't cleared they will be ignored. %s",
8104- pRenderPassBegin->clearValueCount, clear_op_size, HandleToUint64(render_pass_state->renderPass), clear_op_size,
8105- clear_op_size - 1, validation_error_map[VALIDATION_ERROR_1200070c]);
8106- }
8107- skip |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin);
8108- skip |= VerifyFramebufferAndRenderPassLayouts(dev_data, cb_node, pRenderPassBegin,
8109- GetFramebufferState(dev_data, pRenderPassBegin->framebuffer));
8110- if (framebuffer->rp_state->renderPass != render_pass_state->renderPass) {
8111- skip |= validateRenderPassCompatibility(dev_data, "render pass", render_pass_state, "framebuffer",
8112- framebuffer->rp_state.get(), "vkCmdBeginRenderPass()",
8113- VALIDATION_ERROR_12000710);
8114- }
8115- skip |= insideRenderPass(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00017);
8116- skip |= ValidateDependencies(dev_data, framebuffer, render_pass_state);
8117- skip |= validatePrimaryCommandBuffer(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00019);
8118- skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBeginRenderPass()", VK_QUEUE_GRAPHICS_BIT,
8119- VALIDATION_ERROR_17a02415);
8120- skip |= ValidateCmd(dev_data, cb_node, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()");
8121- cb_node->activeRenderPass = render_pass_state;
8122- // This is a shallow copy as that is all that is needed for now
8123- cb_node->activeRenderPassBeginInfo = *pRenderPassBegin;
8124- cb_node->activeSubpass = 0;
8125- cb_node->activeSubpassContents = contents;
8126- cb_node->framebuffers.insert(pRenderPassBegin->framebuffer);
8127- // Connect this framebuffer and its children to this cmdBuffer
8128- AddFramebufferBinding(dev_data, cb_node, framebuffer);
8129- // transition attachments to the correct layouts for beginning of renderPass and first subpass
8130- TransitionBeginRenderPassLayouts(dev_data, cb_node, render_pass_state, framebuffer);
8131- }
8132- }
8133- lock.unlock();
8058+ assert(cb_node);
8059+ assert(pRenderPassBegin);
8060+ auto render_pass_state = GetRenderPassState(dev_data, pRenderPassBegin->renderPass);
8061+ auto framebuffer = GetFramebufferState(dev_data, pRenderPassBegin->framebuffer);
8062+ assert(render_pass_state);
8063+ assert(framebuffer);
8064+
8065+ uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
8066+ for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) {
8067+ auto pAttachment = &render_pass_state->createInfo.pAttachments[i];
8068+ if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8069+ VK_ATTACHMENT_LOAD_OP_CLEAR)) {
8070+ clear_op_size = static_cast<uint32_t>(i) + 1;
8071+ }
8072+ }
8073+ if (clear_op_size > pRenderPassBegin->clearValueCount) {
8074+ skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
8075+ HandleToUint64(render_pass_state->renderPass), __LINE__, VALIDATION_ERROR_1200070c, "DS",
8076+ "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there must "
8077+ "be at least %u entries in pClearValues array to account for the highest index attachment in renderPass "
8078+ "0x%" PRIx64
8079+ " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array "
8080+ "is indexed by attachment number so even if some pClearValues entries between 0 and %u correspond to "
8081+ "attachments that aren't cleared they will be ignored. %s",
8082+ pRenderPassBegin->clearValueCount, clear_op_size, HandleToUint64(render_pass_state->renderPass),
8083+ clear_op_size, clear_op_size - 1, validation_error_map[VALIDATION_ERROR_1200070c]);
8084+ }
8085+ skip |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin);
8086+ skip |= VerifyFramebufferAndRenderPassLayouts(dev_data, cb_node, pRenderPassBegin,
8087+ GetFramebufferState(dev_data, pRenderPassBegin->framebuffer));
8088+ if (framebuffer->rp_state->renderPass != render_pass_state->renderPass) {
8089+ skip |= validateRenderPassCompatibility(dev_data, "render pass", render_pass_state, "framebuffer",
8090+ framebuffer->rp_state.get(), "vkCmdBeginRenderPass()", VALIDATION_ERROR_12000710);
8091+ }
8092+ skip |= insideRenderPass(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00017);
8093+ skip |= ValidateDependencies(dev_data, framebuffer, render_pass_state);
8094+ skip |= validatePrimaryCommandBuffer(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00019);
8095+ skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBeginRenderPass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_17a02415);
8096+ skip |= ValidateCmd(dev_data, cb_node, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()");
81348097 if (!skip) {
8098+ // Perform state updates prior to call down chain
8099+ cb_node->activeFramebuffer = pRenderPassBegin->framebuffer;
8100+ for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) {
8101+ MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
8102+ auto pAttachment = &render_pass_state->createInfo.pAttachments[i];
8103+ if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8104+ VK_ATTACHMENT_LOAD_OP_CLEAR)) {
8105+ std::function<bool()> function = [=]() {
8106+ SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), true);
8107+ return false;
8108+ };
8109+ cb_node->queue_submit_functions.push_back(function);
8110+ } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8111+ VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
8112+ std::function<bool()> function = [=]() {
8113+ SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), false);
8114+ return false;
8115+ };
8116+ cb_node->queue_submit_functions.push_back(function);
8117+ } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8118+ VK_ATTACHMENT_LOAD_OP_LOAD)) {
8119+ std::function<bool()> function = [=]() {
8120+ return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image), "vkCmdBeginRenderPass()");
8121+ };
8122+ cb_node->queue_submit_functions.push_back(function);
8123+ }
8124+ if (render_pass_state->attachment_first_read[i]) {
8125+ std::function<bool()> function = [=]() {
8126+ return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image), "vkCmdBeginRenderPass()");
8127+ };
8128+ cb_node->queue_submit_functions.push_back(function);
8129+ }
8130+ }
8131+ cb_node->activeRenderPass = render_pass_state;
8132+ // This is a shallow copy as that is all that is needed for now
8133+ cb_node->activeRenderPassBeginInfo = *pRenderPassBegin;
8134+ cb_node->activeSubpass = 0;
8135+ cb_node->activeSubpassContents = contents;
8136+ cb_node->framebuffers.insert(pRenderPassBegin->framebuffer);
8137+ // Connect this framebuffer and its children to this cmdBuffer
8138+ AddFramebufferBinding(dev_data, cb_node, framebuffer);
8139+ // transition attachments to the correct layouts for beginning of renderPass and first subpass
8140+ TransitionBeginRenderPassLayouts(dev_data, cb_node, render_pass_state, framebuffer);
8141+ lock.unlock();
81358142 dev_data->dispatch_table.CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
81368143 }
81378144}
0 commit comments