Skip to content
This repository was archived by the owner on Jul 19, 2018. It is now read-only.

Commit 2cd6456

Browse files
committed
layers:Refactor CmdBeginRenderPass()
Only perform state updates for CmdBeginRenderPass() if we're not skipping the call to the driver. Also update validateSubpassCompatibility() to return early if skip is set to "true." That function will only return a single error code so in the event that we hit a skip case go ahead and just return early as we don't need to flag same code multiple times.
1 parent 3d7969f commit 2cd6456

1 file changed

Lines changed: 93 additions & 86 deletions

File tree

layers/core_validation.cpp

Lines changed: 93 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)