diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-08-11 04:26:05 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-08-11 04:26:05 +0000 |
| commit | 5a7eefa4b133574d28400b0e3cb4d4c415e1bf8e (patch) | |
| tree | cc98b304deca3b8d39b9dd157b76c3bf8f00a416 /Graphics/GraphicsEngineOpenGL | |
| parent | Implemented render pass MS resolve test reference in GL (diff) | |
| download | DiligentCore-5a7eefa4b133574d28400b0e3cb4d4c415e1bf8e.tar.gz DiligentCore-5a7eefa4b133574d28400b0e3cb4d4c415e1bf8e.zip | |
Implemented render pass MS resolve in OpenGL
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
4 files changed, 74 insertions, 6 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp index 11886c11..aac30d49 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp @@ -267,6 +267,7 @@ private: __forceinline void PostDraw(); void BeginSubpass(); + void EndSubpass(); Uint32 m_CommitedResourcesTentativeBarriers = 0; diff --git a/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp index 92d05e46..49ea8b84 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp @@ -54,13 +54,25 @@ public: const FramebufferDesc& Desc); ~FramebufferGLImpl(); - const GLObjectWrappers::GLFrameBufferObj& GetSubpassFramebuffer(Uint32 subpass) + struct SubpassFramebuffers + { + SubpassFramebuffers(GLObjectWrappers::GLFrameBufferObj&& _RenderTarget, + GLObjectWrappers::GLFrameBufferObj&& _Resolve) : + RenderTarget{std::move(_RenderTarget)}, + Resolve{std::move(_Resolve)} + {} + + GLObjectWrappers::GLFrameBufferObj RenderTarget; + GLObjectWrappers::GLFrameBufferObj Resolve; + }; + + const SubpassFramebuffers& GetSubpassFramebuffer(Uint32 subpass) { return m_SubpassFramebuffers[subpass]; } private: - std::vector<GLObjectWrappers::GLFrameBufferObj> m_SubpassFramebuffers; + std::vector<SubpassFramebuffers> m_SubpassFramebuffers; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 265f9f0f..37e4a3f4 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -453,6 +453,39 @@ void DeviceContextGLImpl::BeginSubpass() } } +void DeviceContextGLImpl::EndSubpass() +{ + VERIFY_EXPR(m_pActiveRenderPass); + VERIFY_EXPR(m_pBoundFramebuffer); + const auto& RPDesc = m_pActiveRenderPass->GetDesc(); + VERIFY_EXPR(m_SubpassIndex < RPDesc.SubpassCount); + const auto& SubpassDesc = RPDesc.pSubpasses[m_SubpassIndex]; + if (SubpassDesc.pResolveAttachments != nullptr) + { + const auto& SubpassFBOs = m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, SubpassFBOs.RenderTarget); + DEV_CHECK_GL_ERROR("Failed to bind subpass render target FBO as draw framebuffer"); + + GLuint ResolveDstFBO = SubpassFBOs.Resolve; + if (ResolveDstFBO == 0) + { + ResolveDstFBO = m_pSwapChain.RawPtr<ISwapChainGL>()->GetDefaultFBO(); + } + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ResolveDstFBO); + DEV_CHECK_GL_ERROR("Failed to bind resolve destination FBO as draw framebuffer"); + + const auto& FBODesc = m_pBoundFramebuffer->GetDesc(); + glBlitFramebuffer(0, 0, static_cast<GLint>(FBODesc.Width), static_cast<GLint>(FBODesc.Height), + 0, 0, static_cast<GLint>(FBODesc.Width), static_cast<GLint>(FBODesc.Height), + GL_COLOR_BUFFER_BIT, + GL_NEAREST // Filter is ignored + ); + DEV_CHECK_GL_ERROR("glBlitFramebuffer() failed when resolving multi-sampled texture"); + } + m_ContextState.InvalidateFBO(); +} + void DeviceContextGLImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) { TDeviceContextBase::BeginRenderPass(Attribs); @@ -462,7 +495,7 @@ void DeviceContextGLImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) m_AttachmentClearValues[i] = Attribs.pClearValues[i]; VERIFY_EXPR(m_pBoundFramebuffer); - m_ContextState.BindFBO(m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex)); + m_ContextState.BindFBO(m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex).RenderTarget); SetViewports(1, nullptr, 0, 0); BeginSubpass(); @@ -470,16 +503,22 @@ void DeviceContextGLImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) void DeviceContextGLImpl::NextSubpass() { + EndSubpass(); + TDeviceContextBase::NextSubpass(); - m_ContextState.BindFBO(m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex)); + m_ContextState.BindFBO(m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex).RenderTarget); BeginSubpass(); } void DeviceContextGLImpl::EndRenderPass() { + EndSubpass(); + TDeviceContextBase::EndRenderPass(); + + m_ContextState.InvalidateFBO(); } void DeviceContextGLImpl::BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding) diff --git a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp index d9f8341f..51abf1ba 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp @@ -62,8 +62,24 @@ FramebufferGLImpl::FramebufferGLImpl(IReferenceCounters* pRefCounters, { pDSV = ValidatedCast<TextureViewGLImpl>(m_Desc.ppAttachments[SubpassDesc.pDepthStencilAttachment->AttachmentIndex]); } - auto FBO = FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRTVs, pDSV); - m_SubpassFramebuffers.emplace_back(std::move(FBO)); + auto RenderTargetFBO = FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRTVs, pDSV); + + GLObjectWrappers::GLFrameBufferObj ResolveFBO{false}; + if (SubpassDesc.pResolveAttachments != nullptr) + { + TextureViewGLImpl* ppRsvlViews[MAX_RENDER_TARGETS] = {}; + for (Uint32 rt = 0; rt < SubpassDesc.RenderTargetAttachmentCount; ++rt) + { + const auto& RslvAttachmentRef = SubpassDesc.pResolveAttachments[rt]; + if (RslvAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED) + { + ppRsvlViews[rt] = ValidatedCast<TextureViewGLImpl>(m_Desc.ppAttachments[RslvAttachmentRef.AttachmentIndex]); + } + } + ResolveFBO = FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRsvlViews, nullptr); + } + + m_SubpassFramebuffers.emplace_back(std::move(RenderTargetFBO), std::move(ResolveFBO)); } } |
