summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-04-21 06:12:43 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-04-21 06:12:43 +0000
commit67c24cfd4c5ef9ce9af1ea5a1943d4df9c9f0017 (patch)
tree63778f49d56e0a92c1a4c9099a3779de946f4d5b /Graphics/GraphicsEngineVulkan
parentRenamed ClearRenderTargets to ResetRenderTargets (diff)
downloadDiligentCore-67c24cfd4c5ef9ce9af1ea5a1943d4df9c9f0017.tar.gz
DiligentCore-67c24cfd4c5ef9ce9af1ea5a1943d4df9c9f0017.zip
Added Vulkan render pass and framebuffer commit
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h15
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/TextureViewVk.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp84
-rw-r--r--Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp7
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)