@@ -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) {
@@ -8036,90 +8040,93 @@ VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, con
80368040 layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
80378041 unique_lock_t lock(global_lock);
80388042 GLOBAL_CB_NODE *cb_node = GetCBNode(dev_data, commandBuffer);
8039- auto render_pass_state = pRenderPassBegin ? GetRenderPassState(dev_data, pRenderPassBegin->renderPass) : nullptr;
8040- auto framebuffer = pRenderPassBegin ? GetFramebufferState(dev_data, pRenderPassBegin->framebuffer) : nullptr;
8041- if (cb_node) {
8042- if (render_pass_state) {
8043- uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
8044- cb_node->activeFramebuffer = pRenderPassBegin->framebuffer;
8045- for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) {
8046- MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
8047- auto pAttachment = &render_pass_state->createInfo.pAttachments[i];
8048- if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8049- VK_ATTACHMENT_LOAD_OP_CLEAR)) {
8050- clear_op_size = static_cast<uint32_t>(i) + 1;
8051- std::function<bool()> function = [=]() {
8052- SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), true);
8053- return false;
8054- };
8055- cb_node->queue_submit_functions.push_back(function);
8056- } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
8057- pAttachment->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
8058- std::function<bool()> function = [=]() {
8059- SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), false);
8060- return false;
8061- };
8062- cb_node->queue_submit_functions.push_back(function);
8063- } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
8064- pAttachment->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_LOAD)) {
8065- std::function<bool()> function = [=]() {
8066- return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image),
8067- "vkCmdBeginRenderPass()");
8068- };
8069- cb_node->queue_submit_functions.push_back(function);
8070- }
8071- if (render_pass_state->attachment_first_read[i]) {
8072- std::function<bool()> function = [=]() {
8073- return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image),
8074- "vkCmdBeginRenderPass()");
8075- };
8076- cb_node->queue_submit_functions.push_back(function);
8077- }
8078- }
8079- if (clear_op_size > pRenderPassBegin->clearValueCount) {
8080- skip |= log_msg(
8081- dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
8082- HandleToUint64(render_pass_state->renderPass), __LINE__, VALIDATION_ERROR_1200070c, "DS",
8083- "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there must "
8084- "be at least %u entries in pClearValues array to account for the highest index attachment in renderPass "
8085- "0x%" PRIx64
8086- " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array "
8087- "is indexed by attachment number so even if some pClearValues entries between 0 and %u correspond to "
8088- "attachments that aren't cleared they will be ignored. %s",
8089- pRenderPassBegin->clearValueCount, clear_op_size, HandleToUint64(render_pass_state->renderPass), clear_op_size,
8090- clear_op_size - 1, validation_error_map[VALIDATION_ERROR_1200070c]);
8091- }
8092- skip |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin);
8093- skip |= VerifyFramebufferAndRenderPassLayouts(dev_data, cb_node, pRenderPassBegin,
8094- GetFramebufferState(dev_data, pRenderPassBegin->framebuffer));
8095- if (framebuffer->rp_state->renderPass != render_pass_state->renderPass) {
8096- skip |= validateRenderPassCompatibility(dev_data, "render pass", render_pass_state, "framebuffer",
8097- framebuffer->rp_state.get(), "vkCmdBeginRenderPass()",
8098- VALIDATION_ERROR_12000710);
8099- }
8100- skip |= insideRenderPass(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00017);
8101- skip |= ValidateDependencies(dev_data, framebuffer, render_pass_state);
8102- skip |= validatePrimaryCommandBuffer(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00019);
8103- skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBeginRenderPass()", VK_QUEUE_GRAPHICS_BIT,
8104- VALIDATION_ERROR_17a02415);
8105- skip |= ValidateCmd(dev_data, cb_node, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()");
8106- cb_node->activeRenderPass = render_pass_state;
8107- // This is a shallow copy as that is all that is needed for now
8108- cb_node->activeRenderPassBeginInfo = *pRenderPassBegin;
8109- cb_node->activeSubpass = 0;
8110- cb_node->activeSubpassContents = contents;
8111- cb_node->framebuffers.insert(pRenderPassBegin->framebuffer);
8112- // Connect this framebuffer and its children to this cmdBuffer
8113- AddFramebufferBinding(dev_data, cb_node, framebuffer);
8114- // Connect this RP to cmdBuffer
8115- addCommandBufferBinding(&render_pass_state->cb_bindings,
8116- {HandleToUint64(render_pass_state->renderPass), kVulkanObjectTypeRenderPass}, cb_node);
8117- // transition attachments to the correct layouts for beginning of renderPass and first subpass
8118- TransitionBeginRenderPassLayouts(dev_data, cb_node, render_pass_state, framebuffer);
8119- }
8120- }
8121- lock.unlock();
8043+ assert(cb_node);
8044+ assert(pRenderPassBegin);
8045+ auto render_pass_state = GetRenderPassState(dev_data, pRenderPassBegin->renderPass);
8046+ auto framebuffer = GetFramebufferState(dev_data, pRenderPassBegin->framebuffer);
8047+ assert(render_pass_state);
8048+ assert(framebuffer);
8049+
8050+ uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
8051+ for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) {
8052+ auto pAttachment = &render_pass_state->createInfo.pAttachments[i];
8053+ if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8054+ VK_ATTACHMENT_LOAD_OP_CLEAR)) {
8055+ clear_op_size = static_cast<uint32_t>(i) + 1;
8056+ }
8057+ }
8058+ if (clear_op_size > pRenderPassBegin->clearValueCount) {
8059+ skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
8060+ HandleToUint64(render_pass_state->renderPass), __LINE__, VALIDATION_ERROR_1200070c, "DS",
8061+ "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there must "
8062+ "be at least %u entries in pClearValues array to account for the highest index attachment in renderPass "
8063+ "0x%" PRIx64
8064+ " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array "
8065+ "is indexed by attachment number so even if some pClearValues entries between 0 and %u correspond to "
8066+ "attachments that aren't cleared they will be ignored. %s",
8067+ pRenderPassBegin->clearValueCount, clear_op_size, HandleToUint64(render_pass_state->renderPass),
8068+ clear_op_size, clear_op_size - 1, validation_error_map[VALIDATION_ERROR_1200070c]);
8069+ }
8070+ skip |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin);
8071+ skip |= VerifyFramebufferAndRenderPassLayouts(dev_data, cb_node, pRenderPassBegin,
8072+ GetFramebufferState(dev_data, pRenderPassBegin->framebuffer));
8073+ if (framebuffer->rp_state->renderPass != render_pass_state->renderPass) {
8074+ skip |= validateRenderPassCompatibility(dev_data, "render pass", render_pass_state, "framebuffer",
8075+ framebuffer->rp_state.get(), "vkCmdBeginRenderPass()", VALIDATION_ERROR_12000710);
8076+ }
8077+ skip |= insideRenderPass(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00017);
8078+ skip |= ValidateDependencies(dev_data, framebuffer, render_pass_state);
8079+ skip |= validatePrimaryCommandBuffer(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00019);
8080+ skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBeginRenderPass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_17a02415);
8081+ skip |= ValidateCmd(dev_data, cb_node, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()");
81228082 if (!skip) {
8083+ // Perform state updates prior to call down chain
8084+ cb_node->activeFramebuffer = pRenderPassBegin->framebuffer;
8085+ for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) {
8086+ MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
8087+ auto pAttachment = &render_pass_state->createInfo.pAttachments[i];
8088+ if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8089+ VK_ATTACHMENT_LOAD_OP_CLEAR)) {
8090+ std::function<bool()> function = [=]() {
8091+ SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), true);
8092+ return false;
8093+ };
8094+ cb_node->queue_submit_functions.push_back(function);
8095+ } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8096+ VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
8097+ std::function<bool()> function = [=]() {
8098+ SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), false);
8099+ return false;
8100+ };
8101+ cb_node->queue_submit_functions.push_back(function);
8102+ } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp,
8103+ VK_ATTACHMENT_LOAD_OP_LOAD)) {
8104+ std::function<bool()> function = [=]() {
8105+ return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image), "vkCmdBeginRenderPass()");
8106+ };
8107+ cb_node->queue_submit_functions.push_back(function);
8108+ }
8109+ if (render_pass_state->attachment_first_read[i]) {
8110+ std::function<bool()> function = [=]() {
8111+ return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image), "vkCmdBeginRenderPass()");
8112+ };
8113+ cb_node->queue_submit_functions.push_back(function);
8114+ }
8115+ }
8116+ cb_node->activeRenderPass = render_pass_state;
8117+ // This is a shallow copy as that is all that is needed for now
8118+ cb_node->activeRenderPassBeginInfo = *pRenderPassBegin;
8119+ cb_node->activeSubpass = 0;
8120+ cb_node->activeSubpassContents = contents;
8121+ cb_node->framebuffers.insert(pRenderPassBegin->framebuffer);
8122+ // Connect this framebuffer and its children to this cmdBuffer
8123+ AddFramebufferBinding(dev_data, cb_node, framebuffer);
8124+ // Connect this RP to cmdBuffer
8125+ addCommandBufferBinding(&render_pass_state->cb_bindings,
8126+ {HandleToUint64(render_pass_state->renderPass), kVulkanObjectTypeRenderPass}, cb_node);
8127+ // transition attachments to the correct layouts for beginning of renderPass and first subpass
8128+ TransitionBeginRenderPassLayouts(dev_data, cb_node, render_pass_state, framebuffer);
8129+ lock.unlock();
81238130 dev_data->dispatch_table.CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
81248131 }
81258132}
0 commit comments