From ee7588230b461390cc627e878f5e4dba5e088a31 Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Mon, 13 Nov 2023 15:52:55 -0800 Subject: [PATCH] vk_renderpass_cache: Implement depth+stencil render pass resolve --- .../renderer_vulkan/vk_renderpass_cache.cpp | 195 ++++++++++++------ .../renderer_vulkan/vk_renderpass_cache.h | 8 +- 2 files changed, 141 insertions(+), 62 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp index f584dee1c..bf79adbdc 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp @@ -150,20 +150,20 @@ vk::RenderPass RenderpassCache::GetRenderpass(VideoCore::PixelFormat color, const vk::Format depth_format = instance.GetTraits(depth).native; const vk::AttachmentLoadOp load_op = is_clear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad; - renderpass = CreateRenderPass(color_format, depth_format, load_op, - static_cast(sample_count)); + + renderpass = (sample_count > 1) + ? CreateRenderPassMSAA(color_format, depth_format, load_op, + static_cast(sample_count)) + : CreateRenderPass(color_format, depth_format, load_op); } return *renderpass; } vk::UniqueRenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::Format depth, - vk::AttachmentLoadOp load_op, - vk::SampleCountFlagBits sample_count) const { - - boost::container::static_vector attachments{}; - boost::container::static_vector resolve_attachments{}; + vk::AttachmentLoadOp load_op) const { + boost::container::static_vector attachments{}; bool use_color = false; vk::AttachmentReference color_attachment_ref{}; bool use_depth = false; @@ -209,65 +209,12 @@ vk::UniqueRenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::For use_depth = true; } - // In the case of MSAA, each attachment gets an additional MSAA attachment that now becomes the - // main attachment and the original attachments now get resolved into - if (sample_count > vk::SampleCountFlagBits::e1) { - if (color != vk::Format::eUndefined) { - attachments.emplace_back(vk::AttachmentDescription{ - .format = color, - .samples = sample_count, - .loadOp = load_op, - .storeOp = vk::AttachmentStoreOp::eStore, - .stencilLoadOp = vk::AttachmentLoadOp::eDontCare, - .stencilStoreOp = vk::AttachmentStoreOp::eDontCare, - .initialLayout = vk::ImageLayout::eGeneral, - .finalLayout = vk::ImageLayout::eGeneral, - }); - - resolve_attachments.emplace_back(color_attachment_ref); - - color_attachment_ref = vk::AttachmentReference{ - .attachment = static_cast(attachments.size() - 1), - .layout = vk::ImageLayout::eGeneral, - }; - } - - if (depth != vk::Format::eUndefined) { - attachments.emplace_back(vk::AttachmentDescription{ - .format = depth, - .samples = sample_count, - .loadOp = load_op, - .storeOp = vk::AttachmentStoreOp::eStore, - .stencilLoadOp = load_op, - .stencilStoreOp = vk::AttachmentStoreOp::eStore, - .initialLayout = vk::ImageLayout::eGeneral, - .finalLayout = vk::ImageLayout::eGeneral, - }); - - resolve_attachments.emplace_back(depth_attachment_ref); - - depth_attachment_ref = vk::AttachmentReference{ - .attachment = static_cast(attachments.size() - 1), - .layout = vk::ImageLayout::eGeneral, - }; - } - } else { - if (color != vk::Format::eUndefined) { - resolve_attachments.emplace_back(vk::AttachmentReference{VK_ATTACHMENT_UNUSED}); - } - - if (depth != vk::Format::eUndefined) { - resolve_attachments.emplace_back(vk::AttachmentReference{VK_ATTACHMENT_UNUSED}); - } - } - const vk::SubpassDescription subpass = { .pipelineBindPoint = vk::PipelineBindPoint::eGraphics, .inputAttachmentCount = 0, .pInputAttachments = nullptr, .colorAttachmentCount = use_color ? 1u : 0u, .pColorAttachments = &color_attachment_ref, - .pResolveAttachments = resolve_attachments.data(), .pDepthStencilAttachment = use_depth ? &depth_attachment_ref : nullptr, }; @@ -283,4 +230,132 @@ vk::UniqueRenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::For return instance.GetDevice().createRenderPassUnique(renderpass_info); } +vk::UniqueRenderPass RenderpassCache::CreateRenderPassMSAA( + vk::Format color, vk::Format depth, vk::AttachmentLoadOp load_op, + vk::SampleCountFlagBits sample_count) const { + boost::container::static_vector attachments{}; + + vk::AttachmentReference2 color_resolve_attachment = {.attachment = VK_ATTACHMENT_UNUSED}; + vk::AttachmentReference2 depth_resolve_attachment = {.attachment = VK_ATTACHMENT_UNUSED}; + + bool use_color = false; + vk::AttachmentReference2 color_attachment_ref{}; + bool use_depth = false; + vk::AttachmentReference2 depth_attachment_ref{}; + + if (color != vk::Format::eUndefined) { + attachments.emplace_back(vk::AttachmentDescription2{ + .format = color, + .samples = vk::SampleCountFlagBits::e1, + .loadOp = load_op, + .storeOp = vk::AttachmentStoreOp::eStore, + .stencilLoadOp = vk::AttachmentLoadOp::eDontCare, + .stencilStoreOp = vk::AttachmentStoreOp::eDontCare, + .initialLayout = vk::ImageLayout::eGeneral, + .finalLayout = vk::ImageLayout::eGeneral, + }); + + color_attachment_ref = vk::AttachmentReference2{ + .attachment = static_cast(attachments.size() - 1), + .layout = vk::ImageLayout::eGeneral, + .aspectMask = vk::ImageAspectFlagBits::eColor, + }; + + use_color = true; + } + + if (depth != vk::Format::eUndefined) { + attachments.emplace_back(vk::AttachmentDescription2{ + .format = depth, + .samples = vk::SampleCountFlagBits::e1, + .loadOp = load_op, + .storeOp = vk::AttachmentStoreOp::eStore, + .stencilLoadOp = load_op, + .stencilStoreOp = vk::AttachmentStoreOp::eStore, + .initialLayout = vk::ImageLayout::eGeneral, + .finalLayout = vk::ImageLayout::eGeneral, + }); + + depth_attachment_ref = vk::AttachmentReference2{ + .attachment = static_cast(attachments.size() - 1), + .layout = vk::ImageLayout::eGeneral, + .aspectMask = vk::ImageAspectFlagBits::eDepth, + }; + + use_depth = true; + } + + // In the case of MSAA, each attachment gets an additional MSAA attachment that now becomes the + // main attachment and the original attachments now get resolved into + if (sample_count > vk::SampleCountFlagBits::e1) { + if (color != vk::Format::eUndefined) { + attachments.emplace_back(vk::AttachmentDescription2{ + .format = color, + .samples = sample_count, + .loadOp = load_op, + .storeOp = vk::AttachmentStoreOp::eStore, + .stencilLoadOp = vk::AttachmentLoadOp::eDontCare, + .stencilStoreOp = vk::AttachmentStoreOp::eDontCare, + .initialLayout = vk::ImageLayout::eGeneral, + .finalLayout = vk::ImageLayout::eGeneral, + }); + + color_resolve_attachment = color_attachment_ref; + + color_attachment_ref = vk::AttachmentReference2{ + .attachment = static_cast(attachments.size() - 1), + .layout = vk::ImageLayout::eGeneral, + }; + } + + if (depth != vk::Format::eUndefined) { + attachments.emplace_back(vk::AttachmentDescription2{ + .format = depth, + .samples = sample_count, + .loadOp = load_op, + .storeOp = vk::AttachmentStoreOp::eStore, + .stencilLoadOp = load_op, + .stencilStoreOp = vk::AttachmentStoreOp::eStore, + .initialLayout = vk::ImageLayout::eGeneral, + .finalLayout = vk::ImageLayout::eGeneral, + }); + + depth_resolve_attachment = depth_attachment_ref; + + depth_attachment_ref = vk::AttachmentReference2{ + .attachment = static_cast(attachments.size() - 1), + .layout = vk::ImageLayout::eGeneral, + }; + } + } + + const vk::StructureChain + subpass = { + vk::SubpassDescription2{ + .pipelineBindPoint = vk::PipelineBindPoint::eGraphics, + .inputAttachmentCount = 0, + .pInputAttachments = nullptr, + .colorAttachmentCount = use_color ? 1u : 0u, + .pColorAttachments = &color_attachment_ref, + .pResolveAttachments = &color_resolve_attachment, + .pDepthStencilAttachment = use_depth ? &depth_attachment_ref : nullptr, + }, + vk::SubpassDescriptionDepthStencilResolve{ + .depthResolveMode = vk::ResolveModeFlagBits::eSampleZero, + .stencilResolveMode = vk::ResolveModeFlagBits::eSampleZero, + .pDepthStencilResolveAttachment = &depth_resolve_attachment}, + }; + + const vk::RenderPassCreateInfo2 renderpass_info = { + .attachmentCount = static_cast(attachments.size()), + .pAttachments = attachments.data(), + .subpassCount = 1, + .pSubpasses = &subpass.get(), + .dependencyCount = 0, + .pDependencies = nullptr, + }; + + return instance.GetDevice().createRenderPass2Unique(renderpass_info); +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.h b/src/video_core/renderer_vulkan/vk_renderpass_cache.h index 8621c9f28..8816f9fa2 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.h +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.h @@ -61,8 +61,12 @@ public: private: /// Creates a renderpass configured appropriately and stores it in cached_renderpasses vk::UniqueRenderPass CreateRenderPass(vk::Format color, vk::Format depth, - vk::AttachmentLoadOp load_op, - vk::SampleCountFlagBits sample_count) const; + vk::AttachmentLoadOp load_op) const; + + /// Creates an MSAA renderpass configured appropriately and stores it in cached_renderpasses + vk::UniqueRenderPass CreateRenderPassMSAA(vk::Format color, vk::Format depth, + vk::AttachmentLoadOp load_op, + vk::SampleCountFlagBits sample_count) const; private: const Instance& instance;