From c778652b7fd834aeee7ca046d1a8d1e1d0a9f5e4 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 31 Jul 2020 19:47:37 -0700 Subject: PipelineStateVkImpl: creating implicit IRenderPass object instead of Vulkan render pass --- .../include/PipelineStateVkImpl.hpp | 19 ++- .../include/RenderDeviceVkImpl.hpp | 9 +- .../include/RenderPassCache.hpp | 13 +- .../include/RenderPassVkImpl.hpp | 3 +- .../interface/PipelineStateVk.h | 9 +- .../src/DeviceContextVkImpl.cpp | 7 +- .../src/PipelineStateVkImpl.cpp | 143 ++++++++++----------- .../src/RenderDeviceVkImpl.cpp | 23 ++-- .../GraphicsEngineVulkan/src/RenderPassCache.cpp | 32 +++-- .../GraphicsEngineVulkan/src/RenderPassVkImpl.cpp | 5 +- 10 files changed, 140 insertions(+), 123 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index aca69cac..b8d5b0ec 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -68,8 +68,8 @@ public: /// Implementation of IPipelineState::IsCompatibleWith() in Vulkan backend. virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineState* pPSO) const override final; - /// Implementation of IPipelineStateVk::GetVkRenderPass(). - virtual VkRenderPass DILIGENT_CALL_TYPE GetVkRenderPass() const override final { return m_RenderPass; } + /// Implementation of IPipelineStateVk::GetRenderPass(). + virtual IRenderPassVk* DILIGENT_CALL_TYPE GetRenderPass() const override final { return m_pRenderPass.RawPtr(); } /// Implementation of IPipelineStateVk::GetVkPipeline(). virtual VkPipeline DILIGENT_CALL_TYPE GetVkPipeline() const override final { return m_Pipeline; } @@ -113,13 +113,13 @@ public: return m_SRBMemAllocator; } - static VkRenderPassCreateInfo GetRenderPassCreateInfo(Uint32 NumRenderTargets, - const TEXTURE_FORMAT RTVFormats[], - TEXTURE_FORMAT DSVFormat, - Uint32 SampleCount, - std::array& Attachments, - std::array& AttachmentReferences, - VkSubpassDescription& SubpassDesc); + static RenderPassDesc GetImplicitRenderPassDesc(Uint32 NumRenderTargets, + const TEXTURE_FORMAT RTVFormats[], + TEXTURE_FORMAT DSVFormat, + Uint8 SampleCount, + std::array& Attachments, + std::array& AttachmentReferences, + SubpassDesc& SubpassDesc); void InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache) const; @@ -152,7 +152,6 @@ private: std::array m_ShaderModules; - VkRenderPass m_RenderPass = VK_NULL_HANDLE; // Render passes are managed by the render device VulkanUtilities::PipelineWrapper m_Pipeline; PipelineLayout m_PipelineLayout; diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 6ec79aad..38bd4893 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -102,6 +102,11 @@ public: virtual void DILIGENT_CALL_TYPE CreateRenderPass(const RenderPassDesc& Desc, IRenderPass** ppRenderPass) override final; + void CreateRenderPass(const RenderPassDesc& Desc, + IRenderPass** ppRenderPass, + bool IsDeviceInternal); + + /// Implementation of IRenderDevice::CreateFramebuffer() in Vulkan backend. virtual void DILIGENT_CALL_TYPE CreateFramebuffer(const FramebufferDesc& Desc, IFramebuffer** ppFramebuffer) override final; @@ -152,7 +157,7 @@ public: const VulkanUtilities::VulkanLogicalDevice& GetLogicalDevice() { return *m_LogicalVkDevice; } FramebufferCache& GetFramebufferCache() { return m_FramebufferCache; } - RenderPassCache& GetRenderPassCache() { return m_RenderPassCache; } + RenderPassCache& GetImplicitRenderPassCache() { return m_ImplicitRenderPassCache; } VulkanUtilities::VulkanMemoryAllocation AllocateMemory(const VkMemoryRequirements& MemReqs, VkMemoryPropertyFlags MemoryProperties) { @@ -181,7 +186,7 @@ private: EngineVkCreateInfo m_EngineAttribs; FramebufferCache m_FramebufferCache; - RenderPassCache m_RenderPassCache; + RenderPassCache m_ImplicitRenderPassCache; DescriptorSetAllocator m_DescriptorSetAllocator; DescriptorPoolManager m_DynamicDescriptorPool; diff --git a/Graphics/GraphicsEngineVulkan/include/RenderPassCache.hpp b/Graphics/GraphicsEngineVulkan/include/RenderPassCache.hpp index bfab6c53..d2def841 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderPassCache.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderPassCache.hpp @@ -36,17 +36,18 @@ #include "Constants.h" #include "HashUtils.hpp" #include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "RefCntAutoPtr.hpp" namespace Diligent { class RenderDeviceVkImpl; +class RenderPassVkImpl; + class RenderPassCache { public: - RenderPassCache(RenderDeviceVkImpl& DeviceVk) noexcept : - m_DeviceVkImpl{DeviceVk} - {} + RenderPassCache(RenderDeviceVkImpl& DeviceVk) noexcept; // clang-format off RenderPassCache (const RenderPassCache&) = delete; @@ -123,7 +124,7 @@ public: mutable size_t Hash = 0; }; - VkRenderPass GetRenderPass(const RenderPassCacheKey& Key); + RenderPassVkImpl* GetRenderPass(const RenderPassCacheKey& Key); private: struct RenderPassCacheKeyHash @@ -136,8 +137,8 @@ private: RenderDeviceVkImpl& m_DeviceVkImpl; - std::mutex m_Mutex; - std::unordered_map m_Cache; + std::mutex m_Mutex; + std::unordered_map, RenderPassCacheKeyHash> m_Cache; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp index 9cf34e08..5c77784f 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderPassVkImpl.hpp @@ -49,7 +49,8 @@ public: RenderPassVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDevice, - const RenderPassDesc& Desc); + const RenderPassDesc& Desc, + bool IsDeviceInternal); ~RenderPassVkImpl(); /// Implementation of ISamplerVk::GetVkRenderPass(). diff --git a/Graphics/GraphicsEngineVulkan/interface/PipelineStateVk.h b/Graphics/GraphicsEngineVulkan/interface/PipelineStateVk.h index 679b6e73..f3377f08 100644 --- a/Graphics/GraphicsEngineVulkan/interface/PipelineStateVk.h +++ b/Graphics/GraphicsEngineVulkan/interface/PipelineStateVk.h @@ -31,6 +31,7 @@ /// Definition of the Diligent::IPipeplineStateVk interface #include "../../GraphicsEngine/interface/PipelineState.h" +#include "RenderPassVk.h" DILIGENT_BEGIN_NAMESPACE(Diligent) @@ -48,8 +49,8 @@ static const INTERFACE_ID IID_PipelineStateVk = /// Exposes Vulkan-specific functionality of a pipeline state object. DILIGENT_BEGIN_INTERFACE(IPipelineStateVk, IPipelineState) { - /// Returns handle to a vulkan render pass object. - VIRTUAL VkRenderPass METHOD(GetVkRenderPass)(THIS) CONST PURE; + /// Returns the pointer to the internal render pass object. + VIRTUAL IRenderPassVk* METHOD(GetRenderPass)(THIS) CONST PURE; /// Returns handle to a vulkan pipeline pass object. VIRTUAL VkPipeline METHOD(GetVkPipeline)(THIS) CONST PURE; @@ -62,8 +63,8 @@ DILIGENT_END_INTERFACE // clang-format off -# define IPipelineStateVk_GetVkRenderPass(This) CALL_IFACE_METHOD(PipelineStateVk, GetVkRenderPass, This) -# define IPipelineStateVk_GetVkPipeline(This) CALL_IFACE_METHOD(PipelineStateVk, GetVkPipeline, This) +# define IPipelineStateVk_GetRenderPass(This) CALL_IFACE_METHOD(PipelineStateVk, GetRenderPass, This) +# define IPipelineStateVk_GetVkPipeline(This) CALL_IFACE_METHOD(PipelineStateVk, GetVkPipeline, This) // clang-format on diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index efa7e34b..7fef3833 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -32,6 +32,7 @@ #include "PipelineStateVkImpl.hpp" #include "TextureVkImpl.hpp" #include "BufferVkImpl.hpp" +#include "RenderPassVkImpl.hpp" #include "VulkanTypeConversions.hpp" #include "CommandListVkImpl.hpp" #include "FenceVkImpl.hpp" @@ -461,7 +462,7 @@ void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags) #endif #ifdef DILIGENT_DEVELOPMENT - if (m_pPipelineState->GetVkRenderPass() != m_RenderPass) + if (m_pPipelineState->GetRenderPass()->GetVkRenderPass() != m_RenderPass) { DvpLogRenderPass_PSOMismatch(); } @@ -1163,9 +1164,9 @@ void DeviceContextVkImpl::SetRenderTargets(Uint32 NumRen } auto& FBCache = m_pDevice->GetFramebufferCache(); - auto& RPCache = m_pDevice->GetRenderPassCache(); + auto& RPCache = m_pDevice->GetImplicitRenderPassCache(); - m_RenderPass = RPCache.GetRenderPass(RenderPassKey); + m_RenderPass = RPCache.GetRenderPass(RenderPassKey)->GetVkRenderPass(); FBKey.Pass = m_RenderPass; FBKey.CommandQueueMask = ~Uint64{0}; m_Framebuffer = FBCache.GetFramebuffer(FBKey, m_FramebufferWidth, m_FramebufferHeight, m_FramebufferSlices); diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 99b27d2c..4355b453 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -32,10 +32,12 @@ #include "VulkanTypeConversions.hpp" #include "RenderDeviceVkImpl.hpp" #include "DeviceContextVkImpl.hpp" +#include "RenderPassVkImpl.hpp" #include "ShaderResourceBindingVkImpl.hpp" #include "EngineMemory.h" #include "StringTools.hpp" + #if !DILIGENT_NO_HLSL # include "spirv-tools/optimizer.hpp" #endif @@ -43,97 +45,88 @@ namespace Diligent { -VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( - Uint32 NumRenderTargets, - const TEXTURE_FORMAT RTVFormats[], - TEXTURE_FORMAT DSVFormat, - Uint32 SampleCount, - std::array& Attachments, - std::array& AttachmentReferences, - VkSubpassDescription& SubpassDesc) +RenderPassDesc PipelineStateVkImpl::GetImplicitRenderPassDesc( + Uint32 NumRenderTargets, + const TEXTURE_FORMAT RTVFormats[], + TEXTURE_FORMAT DSVFormat, + Uint8 SampleCount, + std::array& Attachments, + std::array& AttachmentReferences, + SubpassDesc& SubpassDesc) { VERIFY_EXPR(NumRenderTargets <= MAX_RENDER_TARGETS); - // Prepare render pass create info (7.1) - VkRenderPassCreateInfo RenderPassCI = {}; + RenderPassDesc RPDesc; - RenderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - RenderPassCI.pNext = nullptr; - RenderPassCI.flags = 0; // reserved for future use - RenderPassCI.attachmentCount = (DSVFormat != TEX_FORMAT_UNKNOWN ? 1 : 0) + NumRenderTargets; + RPDesc.AttachmentCount = (DSVFormat != TEX_FORMAT_UNKNOWN ? 1 : 0) + NumRenderTargets; - uint32_t AttachmentInd = 0; - VkSampleCountFlagBits SampleCountFlags = static_cast(SampleCount); - VkAttachmentReference* pDepthAttachmentReference = nullptr; + uint32_t AttachmentInd = 0; + AttachmentReference* pDepthAttachmentReference = nullptr; if (DSVFormat != TEX_FORMAT_UNKNOWN) { auto& DepthAttachment = Attachments[AttachmentInd]; - DepthAttachment.flags = 0; // Allowed value VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT - DepthAttachment.format = TexFormatToVkFormat(DSVFormat); - DepthAttachment.samples = SampleCountFlags; - DepthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area - // will be preserved. For attachments with a depth/stencil format, - // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT. - DepthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // the contents generated during the render pass and within the render - // area are written to memory. For attachments with a depth/stencil format, - // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. - DepthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - DepthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - DepthAttachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - DepthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - pDepthAttachmentReference = &AttachmentReferences[AttachmentInd]; - pDepthAttachmentReference->attachment = AttachmentInd; - pDepthAttachmentReference->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + DepthAttachment.Format = DSVFormat; + DepthAttachment.SampleCount = SampleCount; + DepthAttachment.LoadOp = ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area + // will be preserved. For attachments with a depth/stencil format, + // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT. + DepthAttachment.StoreOp = ATTACHMENT_STORE_OP_STORE; // the contents generated during the render pass and within the render + // area are written to memory. For attachments with a depth/stencil format, + // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. + DepthAttachment.StencilLoadOp = ATTACHMENT_LOAD_OP_LOAD; + DepthAttachment.StencilStoreOp = ATTACHMENT_STORE_OP_STORE; + DepthAttachment.InitialState = RESOURCE_STATE_DEPTH_WRITE; + DepthAttachment.FinalState = RESOURCE_STATE_DEPTH_WRITE; + + pDepthAttachmentReference = &AttachmentReferences[AttachmentInd]; + pDepthAttachmentReference->AttachmentIndex = AttachmentInd; + pDepthAttachmentReference->State = RESOURCE_STATE_DEPTH_WRITE; ++AttachmentInd; } - VkAttachmentReference* pColorAttachmentsReference = NumRenderTargets > 0 ? &AttachmentReferences[AttachmentInd] : nullptr; + AttachmentReference* pColorAttachmentsReference = NumRenderTargets > 0 ? &AttachmentReferences[AttachmentInd] : nullptr; for (Uint32 rt = 0; rt < NumRenderTargets; ++rt, ++AttachmentInd) { auto& ColorAttachment = Attachments[AttachmentInd]; - ColorAttachment.flags = 0; // Allowed value VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT - ColorAttachment.format = TexFormatToVkFormat(RTVFormats[rt]); - ColorAttachment.samples = SampleCountFlags; - ColorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area - // will be preserved. For attachments with a depth/stencil format, - // this uses the access type VK_ACCESS_COLOR_ATTACHMENT_READ_BIT. - ColorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // the contents generated during the render pass and within the render - // area are written to memory. For attachments with a color format, - // this uses the access type VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT. - ColorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - ColorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - ColorAttachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - ColorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - auto& ColorAttachmentRef = AttachmentReferences[AttachmentInd]; - ColorAttachmentRef.attachment = AttachmentInd; - ColorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + ColorAttachment.Format = RTVFormats[rt]; + ColorAttachment.SampleCount = SampleCount; + ColorAttachment.LoadOp = ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area + // will be preserved. For attachments with a depth/stencil format, + // this uses the access type VK_ACCESS_COLOR_ATTACHMENT_READ_BIT. + ColorAttachment.StoreOp = ATTACHMENT_STORE_OP_STORE; // the contents generated during the render pass and within the render + // area are written to memory. For attachments with a color format, + // this uses the access type VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT. + ColorAttachment.StencilLoadOp = ATTACHMENT_LOAD_OP_DONT_CARE; + ColorAttachment.StencilStoreOp = ATTACHMENT_STORE_OP_DONT_CARE; + ColorAttachment.InitialState = RESOURCE_STATE_RENDER_TARGET; + ColorAttachment.FinalState = RESOURCE_STATE_RENDER_TARGET; + + auto& ColorAttachmentRef = AttachmentReferences[AttachmentInd]; + ColorAttachmentRef.AttachmentIndex = AttachmentInd; + ColorAttachmentRef.State = RESOURCE_STATE_RENDER_TARGET; } - RenderPassCI.pAttachments = Attachments.data(); - RenderPassCI.subpassCount = 1; - RenderPassCI.pSubpasses = &SubpassDesc; - RenderPassCI.dependencyCount = 0; // the number of dependencies between pairs of subpasses, or zero indicating no dependencies. - RenderPassCI.pDependencies = nullptr; // an array of dependencyCount number of VkSubpassDependency structures describing - // dependencies between pairs of subpasses, or NULL if dependencyCount is zero. - - - SubpassDesc.flags = 0; // All bits for this type are defined by extensions - SubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; // Currently, only graphics subpasses are supported. - SubpassDesc.inputAttachmentCount = 0; - SubpassDesc.pInputAttachments = nullptr; - SubpassDesc.colorAttachmentCount = NumRenderTargets; - SubpassDesc.pColorAttachments = pColorAttachmentsReference; - SubpassDesc.pResolveAttachments = nullptr; - SubpassDesc.pDepthStencilAttachment = pDepthAttachmentReference; - SubpassDesc.preserveAttachmentCount = 0; - SubpassDesc.pPreserveAttachments = nullptr; - - return RenderPassCI; + RPDesc.pAttachments = Attachments.data(); + RPDesc.SubpassCount = 1; + RPDesc.pSubpasses = &SubpassDesc; + RPDesc.DependencyCount = 0; // the number of dependencies between pairs of subpasses, or zero indicating no dependencies. + RPDesc.pDependencies = nullptr; // an array of dependencyCount number of VkSubpassDependency structures describing + // dependencies between pairs of subpasses, or NULL if dependencyCount is zero. + + + SubpassDesc.InputAttachmentCount = 0; + SubpassDesc.pInputAttachments = nullptr; + SubpassDesc.RenderTargetAttachmentCount = NumRenderTargets; + SubpassDesc.pRenderTargetAttachments = pColorAttachmentsReference; + SubpassDesc.pResolveAttachments = nullptr; + SubpassDesc.pDepthStencilAttachment = pDepthAttachmentReference; + SubpassDesc.PreserveAttachmentCount = 0; + SubpassDesc.pPreserveAttachments = nullptr; + + return RPDesc; } static std::vector StripReflection(const std::vector& OriginalSPIRV) @@ -295,14 +288,14 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun { const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); auto& GraphicsPipeline = m_Desc.GraphicsPipeline; - auto& RPCache = pDeviceVk->GetRenderPassCache(); + auto& RPCache = pDeviceVk->GetImplicitRenderPassCache(); RenderPassCache::RenderPassCacheKey Key{ GraphicsPipeline.NumRenderTargets, GraphicsPipeline.SmplDesc.Count, GraphicsPipeline.RTVFormats, GraphicsPipeline.DSVFormat}; - m_RenderPass = RPCache.GetRenderPass(Key); + m_pRenderPass = RPCache.GetRenderPass(Key); VkGraphicsPipelineCreateInfo PipelineCI = {}; @@ -442,7 +435,7 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun PipelineCI.pDynamicState = &DynamicStateCI; - PipelineCI.renderPass = m_RenderPass; + PipelineCI.renderPass = GetRenderPass()->GetVkRenderPass(); PipelineCI.subpass = 0; PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from PipelineCI.basePipelineIndex = 0; // an index into the pCreateInfos parameter to use as a pipeline to derive from diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index d5f38ade..3b8e569a 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -78,12 +78,12 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters* sizeof(FramebufferVkImpl) } }, - m_VulkanInstance {Instance }, - m_PhysicalDevice {std::move(PhysicalDevice)}, - m_LogicalVkDevice {std::move(LogicalDevice) }, - m_EngineAttribs {EngineCI }, - m_FramebufferCache {*this }, - m_RenderPassCache {*this }, + m_VulkanInstance {Instance }, + m_PhysicalDevice {std::move(PhysicalDevice)}, + m_LogicalVkDevice {std::move(LogicalDevice) }, + m_EngineAttribs {EngineCI }, + m_FramebufferCache {*this }, + m_ImplicitRenderPassCache{*this }, m_DescriptorSetAllocator { *this, @@ -622,19 +622,26 @@ void RenderDeviceVkImpl::CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) ); } -void RenderDeviceVkImpl::CreateRenderPass(const RenderPassDesc& Desc, IRenderPass** ppRenderPass) +void RenderDeviceVkImpl::CreateRenderPass(const RenderPassDesc& Desc, + IRenderPass** ppRenderPass, + bool IsDeviceInternal) { CreateDeviceObject( "RenderPass", Desc, ppRenderPass, [&]() // { - RenderPassVkImpl* pRenderPassVk(NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassVkImpl instance", RenderPassVkImpl)(this, Desc)); + RenderPassVkImpl* pRenderPassVk(NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassVkImpl instance", RenderPassVkImpl)(this, Desc, IsDeviceInternal)); pRenderPassVk->QueryInterface(IID_RenderPass, reinterpret_cast(ppRenderPass)); OnCreateDeviceObject(pRenderPassVk); } // ); } +void RenderDeviceVkImpl::CreateRenderPass(const RenderPassDesc& Desc, IRenderPass** ppRenderPass) +{ + CreateRenderPass(Desc, ppRenderPass, /*IsDeviceInternal = */ false); +} + void RenderDeviceVkImpl::CreateFramebuffer(const FramebufferDesc& Desc, IFramebuffer** ppFramebuffer) { CreateDeviceObject("Framebuffer", Desc, ppFramebuffer, diff --git a/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp b/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp index c352c2a9..29b817ce 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp @@ -30,36 +30,42 @@ #include "RenderPassCache.hpp" #include "RenderDeviceVkImpl.hpp" #include "PipelineStateVkImpl.hpp" +#include "RenderPassVkImpl.hpp" namespace Diligent { +RenderPassCache::RenderPassCache(RenderDeviceVkImpl& DeviceVk) noexcept : + m_DeviceVkImpl{DeviceVk} +{} + + RenderPassCache::~RenderPassCache() { auto& FBCache = m_DeviceVkImpl.GetFramebufferCache(); for (auto it = m_Cache.begin(); it != m_Cache.end(); ++it) { - FBCache.OnDestroyRenderPass(it->second); + FBCache.OnDestroyRenderPass(it->second->GetVkRenderPass()); } } -VkRenderPass RenderPassCache::GetRenderPass(const RenderPassCacheKey& Key) +RenderPassVkImpl* RenderPassCache::GetRenderPass(const RenderPassCacheKey& Key) { std::lock_guard Lock{m_Mutex}; auto it = m_Cache.find(Key); if (it == m_Cache.end()) { // Do not zero-intitialize arrays - std::array Attachments; - std::array AttachmentReferences; + std::array Attachments; + std::array AttachmentReferences; - VkSubpassDescription Subpass; + SubpassDesc Subpass; - auto RenderPassCI = - PipelineStateVkImpl::GetRenderPassCreateInfo(Key.NumRenderTargets, Key.RTVFormats, Key.DSVFormat, - Key.SampleCount, Attachments, AttachmentReferences, Subpass); + auto RPDesc = + PipelineStateVkImpl::GetImplicitRenderPassDesc(Key.NumRenderTargets, Key.RTVFormats, Key.DSVFormat, + Key.SampleCount, Attachments, AttachmentReferences, Subpass); std::stringstream PassNameSS; - PassNameSS << "Render pass: RT count: " << Uint32{Key.NumRenderTargets} << "; sample count: " << Uint32{Key.SampleCount} + PassNameSS << "Implicit render pass: RT count: " << Uint32{Key.NumRenderTargets} << "; sample count: " << Uint32{Key.SampleCount} << "; DSV Format: " << GetTextureFormatAttribs(Key.DSVFormat).Name; if (Key.NumRenderTargets > 0) { @@ -69,9 +75,11 @@ VkRenderPass RenderPassCache::GetRenderPass(const RenderPassCacheKey& Key) PassNameSS << (rt > 0 ? ", " : "") << GetTextureFormatAttribs(Key.RTVFormats[rt]).Name; } } - auto RenderPass = m_DeviceVkImpl.GetLogicalDevice().CreateRenderPass(RenderPassCI, PassNameSS.str().c_str()); - VERIFY_EXPR(RenderPass != VK_NULL_HANDLE); - it = m_Cache.emplace(Key, std::move(RenderPass)).first; + + RefCntAutoPtr pRenderPass; + m_DeviceVkImpl.CreateRenderPass(RPDesc, pRenderPass.GetRawDblPtr(), /* IsDeviceInternal = */ true); + VERIFY_EXPR(pRenderPass != nullptr); + it = m_Cache.emplace(Key, std::move(pRenderPass)).first; } return it->second; diff --git a/Graphics/GraphicsEngineVulkan/src/RenderPassVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderPassVkImpl.cpp index 67731739..37bdc106 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderPassVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderPassVkImpl.cpp @@ -36,8 +36,9 @@ namespace Diligent RenderPassVkImpl::RenderPassVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDevice, - const RenderPassDesc& Desc) : - TRenderPassBase{pRefCounters, pDevice, Desc} + const RenderPassDesc& Desc, + bool IsDeviceInternal) : + TRenderPassBase{pRefCounters, pDevice, Desc, IsDeviceInternal} { VkRenderPassCreateInfo RenderPassCI = {}; -- cgit v1.2.3