summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-08-11 01:45:28 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-08-11 01:45:28 +0000
commit80d0d972308444d949eb1c363fb81864143c0762 (patch)
treed12cb2ad7589607e9a42370a319a276393670ce0 /Graphics/GraphicsEngineOpenGL
parentD3D12 backend: disabled warnings about render target and depth stencil clear ... (diff)
downloadDiligentCore-80d0d972308444d949eb1c363fb81864143c0762.tar.gz
DiligentCore-80d0d972308444d949eb1c363fb81864143c0762.zip
Initial implementation of render passes in GL backend
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp7
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp12
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp54
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp213
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp29
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp6
7 files changed, 219 insertions, 108 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
index ad9ff03b..11886c11 100644
--- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp
@@ -27,6 +27,8 @@
#pragma once
+#include <vector>
+
#include "DeviceContextGL.h"
#include "DeviceContextBase.hpp"
#include "BaseInterfacesGL.h"
@@ -264,6 +266,8 @@ private:
__forceinline void PrepareForIndirectDraw(IBuffer* pAttribsBuffer);
__forceinline void PostDraw();
+ void BeginSubpass();
+
Uint32 m_CommitedResourcesTentativeBarriers = 0;
std::vector<class TextureBaseGL*> m_BoundWritableTextures;
@@ -274,6 +278,8 @@ private:
bool m_IsDefaultFBOBound = false;
GLObjectWrappers::GLFrameBufferObj m_DefaultFBO;
+
+ std::vector<OptimizedClearValue> m_AttachmentClearValues;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp b/Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp
index 98e097d2..928da3f8 100644
--- a/Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp
@@ -51,6 +51,11 @@ public:
FBOCache& operator = ( FBOCache&&) = delete;
// clang-format on
+ static GLObjectWrappers::GLFrameBufferObj CreateFBO(class GLContextState& ContextState,
+ Uint32 NumRenderTargets,
+ TextureViewGLImpl* ppRTVs[],
+ TextureViewGLImpl* pDSV);
+
const GLObjectWrappers::GLFrameBufferObj& GetFBO(Uint32 NumRenderTargets,
TextureViewGLImpl* ppRTVs[],
TextureViewGLImpl* pDSV,
@@ -91,7 +96,7 @@ private:
// Multimap that sets up correspondence between unique texture id and all
// FBOs it is used in
- std::unordered_multimap<Diligent::UniqueIdentifier, FBOCacheKey> m_TexIdToKey;
+ std::unordered_multimap<UniqueIdentifier, FBOCacheKey> m_TexIdToKey;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp
index 8144ffe3..92d05e46 100644
--- a/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp
@@ -30,9 +30,12 @@
/// \file
/// Declaration of Diligent::FramebufferGLImpl class
+#include <vector>
+
#include "RenderDeviceGL.h"
#include "FramebufferBase.hpp"
#include "RenderDeviceGLImpl.hpp"
+#include "GLObjectWrapper.hpp"
namespace Diligent
{
@@ -47,8 +50,17 @@ public:
FramebufferGLImpl(IReferenceCounters* pRefCounters,
RenderDeviceGLImpl* pDevice,
+ GLContextState& CtxState,
const FramebufferDesc& Desc);
~FramebufferGLImpl();
+
+ const GLObjectWrappers::GLFrameBufferObj& GetSubpassFramebuffer(Uint32 subpass)
+ {
+ return m_SubpassFramebuffers[subpass];
+ }
+
+private:
+ std::vector<GLObjectWrappers::GLFrameBufferObj> m_SubpassFramebuffers;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
index 478be058..265f9f0f 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -416,22 +416,70 @@ void DeviceContextGLImpl::ResetRenderTargets()
m_ContextState.InvalidateFBO();
}
+void DeviceContextGLImpl::BeginSubpass()
+{
+ 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];
+ const auto& FBDesc = m_pBoundFramebuffer->GetDesc();
+ for (Uint32 rt = 0; rt < SubpassDesc.RenderTargetAttachmentCount; ++rt)
+ {
+ const auto& RTAttachmentRef = SubpassDesc.pRenderTargetAttachments[rt];
+ if (RTAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED)
+ {
+ const auto& AttachmentDesc = RPDesc.pAttachments[RTAttachmentRef.AttachmentIndex];
+ auto FirstLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(RTAttachmentRef.AttachmentIndex);
+ if (FirstLastUse.first == m_SubpassIndex && AttachmentDesc.LoadOp == ATTACHMENT_LOAD_OP_CLEAR)
+ {
+ auto* pRTV = FBDesc.ppAttachments[RTAttachmentRef.AttachmentIndex];
+ ClearRenderTarget(pRTV, m_AttachmentClearValues[RTAttachmentRef.AttachmentIndex].Color, RESOURCE_STATE_TRANSITION_MODE_NONE);
+ }
+ }
+ }
+
+ if (SubpassDesc.pDepthStencilAttachment != nullptr && SubpassDesc.pDepthStencilAttachment->AttachmentIndex != ATTACHMENT_UNUSED)
+ {
+ auto DepthAttachmentIndex = SubpassDesc.pDepthStencilAttachment->AttachmentIndex;
+ const auto& AttachmentDesc = RPDesc.pAttachments[DepthAttachmentIndex];
+ auto FirstLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(DepthAttachmentIndex);
+ if (FirstLastUse.first == m_SubpassIndex && AttachmentDesc.LoadOp == ATTACHMENT_LOAD_OP_CLEAR)
+ {
+ auto* pDSV = FBDesc.ppAttachments[DepthAttachmentIndex];
+ const auto& ClearVal = m_AttachmentClearValues[DepthAttachmentIndex].DepthStencil;
+ ClearDepthStencil(pDSV, CLEAR_DEPTH_FLAG | CLEAR_STENCIL_FLAG, ClearVal.Depth, ClearVal.Stencil, RESOURCE_STATE_TRANSITION_MODE_NONE);
+ }
+ }
+}
+
void DeviceContextGLImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs)
{
TDeviceContextBase::BeginRenderPass(Attribs);
- UNEXPECTED("Method not implemented");
+
+ m_AttachmentClearValues.resize(Attribs.ClearValueCount);
+ for (Uint32 i = 0; i < Attribs.ClearValueCount; ++i)
+ m_AttachmentClearValues[i] = Attribs.pClearValues[i];
+
+ VERIFY_EXPR(m_pBoundFramebuffer);
+ m_ContextState.BindFBO(m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex));
+ SetViewports(1, nullptr, 0, 0);
+
+ BeginSubpass();
}
void DeviceContextGLImpl::NextSubpass()
{
TDeviceContextBase::NextSubpass();
- UNEXPECTED("Method not implemented");
+
+ m_ContextState.BindFBO(m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex));
+
+ BeginSubpass();
}
void DeviceContextGLImpl::EndRenderPass()
{
TDeviceContextBase::EndRenderPass();
- UNEXPECTED("Method not implemented");
}
void DeviceContextGLImpl::BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding)
diff --git a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp
index 5d18a955..e11a3af2 100644
--- a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp
@@ -109,6 +109,116 @@ void FBOCache::OnReleaseTexture(ITexture* pTexture)
m_TexIdToKey.erase(EqualRange.first, EqualRange.second);
}
+GLObjectWrappers::GLFrameBufferObj FBOCache::CreateFBO(GLContextState& ContextState,
+ Uint32 NumRenderTargets,
+ TextureViewGLImpl* ppRTVs[],
+ TextureViewGLImpl* pDSV)
+{
+ GLObjectWrappers::GLFrameBufferObj FBO{true};
+
+ ContextState.BindFBO(FBO);
+
+ // Initialize the FBO
+ for (Uint32 rt = 0; rt < NumRenderTargets; ++rt)
+ {
+ if (auto* pRTView = ppRTVs[rt])
+ {
+ const auto& RTVDesc = pRTView->GetDesc();
+ auto* pColorTexGL = pRTView->GetTexture<TextureBaseGL>();
+ pColorTexGL->AttachToFramebuffer(RTVDesc, GL_COLOR_ATTACHMENT0 + rt);
+ }
+ }
+
+ if (pDSV != nullptr)
+ {
+ const auto& DSVDesc = pDSV->GetDesc();
+ auto* pDepthTexGL = pDSV->GetTexture<TextureBaseGL>();
+ GLenum AttachmentPoint = 0;
+ if (DSVDesc.Format == TEX_FORMAT_D32_FLOAT ||
+ DSVDesc.Format == TEX_FORMAT_D16_UNORM)
+ {
+#ifdef DILIGENT_DEBUG
+ {
+ const auto GLTexFmt = pDepthTexGL->GetGLTexFormat();
+ VERIFY(GLTexFmt == GL_DEPTH_COMPONENT32F || GLTexFmt == GL_DEPTH_COMPONENT16,
+ "Inappropriate internal texture format (", GLTexFmt,
+ ") for depth attachment. GL_DEPTH_COMPONENT32F or GL_DEPTH_COMPONENT16 is expected");
+ }
+#endif
+ AttachmentPoint = GL_DEPTH_ATTACHMENT;
+ }
+ else if (DSVDesc.Format == TEX_FORMAT_D32_FLOAT_S8X24_UINT ||
+ DSVDesc.Format == TEX_FORMAT_D24_UNORM_S8_UINT)
+ {
+#ifdef DILIGENT_DEBUG
+ {
+ const auto GLTexFmt = pDepthTexGL->GetGLTexFormat();
+ VERIFY(GLTexFmt == GL_DEPTH24_STENCIL8 || GLTexFmt == GL_DEPTH32F_STENCIL8,
+ "Inappropriate internal texture format (", GLTexFmt,
+ ") for depth-stencil attachment. GL_DEPTH24_STENCIL8 or GL_DEPTH32F_STENCIL8 is expected");
+ }
+#endif
+ AttachmentPoint = GL_DEPTH_STENCIL_ATTACHMENT;
+ }
+ else
+ {
+ UNEXPECTED(GetTextureFormatAttribs(DSVDesc.Format).Name, " is not valid depth-stencil view format");
+ }
+ pDepthTexGL->AttachToFramebuffer(DSVDesc, AttachmentPoint);
+ }
+
+ // We now need to set mapping between shader outputs and
+ // color attachments. This largely redundant step is performed
+ // by glDrawBuffers()
+ // clang-format off
+ static const GLenum DrawBuffers[] =
+ {
+ GL_COLOR_ATTACHMENT0,
+ GL_COLOR_ATTACHMENT1,
+ GL_COLOR_ATTACHMENT2,
+ GL_COLOR_ATTACHMENT3,
+ GL_COLOR_ATTACHMENT4,
+ GL_COLOR_ATTACHMENT5,
+ GL_COLOR_ATTACHMENT6,
+ GL_COLOR_ATTACHMENT7,
+ GL_COLOR_ATTACHMENT8,
+ GL_COLOR_ATTACHMENT9,
+ GL_COLOR_ATTACHMENT10,
+ GL_COLOR_ATTACHMENT11,
+ GL_COLOR_ATTACHMENT12,
+ GL_COLOR_ATTACHMENT13,
+ GL_COLOR_ATTACHMENT14,
+ GL_COLOR_ATTACHMENT15
+ };
+ // clang-format on
+
+ // The state set by glDrawBuffers() is part of the state of the framebuffer.
+ // So it can be set up once and left it set.
+ glDrawBuffers(NumRenderTargets, DrawBuffers);
+ CHECK_GL_ERROR("Failed to set draw buffers via glDrawBuffers()");
+
+ GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (Status != GL_FRAMEBUFFER_COMPLETE)
+ {
+ const Char* StatusString = "Unknown";
+ switch (Status)
+ {
+ // clang-format off
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break;
+ case GL_FRAMEBUFFER_UNSUPPORTED: StatusString = "GL_FRAMEBUFFER_UNSUPPORTED"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; break;
+ case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; break;
+ // clang-format on
+ }
+ LOG_ERROR("Framebuffer is incomplete. FB status: ", StatusString);
+ UNEXPECTED("Framebuffer is incomplete");
+ }
+ return FBO;
+}
+
const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 NumRenderTargets,
TextureViewGLImpl* ppRTVs[],
TextureViewGLImpl* pDSV,
@@ -163,108 +273,7 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 Nu
else
{
// Create a new FBO
- GLObjectWrappers::GLFrameBufferObj NewFBO(true);
-
- ContextState.BindFBO(NewFBO);
-
- // Initialize the FBO
- for (Uint32 rt = 0; rt < NumRenderTargets; ++rt)
- {
- if (auto* pRTView = ppRTVs[rt])
- {
- const auto& RTVDesc = pRTView->GetDesc();
- auto* pColorTexGL = pRTView->GetTexture<TextureBaseGL>();
- pColorTexGL->AttachToFramebuffer(RTVDesc, GL_COLOR_ATTACHMENT0 + rt);
- }
- }
-
- if (pDSV != nullptr)
- {
- const auto& DSVDesc = pDSV->GetDesc();
- auto* pDepthTexGL = pDSV->GetTexture<TextureBaseGL>();
- GLenum AttachmentPoint = 0;
- if (DSVDesc.Format == TEX_FORMAT_D32_FLOAT ||
- DSVDesc.Format == TEX_FORMAT_D16_UNORM)
- {
-#ifdef DILIGENT_DEBUG
- {
- const auto GLTexFmt = pDepthTexGL->GetGLTexFormat();
- VERIFY(GLTexFmt == GL_DEPTH_COMPONENT32F || GLTexFmt == GL_DEPTH_COMPONENT16,
- "Inappropriate internal texture format (", GLTexFmt,
- ") for depth attachment. GL_DEPTH_COMPONENT32F or GL_DEPTH_COMPONENT16 is expected");
- }
-#endif
- AttachmentPoint = GL_DEPTH_ATTACHMENT;
- }
- else if (DSVDesc.Format == TEX_FORMAT_D32_FLOAT_S8X24_UINT ||
- DSVDesc.Format == TEX_FORMAT_D24_UNORM_S8_UINT)
- {
-#ifdef DILIGENT_DEBUG
- {
- const auto GLTexFmt = pDepthTexGL->GetGLTexFormat();
- VERIFY(GLTexFmt == GL_DEPTH24_STENCIL8 || GLTexFmt == GL_DEPTH32F_STENCIL8,
- "Inappropriate internal texture format (", GLTexFmt,
- ") for depth-stencil attachment. GL_DEPTH24_STENCIL8 or GL_DEPTH32F_STENCIL8 is expected");
- }
-#endif
- AttachmentPoint = GL_DEPTH_STENCIL_ATTACHMENT;
- }
- else
- {
- UNEXPECTED(GetTextureFormatAttribs(DSVDesc.Format).Name, " is not valid depth-stencil view format");
- }
- pDepthTexGL->AttachToFramebuffer(DSVDesc, AttachmentPoint);
- }
-
- // We now need to set mapping between shader outputs and
- // color attachments. This largely redundant step is performed
- // by glDrawBuffers()
- // clang-format off
- static const GLenum DrawBuffers[] =
- {
- GL_COLOR_ATTACHMENT0,
- GL_COLOR_ATTACHMENT1,
- GL_COLOR_ATTACHMENT2,
- GL_COLOR_ATTACHMENT3,
- GL_COLOR_ATTACHMENT4,
- GL_COLOR_ATTACHMENT5,
- GL_COLOR_ATTACHMENT6,
- GL_COLOR_ATTACHMENT7,
- GL_COLOR_ATTACHMENT8,
- GL_COLOR_ATTACHMENT9,
- GL_COLOR_ATTACHMENT10,
- GL_COLOR_ATTACHMENT11,
- GL_COLOR_ATTACHMENT12,
- GL_COLOR_ATTACHMENT13,
- GL_COLOR_ATTACHMENT14,
- GL_COLOR_ATTACHMENT15
- };
- // clang-format on
-
- // The state set by glDrawBuffers() is part of the state of the framebuffer.
- // So it can be set up once and left it set.
- glDrawBuffers(NumRenderTargets, DrawBuffers);
- CHECK_GL_ERROR("Failed to set draw buffers via glDrawBuffers()");
-
- GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (Status != GL_FRAMEBUFFER_COMPLETE)
- {
- const Char* StatusString = "Unknown";
- switch (Status)
- {
- // clang-format off
- case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break;
- case GL_FRAMEBUFFER_UNSUPPORTED: StatusString = "GL_FRAMEBUFFER_UNSUPPORTED"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"; break;
- // clang-format on
- }
- LOG_ERROR("Framebuffer is incomplete. FB status: ", StatusString);
- UNEXPECTED("Framebuffer is incomplete");
- }
+ auto NewFBO = CreateFBO(ContextState, NumRenderTargets, ppRTVs, pDSV);
auto NewElems = m_Cache.emplace(std::make_pair(Key, std::move(NewFBO)));
// New element must be actually inserted
diff --git a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp
index 6ec1d1f1..d9f8341f 100644
--- a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp
@@ -28,16 +28,43 @@
#include "pch.h"
#include "FramebufferGLImpl.hpp"
-#include "EngineMemory.h"
+#include "FBOCache.hpp"
+#include "TextureViewGLImpl.hpp"
namespace Diligent
{
FramebufferGLImpl::FramebufferGLImpl(IReferenceCounters* pRefCounters,
RenderDeviceGLImpl* pDevice,
+ GLContextState& CtxState,
const FramebufferDesc& Desc) :
TFramebufferBase{pRefCounters, pDevice, Desc}
{
+ const auto& RPDesc = m_Desc.pRenderPass->GetDesc();
+ m_SubpassFramebuffers.reserve(RPDesc.SubpassCount);
+ for (Uint32 subpass = 0; subpass < RPDesc.SubpassCount; ++subpass)
+ {
+ const auto& SubpassDesc = RPDesc.pSubpasses[subpass];
+
+ TextureViewGLImpl* ppRTVs[MAX_RENDER_TARGETS] = {};
+ TextureViewGLImpl* pDSV = nullptr;
+
+ for (Uint32 rt = 0; rt < SubpassDesc.RenderTargetAttachmentCount; ++rt)
+ {
+ const auto& RTAttachmentRef = SubpassDesc.pRenderTargetAttachments[rt];
+ if (RTAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED)
+ {
+ ppRTVs[rt] = ValidatedCast<TextureViewGLImpl>(m_Desc.ppAttachments[RTAttachmentRef.AttachmentIndex]);
+ }
+ }
+
+ if (SubpassDesc.pDepthStencilAttachment != nullptr && SubpassDesc.pDepthStencilAttachment->AttachmentIndex != ATTACHMENT_UNUSED)
+ {
+ 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));
+ }
}
FramebufferGLImpl::~FramebufferGLImpl()
diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
index 6506c5df..ae77fbcf 100644
--- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
@@ -537,7 +537,11 @@ void RenderDeviceGLImpl::CreateFramebuffer(const FramebufferDesc& Desc, IFramebu
CreateDeviceObject("Framebuffer", Desc, ppFramebuffer,
[&]() //
{
- FramebufferGLImpl* pFramebufferGL(NEW_RC_OBJ(m_FramebufferAllocator, "FramebufferGLImpl instance", FramebufferGLImpl)(this, Desc));
+ auto spDeviceContext = GetImmediateContext();
+ VERIFY(spDeviceContext, "Immediate device context has been destroyed");
+ auto& GLState = spDeviceContext.RawPtr<DeviceContextGLImpl>()->GetContextState();
+
+ FramebufferGLImpl* pFramebufferGL(NEW_RC_OBJ(m_FramebufferAllocator, "FramebufferGLImpl instance", FramebufferGLImpl)(this, GLState, Desc));
pFramebufferGL->QueryInterface(IID_Framebuffer, reinterpret_cast<IObject**>(ppFramebuffer));
OnCreateDeviceObject(pFramebufferGL);
});