diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-04-21 06:12:43 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-04-21 06:12:43 +0000 |
| commit | 67c24cfd4c5ef9ce9af1ea5a1943d4df9c9f0017 (patch) | |
| tree | 63778f49d56e0a92c1a4c9099a3779de946f4d5b /Graphics/GraphicsEngineVulkan | |
| parent | Renamed ClearRenderTargets to ResetRenderTargets (diff) | |
| download | DiligentCore-67c24cfd4c5ef9ce9af1ea5a1943d4df9c9f0017.tar.gz DiligentCore-67c24cfd4c5ef9ce9af1ea5a1943d4df9c9f0017.zip | |
Added Vulkan render pass and framebuffer commit
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
6 files changed, 101 insertions, 13 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 82b94413..9bc54e82 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -126,7 +126,7 @@ public: size_t GetNumCommandsInCtx()const { return m_State.NumCommands; } private: - void CommitRenderPassAndFramebuffer(); + void CommitRenderPassAndFramebuffer(class PipelineStateVkImpl *pPipelineStateVk); void CommitVkIndexBuffer(VALUE_TYPE IndexType); void CommitVkVertexBuffers(class GraphicsContext &GraphCtx); void TransitionVkVertexBuffers(class GraphicsContext &GraphCtx); diff --git a/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h index 78dee56e..681785a5 100644 --- a/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h @@ -53,7 +53,7 @@ public: void GenerateMips( IDeviceContext *pContext )override; - VkImageView GetVulkanImageView()const{return m_ImageView;} + VkImageView GetVulkanImageView()const override final{return m_ImageView;} protected: /// Vulkan image view descriptor handle diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h index 90341766..54bf8302 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h @@ -169,14 +169,27 @@ namespace VulkanUtilities ); m_State.RenderPass = RenderPass; m_State.Framebuffer = Framebuffer; + m_State.FramebufferWidth = FramebufferWidth; + m_State.FramebufferHeight = FramebufferHeight; } } void EndRenderPass() { + VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "Render pass has not been started"); + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkCmdEndRenderPass(m_VkCmdBuffer); m_State.RenderPass = VK_NULL_HANDLE; + // Do not set framebuffer to null. We will reuse cached framebuffer handle + // if the render pass is restarted without changing render targets + //m_State.Framebuffer = VK_NULL_HANDLE; + } + + void ResetFramebuffer() + { m_State.Framebuffer = VK_NULL_HANDLE; + m_State.FramebufferWidth = 0; + m_State.FramebufferHeight = 0; } void EndCommandBuffer() @@ -287,6 +300,8 @@ namespace VulkanUtilities VkPipeline ComputePipeline = VK_NULL_HANDLE; VkBuffer IndexBuffer = VK_NULL_HANDLE; VkDeviceSize IndexBufferOffset = 0; + uint32_t FramebufferWidth = 0; + uint32_t FramebufferHeight = 0; VkIndexType IndexType = VK_INDEX_TYPE_MAX_ENUM; }; diff --git a/Graphics/GraphicsEngineVulkan/interface/TextureViewVk.h b/Graphics/GraphicsEngineVulkan/interface/TextureViewVk.h index 657b31c7..cdc2c683 100644 --- a/Graphics/GraphicsEngineVulkan/interface/TextureViewVk.h +++ b/Graphics/GraphicsEngineVulkan/interface/TextureViewVk.h @@ -40,8 +40,8 @@ class ITextureViewVk : public ITextureView { public: - /// Returns CPU descriptor handle of the texture view. - //virtual D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() = 0; + /// Returns Vulkan image view handle + virtual VkImageView GetVulkanImageView()const = 0; }; } diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 43cf53c9..84683c88 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -116,10 +116,11 @@ namespace Diligent void DeviceContextVkImpl::SetPipelineState(IPipelineState *pPipelineState) { - if (m_CommandBuffer.GetState().RenderPass) + if (m_CommandBuffer.GetState().RenderPass != VK_NULL_HANDLE) { m_CommandBuffer.EndRenderPass(); } + m_CommandBuffer.ResetFramebuffer(); // Never flush deferred context! if (!m_bIsDeferred && m_State.NumCommands >= m_NumCommandsToFlush) @@ -221,10 +222,72 @@ namespace Diligent } } - void DeviceContextVkImpl::CommitRenderPassAndFramebuffer() + void DeviceContextVkImpl::CommitRenderPassAndFramebuffer(PipelineStateVkImpl *pPipelineStateVk) { - auto *pPipelineStateVk = m_pPipelineState.RawPtr<PipelineStateVkImpl>(); - + auto *pRenderDeviceVk = m_pDevice.RawPtr<RenderDeviceVkImpl>(); + auto &FBCache = pRenderDeviceVk->GetFramebufferCache(); + auto RenderPass = pPipelineStateVk->GetVkRenderPass(); + const auto& CmdBufferState = m_CommandBuffer.GetState(); + if(CmdBufferState.Framebuffer != VK_NULL_HANDLE) + { + // Render targets have not changed since last time, so we can reuse + // previously bound framebuffer + VERIFY_EXPR(m_FramebufferWidth == CmdBufferState.FramebufferWidth && m_FramebufferHeight == CmdBufferState.FramebufferHeight); + m_CommandBuffer.BeginRenderPass(RenderPass, CmdBufferState.Framebuffer, CmdBufferState.FramebufferWidth, CmdBufferState.FramebufferHeight); + return; + } + + FramebufferCache::FramebufferCacheKey Key; + Key.Pass = RenderPass; + if(m_NumBoundRenderTargets == 0 && !m_pBoundDepthStencil) + { + auto *pSwapChainVk = m_pSwapChain.RawPtr<ISwapChainVk>(); + const auto &GrPipelineDesc = pPipelineStateVk->GetDesc().GraphicsPipeline; + if(GrPipelineDesc.DSVFormat != TEX_FORMAT_UNKNOWN) + { + auto *pDSV = pSwapChainVk->GetDepthBufferDSV(); + TransitionImageLayout(pDSV->GetTexture(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + Key.DSV = pDSV->GetVulkanImageView(); + } + else + Key.DSV = VK_NULL_HANDLE; + + if(GrPipelineDesc.RTVFormats[0] != TEX_FORMAT_UNKNOWN) + { + auto *pRTV = pSwapChainVk->GetCurrentBackBufferRTV(); + TransitionImageLayout(pRTV->GetTexture(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + Key.NumRenderTargets = 1; + Key.RTVs[0] = pRTV->GetVulkanImageView(); + } + else + Key.NumRenderTargets = 0; + } + else + { + if(m_pBoundDepthStencil) + { + auto *pDSVVk = m_pBoundDepthStencil.RawPtr<TextureViewVkImpl>(); + TransitionImageLayout(pDSVVk->GetTexture(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + Key.DSV = pDSVVk->GetVulkanImageView(); + } + else + Key.DSV = nullptr; + + Key.NumRenderTargets = m_NumBoundRenderTargets; + for(Uint32 rt=0; rt < m_NumBoundRenderTargets; ++rt) + { + if(ITextureView *pRTV = m_pBoundRenderTargets[rt]) + { + auto *pRTVVk = ValidatedCast<TextureViewVkImpl>(pRTV); + TransitionImageLayout(pRTV->GetTexture(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + Key.RTVs[rt] = pRTVVk->GetVulkanImageView(); + } + else + Key.RTVs[rt] = nullptr; + } + } + auto vkFramebuffer = FBCache.GetFramebuffer(Key, m_FramebufferWidth, m_FramebufferHeight, m_FramebufferSlices); + m_CommandBuffer.BeginRenderPass(Key.Pass, vkFramebuffer, m_FramebufferWidth, m_FramebufferHeight); } void DeviceContextVkImpl::CommitVkIndexBuffer(VALUE_TYPE IndexType) @@ -357,8 +420,11 @@ namespace Diligent } #endif + auto *pPipelineStateVk = m_pPipelineState.RawPtr<PipelineStateVkImpl>(); + + EnsureVkCmdBuffer(); if(m_CommandBuffer.GetState().RenderPass == VK_NULL_HANDLE) - CommitRenderPassAndFramebuffer(); + CommitRenderPassAndFramebuffer(pPipelineStateVk); #if 0 auto &GraphCtx = RequestCmdContext()->AsGraphicsContext(); @@ -377,7 +443,7 @@ namespace Diligent CommitVkIndexBuffer(DrawAttribs.IndexType); } - auto *pPipelineStateVk = m_pPipelineState.RawPtr<PipelineStateVkImpl>(); + auto VkTopology = TopologyToVkTopology( DrawAttribs.Topology ); GraphCtx.SetPrimitiveTopology(VkTopology); @@ -799,12 +865,12 @@ namespace Diligent { if( TDeviceContextBase::SetRenderTargets( NumRenderTargets, ppRenderTargets, pDepthStencil ) ) { -#if 0 - CommitRenderTargets(); + if(m_CommandBuffer.GetState().RenderPass != VK_NULL_HANDLE) + m_CommandBuffer.EndRenderPass(); + m_CommandBuffer.ResetFramebuffer(); // Set the viewport to match the render target size SetViewports(1, nullptr, 0, 0); -#endif } } diff --git a/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp b/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp index d34564c3..d3fbd6c5 100644 --- a/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp +++ b/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp @@ -111,6 +111,10 @@ FramebufferCache::~FramebufferCache() void FramebufferCache::OnDestroyImageView(VkImageView ImgView) { + // TODO: when a render pass is released, we need to also destroy + // all entries in the m_ViewToKeyMap that refer to all keys with + // that render pass + std::lock_guard<std::mutex> Lock(m_Mutex); auto equal_range = m_ViewToKeyMap.equal_range(ImgView); for(auto it = equal_range.first; it != equal_range.second; ++it) @@ -129,6 +133,9 @@ void FramebufferCache::OnDestroyImageView(VkImageView ImgView) void FramebufferCache::OnDestroyRenderPass(VkRenderPass Pass) { + // TODO: when an image view is released, we need to also destroy + // all entries in the m_RenderPassToKeyMap that refer to the keys + // with the same image view std::lock_guard<std::mutex> Lock(m_Mutex); auto equal_range = m_RenderPassToKeyMap.equal_range(Pass); for (auto it = equal_range.first; it != equal_range.second; ++it) |
