layers:Pipe state owns render pass ptr
authorTobin Ehlis <tobine@google.com>
Mon, 18 Sep 2017 14:38:37 +0000 (08:38 -0600)
committerTobin Ehlis <tobine@google.com>
Mon, 18 Sep 2017 19:36:52 +0000 (13:36 -0600)
Pipeline can outlive the renderPass that it's created with so add
shared_ptr to RENDER_PASS_STATE to PIPELINE_STATE to make sure
renderPass is available for the life of the pipeline.

layers/core_validation.cpp
layers/core_validation_types.h

index 61d8d55..124023d 100644 (file)
@@ -1095,11 +1095,10 @@ static bool ValidatePipelineDrawtimeState(layer_data const *dev_data, LAST_BOUND
                 break;
         }
         std::string err_string;
-        if (pCB->activeRenderPass->renderPass != pPipeline->graphicsPipelineCI.renderPass) {
+        if (pCB->activeRenderPass->renderPass != pPipeline->rp_state->renderPass) {
             // renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with
             skip |= validateRenderPassCompatibility(dev_data, "active render pass", pCB->activeRenderPass, "pipeline state object",
-                                                    GetRenderPassState(dev_data, pPipeline->graphicsPipelineCI.renderPass), caller,
-                                                    rp_error);
+                                                    pPipeline->rp_state.get(), caller, rp_error);
         }
         if (pPipeline->graphicsPipelineCI.subpass != pCB->activeSubpass) {
             skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
@@ -1317,7 +1316,7 @@ static bool ValidatePipelineUnlocked(layer_data *dev_data, std::vector<std::uniq
                 HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005d4, "DS",
                 "vkCreateGraphicsPipelines(): Render pass (0x%" PRIxLEAST64
                 ") subpass %u has colorAttachmentCount of %u which doesn't match the pColorBlendState->attachmentCount of %u. %s",
-                HandleToUint64(pPipeline->graphicsPipelineCI.renderPass), pPipeline->graphicsPipelineCI.subpass,
+                HandleToUint64(pPipeline->rp_state->renderPass), pPipeline->graphicsPipelineCI.subpass,
                 subpass_desc->colorAttachmentCount, color_blend_state->attachmentCount,
                 validation_error_map[VALIDATION_ERROR_096005d4]);
         }
@@ -4514,7 +4513,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipeli
 
     for (i = 0; i < count; i++) {
         pipe_state.push_back(std::unique_ptr<PIPELINE_STATE>(new PIPELINE_STATE));
-        pipe_state[i]->initGraphicsPipeline(&pCreateInfos[i]);
+        pipe_state[i]->initGraphicsPipeline(&pCreateInfos[i], GetRenderPassStateSharedPtr(dev_data, pCreateInfos[i].renderPass));
         pipe_state[i]->render_pass_ci.initialize(GetRenderPassState(dev_data, pCreateInfos[i].renderPass)->createInfo.ptr());
         pipe_state[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
     }
@@ -5201,7 +5200,7 @@ VKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipe
         addCommandBufferBinding(&pipe_state->cb_bindings, {HandleToUint64(pipeline), kVulkanObjectTypePipeline}, cb_state);
         if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
             // Add binding for child renderpass
-            auto rp_state = GetRenderPassState(dev_data, pipe_state->graphicsPipelineCI.renderPass);
+            auto rp_state = GetRenderPassState(dev_data, pipe_state->rp_state->renderPass);
             if (rp_state) {
                 addCommandBufferBinding(&rp_state->cb_bindings, {HandleToUint64(rp_state->renderPass), kVulkanObjectTypeRenderPass},
                                         cb_state);
index 928583c..8a6baa8 100644 (file)
@@ -547,6 +547,8 @@ class PIPELINE_STATE : public BASE_NODE {
    public:
     VkPipeline pipeline;
     safe_VkGraphicsPipelineCreateInfo graphicsPipelineCI;
+    // Hold shared ptr to RP in case RP itself is destroyed
+    std::shared_ptr<RENDER_PASS_STATE> rp_state;
     safe_VkComputePipelineCreateInfo computePipelineCI;
     // Flag of which shader stages are active for this pipeline
     uint32_t active_shaders;
@@ -565,6 +567,7 @@ class PIPELINE_STATE : public BASE_NODE {
     PIPELINE_STATE()
         : pipeline{},
           graphicsPipelineCI{},
+          rp_state(nullptr),
           computePipelineCI{},
           active_shaders(0),
           duplicate_shaders(0),
@@ -575,7 +578,7 @@ class PIPELINE_STATE : public BASE_NODE {
           render_pass_ci(),
           pipeline_layout() {}
 
-    void initGraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo) {
+    void initGraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo, std::shared_ptr<RENDER_PASS_STATE> &&rpstate) {
         graphicsPipelineCI.initialize(pCreateInfo);
         // Make sure compute pipeline is null
         VkComputePipelineCreateInfo emptyComputeCI = {};
@@ -599,6 +602,7 @@ class PIPELINE_STATE : public BASE_NODE {
                                                                                      pCBCI->pAttachments + pCBCI->attachmentCount);
             }
         }
+        rp_state = rpstate;
     }
 
     void initComputePipeline(const VkComputePipelineCreateInfo *pCreateInfo) {