summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-08-20 06:31:00 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-08-20 06:31:00 +0000
commit7f69c9a0cc400e118a046e1e5b916ee25ced146e (patch)
treebbecb254d6bcff1a667e717827447a3ae00bede3 /Graphics/GraphicsEngineOpenGL
parentD3D11 backend: reworked subpass transitons to fix the issue with render targe... (diff)
downloadDiligentCore-7f69c9a0cc400e118a046e1e5b916ee25ced146e.tar.gz
DiligentCore-7f69c9a0cc400e118a046e1e5b916ee25ced146e.zip
GL backend: implemented render passes attachment invalidation with glInvalidateFramebuffer
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp80
1 files changed, 75 insertions, 5 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
index 1b7b6891..cf655a01 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -29,6 +29,7 @@
#include <iostream>
#include <fstream>
#include <string>
+#include <array>
#include "SwapChainGL.h"
#include "DeviceContextGLImpl.hpp"
@@ -498,13 +499,20 @@ void DeviceContextGLImpl::EndSubpass()
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_READ_FRAMEBUFFER, SubpassFBOs.RenderTarget);
- DEV_CHECK_GL_ERROR("Failed to bind subpass render target FBO as read framebuffer");
+ const auto& SubpassFBOs = m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex);
+#ifdef DILIGENT_DEBUG
+ {
+ GLint glCurrReadFB = 0;
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &glCurrReadFB);
+ CHECK_GL_ERROR("Failed to get current read framebuffer");
+ GLuint glExpectedReadFB = SubpassFBOs.RenderTarget != 0 ? static_cast<GLuint>(SubpassFBOs.RenderTarget) : m_pSwapChain->GetDefaultFBO();
+ VERIFY(static_cast<GLuint>(glCurrReadFB) == glExpectedReadFB, "Unexpected read framebuffer");
+ }
+#endif
+ if (SubpassDesc.pResolveAttachments != nullptr)
+ {
GLuint ResolveDstFBO = SubpassFBOs.Resolve;
if (ResolveDstFBO == 0)
{
@@ -521,6 +529,68 @@ void DeviceContextGLImpl::EndSubpass()
);
DEV_CHECK_GL_ERROR("glBlitFramebuffer() failed when resolving multi-sampled attachments");
}
+
+ if (glInvalidateFramebuffer != nullptr)
+ {
+ // It is crucially important to invalidate the framebuffer while it is bound
+ // https://community.arm.com/developer/tools-software/graphics/b/blog/posts/mali-performance-2-how-to-correctly-handle-framebuffers
+ GLsizei InvalidateAttachmentsCount = 0;
+
+ std::array<GLenum, MAX_RENDER_TARGETS + 1> InvalidateAttachments;
+ for (Uint32 rt = 0; rt < SubpassDesc.RenderTargetAttachmentCount; ++rt)
+ {
+ const auto RTAttachmentIdx = SubpassDesc.pRenderTargetAttachments[rt].AttachmentIndex;
+ if (RTAttachmentIdx != ATTACHMENT_UNUSED)
+ {
+ auto AttachmentLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(RTAttachmentIdx).second;
+ if (AttachmentLastUse == m_SubpassIndex && RPDesc.pAttachments[RTAttachmentIdx].StoreOp == ATTACHMENT_STORE_OP_DISCARD)
+ {
+ if (SubpassFBOs.RenderTarget == 0)
+ {
+ VERIFY(rt == 0, "Default framebuffer can only have single color attachment");
+ InvalidateAttachments[InvalidateAttachmentsCount++] = GL_COLOR;
+ }
+ else
+ {
+ InvalidateAttachments[InvalidateAttachmentsCount++] = GL_COLOR_ATTACHMENT0 + rt;
+ }
+ }
+ }
+ }
+
+ if (SubpassDesc.pDepthStencilAttachment != nullptr)
+ {
+ const auto DSAttachmentIdx = SubpassDesc.pDepthStencilAttachment->AttachmentIndex;
+ if (DSAttachmentIdx != ATTACHMENT_UNUSED)
+ {
+ auto AttachmentLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(DSAttachmentIdx).second;
+ if (AttachmentLastUse == m_SubpassIndex && RPDesc.pAttachments[DSAttachmentIdx].StoreOp == ATTACHMENT_STORE_OP_DISCARD)
+ {
+ const auto& FmtAttribs = GetTextureFormatAttribs(RPDesc.pAttachments[DSAttachmentIdx].Format);
+ VERIFY_EXPR(FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH || FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL);
+ if (SubpassFBOs.RenderTarget == 0)
+ {
+ InvalidateAttachments[InvalidateAttachmentsCount++] = GL_DEPTH;
+ if (FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL)
+ InvalidateAttachments[InvalidateAttachmentsCount++] = GL_STENCIL;
+ }
+ else
+ {
+ InvalidateAttachments[InvalidateAttachmentsCount++] = FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT;
+ }
+ }
+ }
+ }
+
+ if (InvalidateAttachmentsCount > 0)
+ {
+ glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, InvalidateAttachmentsCount, InvalidateAttachments.data());
+ DEV_CHECK_GL_ERROR("glInvalidateFramebuffer() failed");
+ }
+ }
+
+ // TODO: invalidate input attachments using glInvalidateTexImage
+
m_ContextState.InvalidateFBO();
}