diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2019-12-24 05:24:13 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2019-12-24 05:24:13 +0000 |
| commit | 4fd74ca8444da6491d5ec5f5e2b569c09cba2b3a (patch) | |
| tree | 34bc4400307614539e044c0582f33ee2ce4dd643 /Graphics/GraphicsEngineOpenGL | |
| parent | OpenGL backend: fixed issue with copying default framebuffer (diff) | |
| download | DiligentCore-4fd74ca8444da6491d5ec5f5e2b569c09cba2b3a.tar.gz DiligentCore-4fd74ca8444da6491d5ec5f5e2b569c09cba2b3a.zip | |
Disabled SetRenderTarget(0, nullptr, nullptr) usage (fixed https://github.com/DiligentGraphics/DiligentCore/issues/81)
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
4 files changed, 54 insertions, 34 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index 899c6d68..38c982ca 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -36,6 +36,7 @@ namespace Diligent { class RenderDeviceGLImpl; +class ISwapChainGL; struct DeviceContextGLImplTraits { @@ -212,6 +213,11 @@ public: void CommitRenderTargets(); + void SetSwapChain(ISwapChainGL* pSwapChain); + + virtual void ResetRenderTargets() override final; + + protected: friend class BufferGLImpl; friend class TextureBaseGL; @@ -230,6 +236,10 @@ private: std::vector<class TextureBaseGL*> m_BoundWritableTextures; std::vector<class BufferGLImpl*> m_BoundWritableBuffers; + RefCntAutoPtr<ISwapChainGL> m_pSwapChain; + + bool m_IsDefaultFBOBound = false; + GLObjectWrappers::GLFrameBufferObj m_DefaultFBO; }; diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 746701f2..7b8624a2 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -194,6 +194,7 @@ void DeviceContextGLImpl::InvalidateState() m_ContextState.Invalidate(); m_BoundWritableTextures.clear(); m_BoundWritableBuffers.clear(); + m_IsDefaultFBOBound = false; } void DeviceContextGLImpl::SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) @@ -307,15 +308,19 @@ void DeviceContextGLImpl::SetScissorRects(Uint32 NumRects, const Rect* pRects, U } } +void DeviceContextGLImpl::SetSwapChain(ISwapChainGL* pSwapChain) +{ + m_pSwapChain = pSwapChain; +} + void DeviceContextGLImpl::CommitRenderTargets() { - if (!m_IsDefaultFramebufferBound && m_NumBoundRenderTargets == 0 && !m_pBoundDepthStencil) + if (!m_IsDefaultFBOBound && m_NumBoundRenderTargets == 0 && !m_pBoundDepthStencil) return; - if (m_IsDefaultFramebufferBound) + if (m_IsDefaultFBOBound) { - auto* pSwapChainGL = m_pSwapChain.RawPtr<ISwapChainGL>(); - GLuint DefaultFBOHandle = pSwapChainGL->GetDefaultFBO(); + GLuint DefaultFBOHandle = m_pSwapChain->GetDefaultFBO(); if (m_DefaultFBO != DefaultFBOHandle) { m_DefaultFBO = GLObjectWrappers::GLFrameBufferObj(true, GLObjectWrappers::GLFBOCreateReleaseHelper(DefaultFBOHandle)); @@ -366,26 +371,34 @@ void DeviceContextGLImpl::SetRenderTargets(Uint32 NumRen { if (TDeviceContextBase::SetRenderTargets(NumRenderTargets, ppRenderTargets, pDepthStencil)) { - if (!m_IsDefaultFramebufferBound) + if (m_NumBoundRenderTargets == 1 && m_pBoundRenderTargets[0] && m_pBoundRenderTargets[0]->GetTexture<TextureBaseGL>()->GetGLHandle() == 0) { - if (m_NumBoundRenderTargets == 1 && m_pBoundRenderTargets[0] && m_pBoundRenderTargets[0]->GetTexture<TextureBaseGL>()->GetGLHandle() == 0) - { - DEV_CHECK_ERR(!m_pBoundDepthStencil || m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle() == 0, - "Attempting to bind texture '", m_pBoundDepthStencil->GetTexture()->GetDesc().Name, - "' as depth buffer with the default framebuffer's color buffer: color buffer of the default framebuffer " - "can only be bound with the default framebuffer's depth buffer and cannot be combined with any other depth buffer in OpenGL backend."); - m_IsDefaultFramebufferBound = true; - } - else if (m_NumBoundRenderTargets == 0 && m_pBoundDepthStencil && m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle() == 0) - { - m_IsDefaultFramebufferBound = true; - } + DEV_CHECK_ERR(!m_pBoundDepthStencil || m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle() == 0, + "Attempting to bind texture '", m_pBoundDepthStencil->GetTexture()->GetDesc().Name, + "' as depth buffer with the default framebuffer's color buffer: color buffer of the default framebuffer " + "can only be bound with the default framebuffer's depth buffer and cannot be combined with any other depth buffer in OpenGL backend."); + m_IsDefaultFBOBound = true; + } + else if (m_NumBoundRenderTargets == 0 && m_pBoundDepthStencil && m_pBoundDepthStencil->GetTexture<TextureBaseGL>()->GetGLHandle() == 0) + { + m_IsDefaultFBOBound = true; + } + else + { + m_IsDefaultFBOBound = false; } CommitRenderTargets(); } } +void DeviceContextGLImpl::ResetRenderTargets() +{ + TDeviceContextBase::ResetRenderTargets(); + m_IsDefaultFBOBound = false; +} + + void DeviceContextGLImpl::BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding) { if (!m_pPipelineState) @@ -925,10 +938,10 @@ void DeviceContextGLImpl::ClearDepthStencil(ITextureView* pView } else { - if (!m_IsDefaultFramebufferBound) + if (!m_pBoundDepthStencil) { - UNEXPECTED("Default depth stencil buffer being cleared is not bound to the pipeline"); - LOG_ERROR_MESSAGE("Default depth stencil buffer must be bound to the pipeline to be cleared"); + LOG_ERROR_MESSAGE("ClearDepthStencil(nullptr, ...) is invalid because no depth-stencil buffer is currently bound."); + return; } } Uint32 glClearFlags = 0; @@ -978,12 +991,13 @@ void DeviceContextGLImpl::ClearRenderTarget(ITextureView* pView, const float* RG } else { - if (m_IsDefaultFramebufferBound) + if (m_NumBoundRenderTargets == 1) RTIndex = 0; else { - UNEXPECTED("Default render target must be bound to the pipeline to be cleared"); - LOG_ERROR_MESSAGE("Default render target must be bound to the pipeline to be cleared"); + LOG_ERROR_MESSAGE("ClearRenderTarget(nullptr, ...) semantic is only allowed when single render target is bound to the context. ", + m_NumBoundRenderTargets, " render ", + (m_NumBoundRenderTargets != 1 ? "targets are" : "target is"), " currently bound"); } } diff --git a/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp b/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp index 14fbd670..1300ad68 100644 --- a/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp @@ -149,9 +149,6 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLCreateInf pSwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain)); pDeviceContextOpenGL->SetSwapChain(pSwapChainGL); - // Bind default framebuffer and viewport - pDeviceContextOpenGL->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - pDeviceContextOpenGL->SetViewports(1, nullptr, 0, 0); } catch (const std::runtime_error&) { diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp index c47b8812..831fdb7e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp @@ -132,15 +132,14 @@ void SwapChainGLImpl::Resize(Uint32 NewWidth, Uint32 NewHeight) VERIFY(pDeviceContext, "Immediate context has been released"); if (pDeviceContext) { - auto* pImmediateCtxGL = pDeviceContext.RawPtr<DeviceContextGLImpl>(); - bool bIsDefaultFBBound = pImmediateCtxGL->IsDefaultFBBound(); - - // To update the viewport is the only thing we need to do in OpenGL - if (bIsDefaultFBBound) + auto* pImmediateCtxGL = pDeviceContext.RawPtr<DeviceContextGLImpl>(); + // Unbind the back buffer to be consistent with other backends + auto* pCurrentBackBuffer = ValidatedCast<TextureBaseGL>(m_pRenderTargetView->GetTexture()); + auto RenderTargetsReset = pImmediateCtxGL->UnbindTextureFromFramebuffer(pCurrentBackBuffer, false); + if (RenderTargetsReset) { - // Update framebuffer size and viewport - pImmediateCtxGL->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - pImmediateCtxGL->SetViewports(1, nullptr, 0, 0); + LOG_INFO_MESSAGE_ONCE("Resizing the swap chain requires back and depth-stencil buffers to be unbound from the device context. " + "An application should use SetRenderTargets() to restore them."); } } } |
