layers: Convert RENDER_PASS_NODE::pCreateInfo to use safe struct
authorChris Forbes <chrisforbes@google.com>
Mon, 26 Sep 2016 23:03:31 +0000 (12:03 +1300)
committerChris Forbes <chrisforbes@google.com>
Tue, 27 Sep 2016 01:26:51 +0000 (14:26 +1300)
Gets rid of a memory leak, and simplifies the code.

Signed-off-by: Chris Forbes <chrisforbes@google.com>
layers/core_validation.cpp
layers/core_validation_types.h

index 961ccd1..509d7d7 100644 (file)
@@ -136,7 +136,7 @@ struct layer_data {
     unordered_map<VkFramebuffer, unique_ptr<FRAMEBUFFER_NODE>> frameBufferMap;
     unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap;
     unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap;
-    unordered_map<VkRenderPass, RENDER_PASS_NODE *> renderPassMap;
+    unordered_map<VkRenderPass, unique_ptr<RENDER_PASS_NODE>> renderPassMap;
     unordered_map<VkShaderModule, unique_ptr<shader_module>> shaderModuleMap;
     VkDevice device;
 
@@ -2271,7 +2271,7 @@ static RENDER_PASS_NODE *getRenderPass(layer_data const *my_data, VkRenderPass r
     if (it == my_data->renderPassMap.end()) {
         return nullptr;
     }
-    return it->second;
+    return it->second.get();
 }
 
 static FRAMEBUFFER_NODE *getFramebuffer(const layer_data *my_data, VkFramebuffer framebuffer) {
@@ -3105,7 +3105,7 @@ static bool validatePipelineDrawtimeState(layer_data const *my_data,
         (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
         VkSampleCountFlagBits pso_num_samples = getNumSamples(pPipeline);
         if (pCB->activeRenderPass) {
-            const VkRenderPassCreateInfo *render_pass_info = pCB->activeRenderPass->pCreateInfo;
+            auto const render_pass_info = pCB->activeRenderPass->createInfo.ptr();
             const VkSubpassDescription *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
             uint32_t i;
 
@@ -3156,7 +3156,7 @@ static bool validatePipelineDrawtimeState(layer_data const *my_data,
     if (pCB->activeRenderPass) {
         std::string err_string;
         if ((pCB->activeRenderPass->renderPass != pPipeline->graphicsPipelineCI.renderPass) &&
-            !verify_renderpass_compatibility(my_data, pCB->activeRenderPass->pCreateInfo, pPipeline->render_pass_ci.ptr(),
+            !verify_renderpass_compatibility(my_data, pCB->activeRenderPass->createInfo.ptr(), pPipeline->render_pass_ci.ptr(),
                                              err_string)) {
             // renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with
             skip_call |=
@@ -3360,12 +3360,11 @@ static bool verifyPipelineCreateState(layer_data *my_data, const VkDevice device
     // produces nonsense errors that confuse users. Other layers should already
     // emit errors for renderpass being invalid.
     auto renderPass = getRenderPass(my_data, pPipeline->graphicsPipelineCI.renderPass);
-    if (renderPass &&
-        pPipeline->graphicsPipelineCI.subpass >= renderPass->pCreateInfo->subpassCount) {
+    if (renderPass && pPipeline->graphicsPipelineCI.subpass >= renderPass->createInfo.subpassCount) {
         skip_call |= 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, renderPass->pCreateInfo->subpassCount - 1);
+                             pPipeline->graphicsPipelineCI.subpass, renderPass->createInfo.subpassCount - 1);
     }
 
     if (!validate_and_capture_pipeline_shader_state(my_data->report_data, pPipeline, &my_data->phys_dev_properties.features,
@@ -3495,7 +3494,7 @@ static bool verifyPipelineCreateState(layer_data *my_data, const VkDevice device
 
         // If rasterization is not disabled, and subpass uses a depth/stencil
         // attachment, pDepthStencilState must be a pointer to a valid structure
-        auto subpass_desc = renderPass ? &renderPass->pCreateInfo->pSubpasses[pPipeline->graphicsPipelineCI.subpass] : nullptr;
+        auto subpass_desc = renderPass ? &renderPass->createInfo.pSubpasses[pPipeline->graphicsPipelineCI.subpass] : nullptr;
         if (subpass_desc && subpass_desc->pDepthStencilAttachment &&
             subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
             if (!pPipeline->graphicsPipelineCI.pDepthStencilState) {
@@ -4481,7 +4480,6 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDevice
 }
 
 // prototype
-static void deleteRenderPasses(layer_data *);
 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
     // TODOSC : Shouldn't need any customization here
     dispatch_key key = get_dispatch_key(device);
@@ -4489,7 +4487,7 @@ VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCall
     // Free all the memory
     std::unique_lock<std::mutex> lock(global_lock);
     deletePipelines(dev_data);
-    deleteRenderPasses(dev_data);
+    dev_data->renderPassMap.clear();
     deleteCommandBuffers(dev_data);
     // This will also delete all sets in the pool & remove them from setMap
     deletePools(dev_data);
@@ -6185,7 +6183,6 @@ DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCa
         invalidateCommandBuffers(rp_state->cb_bindings, obj_struct);
     }
     if (!skip) {
-        // TODO: leaking all the guts of the renderpass node here!
         dev_data->renderPassMap.erase(renderPass);
         lock.unlock();
         dev_data->device_dispatch_table->DestroyRenderPass(device, renderPass, pAllocator);
@@ -6417,7 +6414,7 @@ CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t
     for (i = 0; i < count; i++) {
         pPipeNode[i] = new PIPELINE_NODE;
         pPipeNode[i]->initGraphicsPipeline(&pCreateInfos[i]);
-        pPipeNode[i]->render_pass_ci.initialize(getRenderPass(dev_data, pCreateInfos[i].renderPass)->pCreateInfo);
+        pPipeNode[i]->render_pass_ci.initialize(getRenderPass(dev_data, pCreateInfos[i].renderPass)->createInfo.ptr());
         pPipeNode[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
 
         skip_call |= verifyPipelineCreateState(dev_data, device, pPipeNode, i);
@@ -6901,7 +6898,7 @@ BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo
                         if (framebuffer) {
                             if ((framebuffer->createInfo.renderPass != pInfo->renderPass) &&
                                 !verify_renderpass_compatibility(dev_data, framebuffer->renderPassCreateInfo.ptr(),
-                                                                 getRenderPass(dev_data, pInfo->renderPass)->pCreateInfo,
+                                                                 getRenderPass(dev_data, pInfo->renderPass)->createInfo.ptr(),
                                                                  errorString)) {
                                 // renderPass that framebuffer was created with must be compatible with local renderPass
                                 skip_call |= log_msg(
@@ -6935,13 +6932,13 @@ BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo
             if (pInfo && pInfo->renderPass != VK_NULL_HANDLE) {
                 auto renderPass = getRenderPass(dev_data, pInfo->renderPass);
                 if (renderPass) {
-                    if (pInfo->subpass >= renderPass->pCreateInfo->subpassCount) {
+                    if (pInfo->subpass >= renderPass->createInfo.subpassCount) {
                         skip_call |= 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, renderPass->pCreateInfo->subpassCount);
+                            (void *)commandBuffer, pInfo->subpass, renderPass->createInfo.subpassCount);
                     }
                 }
             }
@@ -8265,7 +8262,7 @@ VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, ui
 
     // Validate that attachment is in reference list of active subpass
     if (pCB->activeRenderPass) {
-        const VkRenderPassCreateInfo *pRPCI = pCB->activeRenderPass->pCreateInfo;
+        const VkRenderPassCreateInfo *pRPCI = pCB->activeRenderPass->createInfo.ptr();
         const VkSubpassDescription *pSD = &pRPCI->pSubpasses[pCB->activeSubpass];
 
         for (uint32_t attachment_idx = 0; attachment_idx < attachmentCount; attachment_idx++) {
@@ -9247,7 +9244,7 @@ static bool ValidateFramebufferCreateInfo(layer_data *dev_data, const VkFramebuf
 
     auto rp_node = getRenderPass(dev_data, pCreateInfo->renderPass);
     if (rp_node) {
-        const VkRenderPassCreateInfo *rpci = rp_node->pCreateInfo;
+        const VkRenderPassCreateInfo *rpci = rp_node->createInfo.ptr();
         if (rpci->attachmentCount != pCreateInfo->attachmentCount) {
             skip_call |= log_msg(
                 dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
@@ -9379,7 +9376,7 @@ static bool PreCallValidateCreateFramebuffer(layer_data *dev_data, const VkFrame
 static void PostCallRecordCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo, VkFramebuffer fb) {
     // Shadow create info and store in map
     std::unique_ptr<FRAMEBUFFER_NODE> fb_node(
-        new FRAMEBUFFER_NODE(fb, pCreateInfo, dev_data->renderPassMap[pCreateInfo->renderPass]->pCreateInfo));
+        new FRAMEBUFFER_NODE(fb, pCreateInfo, dev_data->renderPassMap[pCreateInfo->renderPass]->createInfo.ptr()));
 
     for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
         VkImageView view = pCreateInfo->pAttachments[i];
@@ -9514,8 +9511,8 @@ bool isRegionOverlapping(VkImageSubresourceRange range1, VkImageSubresourceRange
 static bool ValidateDependencies(const layer_data *my_data, FRAMEBUFFER_NODE const * framebuffer,
                                  RENDER_PASS_NODE const * renderPass) {
     bool skip_call = false;
-    const safe_VkFramebufferCreateInfo *pFramebufferInfo = &framebuffer->createInfo;
-    const VkRenderPassCreateInfo *pCreateInfo = renderPass->pCreateInfo;
+    auto const pFramebufferInfo = framebuffer->createInfo.ptr();
+    auto const pCreateInfo = renderPass->createInfo.ptr();
     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);
@@ -9977,55 +9974,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderP
         std::vector<DAGNode> subpass_to_node(pCreateInfo->subpassCount);
         skip_call |= CreatePassDAG(dev_data, device, pCreateInfo, subpass_to_node, has_self_dependency);
 
-        // Shadow create info and store in map
-        VkRenderPassCreateInfo *localRPCI = new VkRenderPassCreateInfo(*pCreateInfo);
-        if (pCreateInfo->pAttachments) {
-            localRPCI->pAttachments = new VkAttachmentDescription[localRPCI->attachmentCount];
-            memcpy((void *)localRPCI->pAttachments, pCreateInfo->pAttachments,
-                   localRPCI->attachmentCount * sizeof(VkAttachmentDescription));
-        }
-        if (pCreateInfo->pSubpasses) {
-            localRPCI->pSubpasses = new VkSubpassDescription[localRPCI->subpassCount];
-            memcpy((void *)localRPCI->pSubpasses, pCreateInfo->pSubpasses, localRPCI->subpassCount * sizeof(VkSubpassDescription));
-
-            for (uint32_t i = 0; i < localRPCI->subpassCount; i++) {
-                VkSubpassDescription *subpass = (VkSubpassDescription *)&localRPCI->pSubpasses[i];
-                const uint32_t attachmentCount = subpass->inputAttachmentCount +
-                                                 subpass->colorAttachmentCount * (1 + (subpass->pResolveAttachments ? 1 : 0)) +
-                                                 ((subpass->pDepthStencilAttachment) ? 1 : 0) + subpass->preserveAttachmentCount;
-                VkAttachmentReference *attachments = new VkAttachmentReference[attachmentCount];
-
-                memcpy(attachments, subpass->pInputAttachments, sizeof(attachments[0]) * subpass->inputAttachmentCount);
-                subpass->pInputAttachments = attachments;
-                attachments += subpass->inputAttachmentCount;
-
-                memcpy(attachments, subpass->pColorAttachments, sizeof(attachments[0]) * subpass->colorAttachmentCount);
-                subpass->pColorAttachments = attachments;
-                attachments += subpass->colorAttachmentCount;
-
-                if (subpass->pResolveAttachments) {
-                    memcpy(attachments, subpass->pResolveAttachments, sizeof(attachments[0]) * subpass->colorAttachmentCount);
-                    subpass->pResolveAttachments = attachments;
-                    attachments += subpass->colorAttachmentCount;
-                }
-
-                if (subpass->pDepthStencilAttachment) {
-                    memcpy(attachments, subpass->pDepthStencilAttachment, sizeof(attachments[0]) * 1);
-                    subpass->pDepthStencilAttachment = attachments;
-                    attachments += 1;
-                }
-
-                memcpy(attachments, subpass->pPreserveAttachments, sizeof(attachments[0]) * subpass->preserveAttachmentCount);
-                subpass->pPreserveAttachments = &attachments->attachment;
-            }
-        }
-        if (pCreateInfo->pDependencies) {
-            localRPCI->pDependencies = new VkSubpassDependency[localRPCI->dependencyCount];
-            memcpy((void *)localRPCI->pDependencies, pCreateInfo->pDependencies,
-                   localRPCI->dependencyCount * sizeof(VkSubpassDependency));
-        }
-
-        auto render_pass = new RENDER_PASS_NODE(localRPCI);
+        auto render_pass = unique_ptr<RENDER_PASS_NODE>(new RENDER_PASS_NODE(pCreateInfo));
         render_pass->renderPass = *pRenderPass;
         render_pass->hasSelfDependency = has_self_dependency;
         render_pass->subpassToNode = subpass_to_node;
@@ -10058,42 +10007,14 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderP
             }
         }
 
-        dev_data->renderPassMap[*pRenderPass] = render_pass;
+        dev_data->renderPassMap[*pRenderPass] = std::move(render_pass);
     }
     return result;
 }
 
-// Free the renderpass shadow
-static void deleteRenderPasses(layer_data *my_data) {
-    for (auto renderPass : my_data->renderPassMap) {
-        const VkRenderPassCreateInfo *pRenderPassInfo = renderPass.second->pCreateInfo;
-        delete[] pRenderPassInfo->pAttachments;
-        if (pRenderPassInfo->pSubpasses) {
-            for (uint32_t i = 0; i < pRenderPassInfo->subpassCount; ++i) {
-                // Attachements are all allocated in a block, so just need to
-                //  find the first non-null one to delete
-                if (pRenderPassInfo->pSubpasses[i].pInputAttachments) {
-                    delete[] pRenderPassInfo->pSubpasses[i].pInputAttachments;
-                } else if (pRenderPassInfo->pSubpasses[i].pColorAttachments) {
-                    delete[] pRenderPassInfo->pSubpasses[i].pColorAttachments;
-                } else if (pRenderPassInfo->pSubpasses[i].pResolveAttachments) {
-                    delete[] pRenderPassInfo->pSubpasses[i].pResolveAttachments;
-                } else if (pRenderPassInfo->pSubpasses[i].pPreserveAttachments) {
-                    delete[] pRenderPassInfo->pSubpasses[i].pPreserveAttachments;
-                }
-            }
-            delete[] pRenderPassInfo->pSubpasses;
-        }
-        delete[] pRenderPassInfo->pDependencies;
-        delete pRenderPassInfo;
-        delete renderPass.second;
-    }
-    my_data->renderPassMap.clear();
-}
-
 static bool VerifyFramebufferAndRenderPassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin) {
     bool skip_call = false;
-    const VkRenderPassCreateInfo *pRenderPassInfo = dev_data->renderPassMap[pRenderPassBegin->renderPass]->pCreateInfo;
+    auto const pRenderPassInfo = getRenderPass(dev_data, pRenderPassBegin->renderPass)->createInfo.ptr();
     auto const & framebufferInfo = dev_data->frameBufferMap[pRenderPassBegin->framebuffer]->createInfo;
     if (pRenderPassInfo->attachmentCount != framebufferInfo.attachmentCount) {
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
@@ -10157,7 +10078,7 @@ static void TransitionSubpassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB,
     if (!framebuffer)
         return;
 
-    const VkSubpassDescription &subpass = renderPass->pCreateInfo->pSubpasses[subpass_index];
+    auto const &subpass = renderPass->createInfo.pSubpasses[subpass_index];
     for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
         TransitionAttachmentRefLayout(dev_data, pCB, framebuffer, subpass.pInputAttachments[j]);
     }
@@ -10184,7 +10105,7 @@ static void TransitionFinalSubpassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *
     if (!renderPass)
         return;
 
-    const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->pCreateInfo;
+    const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->createInfo.ptr();
     auto framebuffer = getFramebuffer(dev_data, pRenderPassBegin->framebuffer);
     if (!framebuffer)
         return;
@@ -10240,9 +10161,9 @@ CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *p
         if (renderPass) {
             uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
             cb_node->activeFramebuffer = pRenderPassBegin->framebuffer;
-            for (size_t i = 0; i < renderPass->pCreateInfo->attachmentCount; ++i) {
+            for (size_t i = 0; i < renderPass->createInfo.attachmentCount; ++i) {
                 MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
-                auto pAttachment = &renderPass->pCreateInfo->pAttachments[i];
+                auto pAttachment = &renderPass->createInfo.pAttachments[i];
                 if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
                                                          pAttachment->stencilLoadOp,
                                                          VK_ATTACHMENT_LOAD_OP_CLEAR)) {
@@ -10328,7 +10249,7 @@ VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpa
         skip_call |= addCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()");
         skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass");
 
-        auto subpassCount = pCB->activeRenderPass->pCreateInfo->subpassCount;
+        auto subpassCount = pCB->activeRenderPass->createInfo.subpassCount;
         if (pCB->activeSubpass == subpassCount - 1) {
             skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
@@ -10360,16 +10281,16 @@ VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) {
         RENDER_PASS_NODE* pRPNode = pCB->activeRenderPass;
         auto framebuffer = getFramebuffer(dev_data, pCB->activeFramebuffer);
         if (pRPNode) {
-            if (pCB->activeSubpass != pRPNode->pCreateInfo->subpassCount - 1) {
+            if (pCB->activeSubpass != pRPNode->createInfo.subpassCount - 1) {
                 skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_INVALID_SUBPASS_INDEX, "DS",
                             "vkCmdEndRenderPass(): Called before reaching final subpass");
             }
 
-            for (size_t i = 0; i < pRPNode->pCreateInfo->attachmentCount; ++i) {
+            for (size_t i = 0; i < pRPNode->createInfo.attachmentCount; ++i) {
                 MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
-                auto pAttachment = &pRPNode->pCreateInfo->pAttachments[i];
+                auto pAttachment = &pRPNode->createInfo.pAttachments[i];
                 if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->storeOp,
                                                          pAttachment->stencilStoreOp, VK_ATTACHMENT_STORE_OP_STORE)) {
                     std::function<bool()> function = [=]() {
@@ -10563,7 +10484,7 @@ static bool validateFramebuffer(layer_data *dev_data, VkCommandBuffer primaryBuf
         auto cb_renderpass = getRenderPass(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass);
         if (cb_renderpass->renderPass != fb->createInfo.renderPass) {
             skip_call |= validateRenderPassCompatibility(dev_data, secondaryBuffer, fb->renderPassCreateInfo.ptr(), secondaryBuffer,
-                                                         cb_renderpass->pCreateInfo);
+                                                         cb_renderpass->createInfo.ptr());
         }
     }
     return skip_call;
@@ -10653,8 +10574,9 @@ CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
                 } else {
                     // Make sure render pass is compatible with parent command buffer pass if has continue
                     if (pCB->activeRenderPass->renderPass != secondary_rp_node->renderPass) {
-                        skip_call |= validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->pCreateInfo,
-                                                                    pCommandBuffers[i], secondary_rp_node->pCreateInfo);
+                        skip_call |=
+                            validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->createInfo.ptr(),
+                                                            pCommandBuffers[i], secondary_rp_node->createInfo.ptr());
                     }
                     //  If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB
                     skip_call |= validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB);
@@ -10662,8 +10584,8 @@ CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
                 string errorString = "";
                 // secondaryCB must have been created w/ RP compatible w/ primaryCB active renderpass
                 if ((pCB->activeRenderPass->renderPass != secondary_rp_node->renderPass) &&
-                    !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->pCreateInfo, secondary_rp_node->pCreateInfo,
-                                                     errorString)) {
+                    !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->createInfo.ptr(),
+                                                     secondary_rp_node->createInfo.ptr(), errorString)) {
                     skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)pCommandBuffers[i], __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
index 36e22ab..fcd81cc 100644 (file)
@@ -297,14 +297,14 @@ struct DAGNode {
 
 struct RENDER_PASS_NODE : public BASE_NODE {
     VkRenderPass renderPass;
-    VkRenderPassCreateInfo const *pCreateInfo;
+    safe_VkRenderPassCreateInfo createInfo;
     std::vector<bool> hasSelfDependency;
     std::vector<DAGNode> subpassToNode;
     std::unordered_map<uint32_t, bool> attachment_first_read;
     std::unordered_map<uint32_t, VkImageLayout> attachment_first_layout;
 
     RENDER_PASS_NODE(VkRenderPassCreateInfo const *pCreateInfo)
-        : pCreateInfo(pCreateInfo) {}
+        : createInfo(pCreateInfo) {}
 };
 
 // Cmd Buffer Tracking