From ae80a25e48e78ef39e439c9399fed27614d6bba4 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 17 May 2016 11:36:23 +1200 Subject: layers: Add getRenderPass helper Various similar functions exist, but this one was missing. Returns the RENDER_PASS_NODE ptr if it exists, or nullptr otherwise. Signed-off-by: Chris Forbes --- layers/core_validation.cpp | 161 +++++++++++++++++++++++---------------------- 1 file changed, 81 insertions(+), 80 deletions(-) (limited to 'layers/core_validation.cpp') 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 &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> output_attachment_to_subpass(pCreateInfo->attachmentCount); std::vector> input_attachment_to_subpass(pCreateInfo->attachmentCount); std::vector> 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 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 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 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 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 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 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 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 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 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; } -- cgit v1.2.3