summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-08-11 04:26:05 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-08-11 04:26:05 +0000
commit5a7eefa4b133574d28400b0e3cb4d4c415e1bf8e (patch)
treecc98b304deca3b8d39b9dd157b76c3bf8f00a416 /Graphics/GraphicsEngineOpenGL
parentImplemented render pass MS resolve test reference in GL (diff)
downloadDiligentCore-5a7eefa4b133574d28400b0e3cb4d4c415e1bf8e.tar.gz
DiligentCore-5a7eefa4b133574d28400b0e3cb4d4c415e1bf8e.zip
Implemented render pass MS resolve in OpenGL
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp1
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp16
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp43
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp20
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));
}
}