From c3bc5cfc3b5f143842a463cfc5d8d0bead671be8 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 May 2021 18:20:04 +0200 Subject: [PATCH] vk oit: use a 2nd depth attachment for subpass 1 subpass 1 needs writable depth buffer (see 9f60c5e854b5650a750e4a224a1b9e2d0e13c84c) --- core/rend/vulkan/oit/oit_drawer.cpp | 32 +++++++++++++++---------- core/rend/vulkan/oit/oit_drawer.h | 5 ++-- core/rend/vulkan/oit/oit_renderpass.cpp | 9 ++++++- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/core/rend/vulkan/oit/oit_drawer.cpp b/core/rend/vulkan/oit/oit_drawer.cpp index 7d87f1477..015dd11d8 100644 --- a/core/rend/vulkan/oit/oit_drawer.cpp +++ b/core/rend/vulkan/oit/oit_drawer.cpp @@ -255,7 +255,8 @@ bool OITDrawer::Draw(const Texture *fogTexture, const Texture *paletteTexture) { needDepthTransition = false; // Not convinced that this is really needed but it makes validation layers happy - setImageLayout(cmdBuffer, depthAttachment->GetImage(), GetContext()->GetDepthFormat(), 1, vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilReadOnlyOptimal); + for (auto& attachment : depthAttachments) + setImageLayout(cmdBuffer, attachment->GetImage(), GetContext()->GetDepthFormat(), 1, vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilReadOnlyOptimal); } OITDescriptorSets::VertexShaderUniforms vtxUniforms; @@ -279,8 +280,8 @@ bool OITDrawer::Draw(const Texture *fogTexture, const Texture *paletteTexture) const vk::Buffer mainBuffer = GetMainBuffer(0)->buffer.get(); GetCurrentDescSet().UpdateUniforms(mainBuffer, offsets.vertexUniformOffset, offsets.fragmentUniformOffset, fogTexture->GetImageView(), offsets.polyParamsOffset, - offsets.polyParamsSize, depthAttachment->GetStencilView(), - depthAttachment->GetImageView(), paletteTexture->GetImageView()); + offsets.polyParamsSize, depthAttachments[0]->GetStencilView(), + depthAttachments[0]->GetImageView(), paletteTexture->GetImageView()); GetCurrentDescSet().BindPerFrameDescriptorSets(cmdBuffer); GetCurrentDescSet().UpdateColorInputDescSet(0, colorAttachments[0]->GetImageView()); GetCurrentDescSet().UpdateColorInputDescSet(1, colorAttachments[1]->GetImageView()); @@ -295,10 +296,11 @@ bool OITDrawer::Draw(const Texture *fogTexture, const Texture *paletteTexture) OITDescriptorSets::PushConstants pushConstants = { }; cmdBuffer.pushConstants(pipelineManager->GetPipelineLayout(), vk::ShaderStageFlagBits::eFragment, 0, pushConstants); - const std::array clear_colors = { + const std::array clear_colors = { vk::ClearColorValue(std::array{0.f, 0.f, 0.f, 1.f}), vk::ClearColorValue(std::array{0.f, 0.f, 0.f, 1.f}), vk::ClearDepthStencilValue{ 0.f, 0 }, + vk::ClearDepthStencilValue{ 0.f, 0 }, }; RenderPass previous_pass = {}; @@ -434,17 +436,21 @@ void OITDrawer::MakeBuffers(int width, int height) vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eInputAttachment); } - depthAttachment.reset(); - depthAttachment = std::unique_ptr( - new FramebufferAttachment(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice())); - depthAttachment->Init(maxWidth, maxHeight, GetContext()->GetDepthFormat(), - vk::ImageUsageFlagBits::eDepthStencilAttachment | vk::ImageUsageFlagBits::eInputAttachment); + for (auto& attachment : depthAttachments) + { + attachment.reset(); + attachment = std::unique_ptr( + new FramebufferAttachment(GetContext()->GetPhysicalDevice(), GetContext()->GetDevice())); + attachment->Init(maxWidth, maxHeight, GetContext()->GetDepthFormat(), + vk::ImageUsageFlagBits::eDepthStencilAttachment | vk::ImageUsageFlagBits::eInputAttachment); + } needDepthTransition = true; vk::ImageView attachments[] = { colorAttachments[1]->GetImageView(), colorAttachments[0]->GetImageView(), - depthAttachment->GetImageView(), + depthAttachments[0]->GetImageView(), + depthAttachments[1]->GetImageView(), }; vk::FramebufferCreateInfo createInfo(vk::FramebufferCreateFlags(), pipelineManager->GetRenderPass(true, true), ARRAY_SIZE(attachments), attachments, width, height, 1); @@ -474,7 +480,8 @@ void OITScreenDrawer::MakeFramebuffers(const vk::Extent2D& viewport) vk::ImageView attachments[] = { finalColorAttachments.back()->GetImageView(), colorAttachments[0]->GetImageView(), - depthAttachment->GetImageView(), + depthAttachments[0]->GetImageView(), + depthAttachments[1]->GetImageView(), }; vk::FramebufferCreateInfo createInfo(vk::FramebufferCreateFlags(), screenPipelineManager->GetRenderPass(true, true), ARRAY_SIZE(attachments), attachments, viewport.width, viewport.height, 1); @@ -599,7 +606,8 @@ vk::CommandBuffer OITTextureDrawer::NewFrame() vk::ImageView imageViews[] = { colorImageView, colorAttachments[0]->GetImageView(), - depthAttachment->GetImageView(), + depthAttachments[0]->GetImageView(), + depthAttachments[1]->GetImageView(), }; framebuffers.resize(GetContext()->GetSwapChainSize()); framebuffers[GetCurrentImage()] = device.createFramebufferUnique(vk::FramebufferCreateInfo(vk::FramebufferCreateFlags(), diff --git a/core/rend/vulkan/oit/oit_drawer.h b/core/rend/vulkan/oit/oit_drawer.h index 2308c245b..b34c13ec4 100644 --- a/core/rend/vulkan/oit/oit_drawer.h +++ b/core/rend/vulkan/oit/oit_drawer.h @@ -72,7 +72,8 @@ protected: colorAttachments[1].reset(); tempFramebuffers[0].reset(); tempFramebuffers[1].reset(); - depthAttachment.reset(); + depthAttachments[0].reset(); + depthAttachments[1].reset(); mainBuffers.clear(); descriptorSets.clear(); } @@ -116,7 +117,7 @@ protected: vk::Rect2D viewport; std::array, 2> colorAttachments; - std::unique_ptr depthAttachment; + std::array, 2> depthAttachments; vk::CommandBuffer currentCommandBuffer; std::vector clearNeeded; diff --git a/core/rend/vulkan/oit/oit_renderpass.cpp b/core/rend/vulkan/oit/oit_renderpass.cpp index 97a52cc85..cbc42d6e5 100644 --- a/core/rend/vulkan/oit/oit_renderpass.cpp +++ b/core/rend/vulkan/oit/oit_renderpass.cpp @@ -37,12 +37,19 @@ vk::UniqueRenderPass RenderPasses::MakeRenderPass(bool initial, bool last) last ? vk::AttachmentStoreOp::eDontCare : vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare, initial ? vk::ImageLayout::eUndefined : vk::ImageLayout::eDepthStencilReadOnlyOptimal, vk::ImageLayout::eDepthStencilReadOnlyOptimal), + // OP+PT depth attachment for subpass 1 + vk::AttachmentDescription(vk::AttachmentDescriptionFlags(), GetContext()->GetDepthFormat(), vk::SampleCountFlagBits::e1, + initial ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, + last ? vk::AttachmentStoreOp::eDontCare : vk::AttachmentStoreOp::eStore, + vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare, + initial ? vk::ImageLayout::eUndefined : vk::ImageLayout::eDepthStencilReadOnlyOptimal, vk::ImageLayout::eDepthStencilReadOnlyOptimal), }; vk::AttachmentReference swapChainReference(0, vk::ImageLayout::eColorAttachmentOptimal); vk::AttachmentReference colorReference(1, vk::ImageLayout::eColorAttachmentOptimal); vk::AttachmentReference depthReference(2, vk::ImageLayout::eDepthStencilAttachmentOptimal); vk::AttachmentReference depthReadOnlyRef(2, vk::ImageLayout::eDepthStencilReadOnlyOptimal); + vk::AttachmentReference depthReference2(3, vk::ImageLayout::eDepthStencilAttachmentOptimal); vk::AttachmentReference colorInput(1, vk::ImageLayout::eShaderReadOnlyOptimal); // vk 1.2 sdk wants this layout for subpass 2 vk::AttachmentReference depthRefStencilReadOnly(2, vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal); @@ -59,7 +66,7 @@ vk::UniqueRenderPass RenderPasses::MakeRenderPass(bool initial, bool last) 1, &depthReadOnlyRef, 1, &colorReference, nullptr, - &depthReadOnlyRef), + &depthReference2), // Final pass vk::SubpassDescription(vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, 1, &colorInput,