From 465e53fd32f983aadc2e46c6cee3a0d7b836fe64 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 1 Aug 2020 11:46:38 -0700 Subject: Implemented BeginRenderPass/NextSubpass/EndRenderPass in Vulkan backend --- .../include/DeviceContextVkImpl.hpp | 2 + .../VulkanUtilities/VulkanCommandBuffer.hpp | 28 ++++++++--- .../src/DeviceContextVkImpl.cpp | 57 ++++++++++++++++++++-- 3 files changed, 74 insertions(+), 13 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp index eb1dd4a2..41a9395d 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp @@ -500,6 +500,8 @@ private: std::unique_ptr m_QueryMgr; Int32 m_ActiveQueriesCounter = 0; + + std::vector m_VkClearValues; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp index 1465024b..5b4fc1e7 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp @@ -156,7 +156,12 @@ public: vkCmdDispatchIndirect(m_VkCmdBuffer, Buffer, Offset); } - __forceinline void BeginRenderPass(VkRenderPass RenderPass, VkFramebuffer Framebuffer, uint32_t FramebufferWidth, uint32_t FramebufferHeight) + __forceinline void BeginRenderPass(VkRenderPass RenderPass, + VkFramebuffer Framebuffer, + uint32_t FramebufferWidth, + uint32_t FramebufferHeight, + uint32_t ClearValueCount = 0, + const VkClearValue* pClearValues = nullptr) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass == VK_NULL_HANDLE, "Current pass has not been ended"); @@ -170,13 +175,13 @@ public: BeginInfo.framebuffer = Framebuffer; // The render area MUST be contained within the framebuffer dimensions (7.4) BeginInfo.renderArea = {{0, 0}, {FramebufferWidth, FramebufferHeight}}; - BeginInfo.clearValueCount = 0; - BeginInfo.pClearValues = nullptr; // an array of VkClearValue structures that contains clear values for - // each attachment, if the attachment uses a loadOp value of VK_ATTACHMENT_LOAD_OP_CLEAR - // or if the attachment has a depth/stencil format and uses a stencilLoadOp value of - // VK_ATTACHMENT_LOAD_OP_CLEAR. The array is indexed by attachment number. Only elements - // corresponding to cleared attachments are used. Other elements of pClearValues are - // ignored (7.4) + BeginInfo.clearValueCount = ClearValueCount; + BeginInfo.pClearValues = pClearValues; // an array of VkClearValue structures that contains clear values for + // each attachment, if the attachment uses a loadOp value of VK_ATTACHMENT_LOAD_OP_CLEAR + // or if the attachment has a depth/stencil format and uses a stencilLoadOp value of + // VK_ATTACHMENT_LOAD_OP_CLEAR. The array is indexed by attachment number. Only elements + // corresponding to cleared attachments are used. Other elements of pClearValues are + // ignored (7.4) vkCmdBeginRenderPass(m_VkCmdBuffer, &BeginInfo, VK_SUBPASS_CONTENTS_INLINE // the contents of the subpass will be recorded inline in the @@ -208,6 +213,13 @@ public: } } + __forceinline void NextSubpass() + { + VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "Render pass has not been started"); + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + vkCmdNextSubpass(m_VkCmdBuffer, VK_SUBPASS_CONTENTS_INLINE); + } + __forceinline void EndCommandBuffer() { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index d1528eaa..47e7b76d 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -115,6 +115,8 @@ DeviceContextVkImpl::DeviceContextVkImpl(IReferenceCounters* p RefCntAutoPtr pDummyVB; m_pDevice->CreateBuffer(DummyVBDesc, nullptr, &pDummyVB); m_DummyVB = pDummyVB.RawPtr(); + + m_VkClearValues.reserve(16); } DeviceContextVkImpl::~DeviceContextVkImpl() @@ -279,7 +281,14 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState) { m_CommandBuffer.SetStencilReference(m_StencilRef); m_CommandBuffer.SetBlendConstants(m_BlendFactors); - CommitRenderPassAndFramebuffer(true); + if (PSODesc.GraphicsPipeline.pRenderPass == nullptr) + { + CommitRenderPassAndFramebuffer(true); + } + else + { + // Render pass must be committed explicitly + } CommitViewports(); } @@ -468,7 +477,10 @@ void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags) } #endif - CommitRenderPassAndFramebuffer((Flags & DRAW_FLAG_VERIFY_STATES) != 0); + if (m_pPipelineState->GetDesc().GraphicsPipeline.pRenderPass == nullptr) + { + CommitRenderPassAndFramebuffer((Flags & DRAW_FLAG_VERIFY_STATES) != 0); + } } BufferVkImpl* DeviceContextVkImpl::PrepareIndirectDrawAttribsBuffer(IBuffer* pAttribsBuffer, RESOURCE_STATE_TRANSITION_MODE TransitonMode) @@ -1194,19 +1206,54 @@ void DeviceContextVkImpl::ResetRenderTargets() void DeviceContextVkImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) { TDeviceContextBase::BeginRenderPass(Attribs); - UNEXPECTED("Method not implemented"); + + auto vkRenderPass = m_pActiveRenderPass->GetVkRenderPass(); + + VkFramebuffer vkFramebuffer = VK_NULL_HANDLE; + uint32_t FramebufferWidth = 0; + uint32_t FramebufferHeight = 0; + if (m_pBoundFramebuffer) + { + vkFramebuffer = m_pBoundFramebuffer->GetVkFramebuffer(); + const auto& FBDesc = m_pBoundFramebuffer->GetDesc(); + FramebufferWidth = FBDesc.Width; + FramebufferHeight = FBDesc.Height; + } + + VkClearValue* pVkClearValues = nullptr; + if (Attribs.ClearValueCount > 0) + { + m_VkClearValues.resize(Attribs.ClearValueCount); + const auto& RPDesc = m_pActiveRenderPass->GetDesc(); + for (Uint32 i = 0; i < std::min(RPDesc.AttachmentCount, Attribs.ClearValueCount); ++i) + { + const auto& ClearVal = Attribs.pClearValues[i]; + auto& vkClearVal = m_VkClearValues[i]; + + vkClearVal.color.float32[0] = ClearVal.Color[0]; + vkClearVal.color.float32[1] = ClearVal.Color[1]; + vkClearVal.color.float32[2] = ClearVal.Color[2]; + vkClearVal.color.float32[3] = ClearVal.Color[3]; + + vkClearVal.depthStencil.depth = ClearVal.DepthStencil.Depth; + vkClearVal.depthStencil.stencil = ClearVal.DepthStencil.Stencil; + } + pVkClearValues = m_VkClearValues.data(); + } + + m_CommandBuffer.BeginRenderPass(vkRenderPass, vkFramebuffer, FramebufferWidth, FramebufferHeight, Attribs.ClearValueCount, pVkClearValues); } void DeviceContextVkImpl::NextSubpass() { TDeviceContextBase::NextSubpass(); - UNEXPECTED("Method not implemented"); + m_CommandBuffer.NextSubpass(); } void DeviceContextVkImpl::EndRenderPass() { TDeviceContextBase::EndRenderPass(); - UNEXPECTED("Method not implemented"); + m_CommandBuffer.EndRenderPass(); } void DeviceContextVkImpl::UpdateBufferRegion(BufferVkImpl* pBuffVk, -- cgit v1.2.3