aboutsummaryrefslogtreecommitdiff
path: root/layers/core_validation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layers/core_validation.cpp')
-rw-r--r--layers/core_validation.cpp161
1 files changed, 81 insertions, 80 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 0715fda1..6a4e3576 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -1965,7 +1965,7 @@ static bool validate_status(layer_data *my_data, GLOBAL_CB_NODE *pNode, CBStatus
}
// Retrieve pipeline node ptr for given pipeline object
-static PIPELINE_NODE *getPipeline(layer_data const *my_data, const VkPipeline pipeline) {
+static PIPELINE_NODE *getPipeline(layer_data const *my_data, VkPipeline pipeline) {
auto it = my_data->pipelineMap.find(pipeline);
if (it == my_data->pipelineMap.end()) {
return nullptr;
@@ -1973,6 +1973,14 @@ static PIPELINE_NODE *getPipeline(layer_data const *my_data, const VkPipeline pi
return it->second;
}
+static RENDER_PASS_NODE *getRenderPass(layer_data const *my_data, VkRenderPass renderpass) {
+ auto it = my_data->renderPassMap.find(renderpass);
+ if (it == my_data->renderPassMap.end()) {
+ return nullptr;
+ }
+ return it->second;
+}
+
// Return true if for a given PSO, the given state enum is dynamic, else return false
static bool isDynamic(const PIPELINE_NODE *pPipeline, const VkDynamicState state) {
if (pPipeline && pPipeline->graphicsPipelineCI.pDynamicState) {
@@ -2057,12 +2065,17 @@ static bool attachment_references_compatible(const uint32_t index, const VkAttac
// For give primary and secondary RenderPass objects, verify that they're compatible
static bool verify_renderpass_compatibility(layer_data *my_data, const VkRenderPass primaryRP, const VkRenderPass secondaryRP,
string &errorMsg) {
- if (my_data->renderPassMap.find(primaryRP) == my_data->renderPassMap.end()) {
+ auto primary_render_pass = getRenderPass(my_data, primaryRP);
+ auto secondary_render_pass = getRenderPass(my_data, secondaryRP);
+
+ if (!primary_render_pass) {
stringstream errorStr;
errorStr << "invalid VkRenderPass (" << primaryRP << ")";
errorMsg = errorStr.str();
return false;
- } else if (my_data->renderPassMap.find(secondaryRP) == my_data->renderPassMap.end()) {
+ }
+
+ if (!secondary_render_pass) {
stringstream errorStr;
errorStr << "invalid VkRenderPass (" << secondaryRP << ")";
errorMsg = errorStr.str();
@@ -2072,8 +2085,8 @@ static bool verify_renderpass_compatibility(layer_data *my_data, const VkRenderP
if (primaryRP == secondaryRP) {
return true;
}
- const VkRenderPassCreateInfo *primaryRPCI = my_data->renderPassMap[primaryRP]->pCreateInfo;
- const VkRenderPassCreateInfo *secondaryRPCI = my_data->renderPassMap[secondaryRP]->pCreateInfo;
+ const VkRenderPassCreateInfo *primaryRPCI = primary_render_pass->pCreateInfo;
+ const VkRenderPassCreateInfo *secondaryRPCI = secondary_render_pass->pCreateInfo;
if (primaryRPCI->subpassCount != secondaryRPCI->subpassCount) {
stringstream errorStr;
errorStr << "RenderPass for primary cmdBuffer has " << primaryRPCI->subpassCount
@@ -2951,13 +2964,13 @@ static bool verifyPipelineCreateState(layer_data *my_data, const VkDevice device
// Ensure the subpass index is valid. If not, then validate_and_capture_pipeline_shader_state
// produces nonsense errors that confuse users. Other layers should already
// emit errors for renderpass being invalid.
- auto rp_data = my_data->renderPassMap.find(pPipeline->graphicsPipelineCI.renderPass);
- if (rp_data != my_data->renderPassMap.end() &&
- pPipeline->graphicsPipelineCI.subpass >= rp_data->second->pCreateInfo->subpassCount) {
+ auto renderPass = getRenderPass(my_data, pPipeline->graphicsPipelineCI.renderPass);
+ if (renderPass &&
+ pPipeline->graphicsPipelineCI.subpass >= renderPass->pCreateInfo->subpassCount) {
skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: Subpass index %u "
"is out of range for this renderpass (0..%u)",
- pPipeline->graphicsPipelineCI.subpass, rp_data->second->pCreateInfo->subpassCount - 1);
+ pPipeline->graphicsPipelineCI.subpass, renderPass->pCreateInfo->subpassCount - 1);
}
if (!validate_and_capture_pipeline_shader_state(my_data->report_data, pPipeline, &my_data->phys_dev_properties.features,
@@ -5672,11 +5685,7 @@ CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t
for (i = 0; i < count; i++) {
pPipeNode[i] = new PIPELINE_NODE;
pPipeNode[i]->initGraphicsPipeline(&pCreateInfos[i]);
-
- auto renderpass_it = dev_data->renderPassMap.find(pCreateInfos[i].renderPass);
- if (renderpass_it != dev_data->renderPassMap.end()) {
- pPipeNode[i]->renderPass = renderpass_it->second;
- }
+ pPipeNode[i]->renderPass = getRenderPass(dev_data, pCreateInfos[i].renderPass);
auto pipeline_layout_it = dev_data->pipelineLayoutMap.find(pCreateInfos[i].layout);
if (pipeline_layout_it != dev_data->pipelineLayoutMap.end()) {
@@ -6178,15 +6187,15 @@ BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo
}
}
if (pInfo && pInfo->renderPass != VK_NULL_HANDLE) {
- auto rp_data = dev_data->renderPassMap.find(pInfo->renderPass);
- if (rp_data != dev_data->renderPassMap.end() && rp_data->second && rp_data->second->pCreateInfo) {
- if (pInfo->subpass >= rp_data->second->pCreateInfo->subpassCount) {
+ auto renderPass = getRenderPass(dev_data, pInfo->renderPass);
+ if (renderPass) {
+ if (pInfo->subpass >= renderPass->pCreateInfo->subpassCount) {
skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, __LINE__,
DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
"vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) must has a subpass index (%d) "
"that is less than the number of subpasses (%d).",
- (void *)commandBuffer, pInfo->subpass, rp_data->second->pCreateInfo->subpassCount);
+ (void *)commandBuffer, pInfo->subpass, renderPass->pCreateInfo->subpassCount);
}
}
}
@@ -6220,8 +6229,7 @@ BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo
// If we are a secondary command-buffer and inheriting. Update the items we should inherit.
if ((pCB->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) &&
(pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
- auto inherited_render_pass_it = dev_data->renderPassMap.find(pCB->beginInfo.pInheritanceInfo->renderPass);
- pCB->activeRenderPass = inherited_render_pass_it != dev_data->renderPassMap.end() ? inherited_render_pass_it->second : nullptr;
+ pCB->activeRenderPass = getRenderPass(dev_data, pCB->beginInfo.pInheritanceInfo->renderPass);
pCB->activeSubpass = pCB->beginInfo.pInheritanceInfo->subpass;
pCB->framebuffers.insert(pCB->beginInfo.pInheritanceInfo->framebuffer);
}
@@ -8251,10 +8259,11 @@ bool isRegionOverlapping(VkImageSubresourceRange range1, VkImageSubresourceRange
}
static bool ValidateDependencies(const layer_data *my_data, const VkRenderPassBeginInfo *pRenderPassBegin,
- const std::vector<DAGNode> &subpass_to_node) {
+ RENDER_PASS_NODE const * renderPass) {
bool skip_call = false;
const VkFramebufferCreateInfo *pFramebufferInfo = &my_data->frameBufferMap.at(pRenderPassBegin->framebuffer).createInfo;
- const VkRenderPassCreateInfo *pCreateInfo = my_data->renderPassMap.at(pRenderPassBegin->renderPass)->pCreateInfo;
+ const VkRenderPassCreateInfo *pCreateInfo = renderPass->pCreateInfo;
+ auto const & subpass_to_node = renderPass->subpassToNode;
std::vector<std::vector<uint32_t>> output_attachment_to_subpass(pCreateInfo->attachmentCount);
std::vector<std::vector<uint32_t>> input_attachment_to_subpass(pCreateInfo->attachmentCount);
std::vector<std::vector<uint32_t>> overlapping_attachments(pCreateInfo->attachmentCount);
@@ -8771,17 +8780,16 @@ static void TransitionSubpassLayouts(VkCommandBuffer cmdBuffer, const VkRenderPa
const int subpass_index) {
layer_data *dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer);
- auto render_pass_data = dev_data->renderPassMap.find(pRenderPassBegin->renderPass);
- if (render_pass_data == dev_data->renderPassMap.end()) {
+ auto renderPass = getRenderPass(dev_data, pRenderPassBegin->renderPass);
+ if (!renderPass)
return;
- }
- const VkRenderPassCreateInfo *pRenderPassInfo = render_pass_data->second->pCreateInfo;
+
auto framebuffer_data = dev_data->frameBufferMap.find(pRenderPassBegin->framebuffer);
if (framebuffer_data == dev_data->frameBufferMap.end()) {
return;
}
const VkFramebufferCreateInfo framebufferInfo = framebuffer_data->second.createInfo;
- const VkSubpassDescription &subpass = pRenderPassInfo->pSubpasses[subpass_index];
+ const VkSubpassDescription &subpass = renderPass->pCreateInfo->pSubpasses[subpass_index];
for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
const VkImageView &image_view = framebufferInfo.pAttachments[subpass.pInputAttachments[j].attachment];
SetLayout(dev_data, pCB, image_view, subpass.pInputAttachments[j].layout);
@@ -8809,11 +8817,11 @@ static bool validatePrimaryCommandBuffer(const layer_data *my_data, const GLOBAL
static void TransitionFinalSubpassLayouts(VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo *pRenderPassBegin) {
layer_data *dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer);
- auto render_pass_data = dev_data->renderPassMap.find(pRenderPassBegin->renderPass);
- if (render_pass_data == dev_data->renderPassMap.end()) {
+ auto renderPass = getRenderPass(dev_data, pRenderPassBegin->renderPass);
+ if (!renderPass)
return;
- }
- const VkRenderPassCreateInfo *pRenderPassInfo = render_pass_data->second->pCreateInfo;
+
+ const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->pCreateInfo;
auto framebuffer_data = dev_data->frameBufferMap.find(pRenderPassBegin->framebuffer);
if (framebuffer_data == dev_data->frameBufferMap.end()) {
return;
@@ -8850,53 +8858,46 @@ CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *p
layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
std::unique_lock<std::mutex> lock(global_lock);
GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
+ auto renderPass = pRenderPassBegin ? getRenderPass(dev_data, pRenderPassBegin->renderPass) : nullptr;
if (pCB) {
- if (pRenderPassBegin && pRenderPassBegin->renderPass) {
+ if (renderPass) {
#if MTMERGE
- auto pass_data = dev_data->renderPassMap.find(pRenderPassBegin->renderPass);
- if (pass_data != dev_data->renderPassMap.end()) {
- RENDER_PASS_NODE* pRPNode = pass_data->second;
- pCB->activeFramebuffer = pRenderPassBegin->framebuffer;
- for (size_t i = 0; i < pRPNode->attachments.size(); ++i) {
- MT_FB_ATTACHMENT_INFO &fb_info = dev_data->frameBufferMap[pRenderPassBegin->framebuffer].attachments[i];
- if (pRPNode->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
- std::function<bool()> function = [=]() {
- set_memory_valid(dev_data, fb_info.mem, true, fb_info.image);
- return false;
- };
- pCB->validate_functions.push_back(function);
- } else if (pRPNode->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) {
- std::function<bool()> function = [=]() {
- set_memory_valid(dev_data, fb_info.mem, false, fb_info.image);
- return false;
- };
- pCB->validate_functions.push_back(function);
- } else if (pRPNode->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_LOAD) {
- std::function<bool()> function = [=]() {
- return validate_memory_is_valid(dev_data, fb_info.mem, "vkCmdBeginRenderPass()", fb_info.image);
- };
- pCB->validate_functions.push_back(function);
- }
- if (pRPNode->attachment_first_read[pRPNode->attachments[i].attachment]) {
- std::function<bool()> function = [=]() {
- return validate_memory_is_valid(dev_data, fb_info.mem, "vkCmdBeginRenderPass()", fb_info.image);
- };
- pCB->validate_functions.push_back(function);
- }
+ pCB->activeFramebuffer = pRenderPassBegin->framebuffer;
+ for (size_t i = 0; i < renderPass->attachments.size(); ++i) {
+ MT_FB_ATTACHMENT_INFO &fb_info = dev_data->frameBufferMap[pRenderPassBegin->framebuffer].attachments[i];
+ if (renderPass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+ std::function<bool()> function = [=]() {
+ set_memory_valid(dev_data, fb_info.mem, true, fb_info.image);
+ return false;
+ };
+ pCB->validate_functions.push_back(function);
+ } else if (renderPass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) {
+ std::function<bool()> function = [=]() {
+ set_memory_valid(dev_data, fb_info.mem, false, fb_info.image);
+ return false;
+ };
+ pCB->validate_functions.push_back(function);
+ } else if (renderPass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_LOAD) {
+ std::function<bool()> function = [=]() {
+ return validate_memory_is_valid(dev_data, fb_info.mem, "vkCmdBeginRenderPass()", fb_info.image);
+ };
+ pCB->validate_functions.push_back(function);
+ }
+ if (renderPass->attachment_first_read[renderPass->attachments[i].attachment]) {
+ std::function<bool()> function = [=]() {
+ return validate_memory_is_valid(dev_data, fb_info.mem, "vkCmdBeginRenderPass()", fb_info.image);
+ };
+ pCB->validate_functions.push_back(function);
}
}
#endif
skipCall |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin);
skipCall |= VerifyFramebufferAndRenderPassLayouts(commandBuffer, pRenderPassBegin);
skipCall |= insideRenderPass(dev_data, pCB, "vkCmdBeginRenderPass");
- auto render_pass_data = dev_data->renderPassMap.find(pRenderPassBegin->renderPass);
- if (render_pass_data != dev_data->renderPassMap.end()) {
- skipCall |= ValidateDependencies(dev_data, pRenderPassBegin, render_pass_data->second->subpassToNode);
- pCB->activeRenderPass = render_pass_data->second;
- }
- else {
- pCB->activeRenderPass = nullptr;
+ if (renderPass) {
+ skipCall |= ValidateDependencies(dev_data, pRenderPassBegin, renderPass);
}
+ pCB->activeRenderPass = renderPass;
skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdBeginRenderPass");
skipCall |= addCmd(dev_data, pCB, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()");
// This is a shallow copy as that is all that is needed for now
@@ -8908,8 +8909,8 @@ CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *p
dev_data->frameBufferMap[pRenderPassBegin->framebuffer].referencingCmdBuffers.insert(pCB->commandBuffer);
} else {
skipCall |=
- log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
- DRAWSTATE_INVALID_RENDERPASS, "DS", "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
+ log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+ DRAWSTATE_INVALID_RENDERPASS, "DS", "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
}
}
lock.unlock();
@@ -9089,9 +9090,9 @@ static bool validateRenderPassCompatibility(layer_data *dev_data, VkCommandBuffe
// Early exit if renderPass objects are identical (and therefore compatible)
if (primaryPass == secondaryPass)
return skip_call;
- auto primary_data = dev_data->renderPassMap.find(primaryPass);
- auto secondary_data = dev_data->renderPassMap.find(secondaryPass);
- if (primary_data == dev_data->renderPassMap.end() || primary_data->second == nullptr) {
+ auto primary_render_pass = getRenderPass(dev_data, primaryPass);
+ auto secondary_render_pass = getRenderPass(dev_data, secondaryPass);
+ if (!primary_render_pass) {
skip_call |=
log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
@@ -9099,7 +9100,7 @@ static bool validateRenderPassCompatibility(layer_data *dev_data, VkCommandBuffe
(void *)primaryBuffer, (uint64_t)(primaryPass));
return skip_call;
}
- if (secondary_data == dev_data->renderPassMap.end() || secondary_data->second == nullptr) {
+ if (!secondary_render_pass) {
skip_call |=
log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
@@ -9107,7 +9108,7 @@ static bool validateRenderPassCompatibility(layer_data *dev_data, VkCommandBuffe
(void *)secondaryBuffer, (uint64_t)(secondaryPass));
return skip_call;
}
- if (primary_data->second->pCreateInfo->subpassCount != secondary_data->second->pCreateInfo->subpassCount) {
+ if (primary_render_pass->pCreateInfo->subpassCount != secondary_render_pass->pCreateInfo->subpassCount) {
skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS",
"vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p which has a render pass 0x%" PRIx64
@@ -9116,10 +9117,10 @@ static bool validateRenderPassCompatibility(layer_data *dev_data, VkCommandBuffe
(void *)secondaryBuffer, (uint64_t)(secondaryPass), (uint64_t)(primaryPass));
return skip_call;
}
- bool is_multi = primary_data->second->pCreateInfo->subpassCount > 1;
- for (uint32_t i = 0; i < primary_data->second->pCreateInfo->subpassCount; ++i) {
- skip_call |=
- validateSubpassCompatibility(dev_data, primaryBuffer, primary_data->second, secondaryBuffer, secondary_data->second, i, is_multi);
+ auto subpassCount = primary_render_pass->pCreateInfo->subpassCount;
+ for (uint32_t i = 0; i < subpassCount; ++i) {
+ skip_call |= validateSubpassCompatibility(dev_data, primaryBuffer, primary_render_pass, secondaryBuffer,
+ secondary_render_pass, i, subpassCount > 1);
}
return skip_call;
}