]> git.tdb.fi Git - libs/gl.git/blobdiff - source/backends/vulkan/pipelinecache.cpp
Discard render target contents only if the entire mip level is used
[libs/gl.git] / source / backends / vulkan / pipelinecache.cpp
index 3f8e55008223484036b3e5c4760ae5c5bd09d047..1568e6431c9716bff03569417548db7849130c86 100644 (file)
@@ -67,26 +67,28 @@ VkRenderPass PipelineCache::get_render_pass(const FrameFormat &format, bool clea
        unsigned color_count = 0;
        for(FrameAttachment a: format)
        {
+               VkImageLayout subpass_layout = static_cast<VkImageLayout>(get_vulkan_attachment_layout(get_components(get_attachment_pixelformat(a))));
+               VkImageLayout external_layout = (to_present ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR : subpass_layout);
+
                attachments[i].format = static_cast<VkFormat>(get_vulkan_pixelformat(get_attachment_pixelformat(a)));
                attachments[i].samples = vk_samples;
                attachments[i].loadOp = (clear ? discard ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD);
                attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
                attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
                attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
-               attachments[i].initialLayout = (clear ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-               attachments[i].finalLayout = (to_present ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+               attachments[i].initialLayout = ((clear && discard) ? VK_IMAGE_LAYOUT_UNDEFINED : external_layout);
+               attachments[i].finalLayout = external_layout;
 
-               unsigned attach_pt = get_attach_point(a);
-               if(attach_pt==get_attach_point(COLOR_ATTACHMENT))
+               if(subpass_layout==VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
                {
                        color_refs[color_count].attachment = i;
-                       color_refs[color_count].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+                       color_refs[color_count].layout = subpass_layout;
                        ++color_count;
                }
-               else if(attach_pt==get_attach_point(DEPTH_ATTACHMENT))
+               else
                {
                        depth_stencil_ref.attachment = i;
-                       depth_stencil_ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+                       depth_stencil_ref.layout = subpass_layout;
                }
 
                ++i;
@@ -98,6 +100,7 @@ VkRenderPass PipelineCache::get_render_pass(const FrameFormat &format, bool clea
        subpass.pColorAttachments = color_refs;
        subpass.pDepthStencilAttachment = &depth_stencil_ref;
 
+       VkSubpassDependency dependency = { };
        VkRenderPassCreateInfo render_pass_info = { };
        render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
        render_pass_info.attachmentCount = format.size();
@@ -105,6 +108,19 @@ VkRenderPass PipelineCache::get_render_pass(const FrameFormat &format, bool clea
        render_pass_info.subpassCount = 1;
        render_pass_info.pSubpasses = &subpass;
 
+       if(to_present)
+       {
+               dependency.srcSubpass = 0;
+               dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
+               dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+               dependency.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
+               dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+               dependency.dstAccessMask = 0;
+
+               render_pass_info.dependencyCount = 1;
+               render_pass_info.pDependencies = &dependency;
+       }
+
        VkRenderPass render_pass;
        vk.CreateRenderPass(render_pass_info, render_pass);