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

Commit 97fadcf

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 61e2b05 commit 97fadcf

1 file changed

Lines changed: 96 additions & 89 deletions

File tree

layers/core_validation.cpp

Lines changed: 96 additions & 89 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) {
@@ -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

Comments
 (0)