From a78add37a57b51d80ef2fd21a7a0799ba73dd937 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 23 Jul 2020 15:24:54 -0700 Subject: Added Render pass interface stub --- .../GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp | 4 ++++ Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp | 13 +++++++++++++ 2 files changed, 17 insertions(+) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp index 310faaf6..39084c3e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp @@ -113,6 +113,10 @@ public: /// Implementation of IRenderDevice::CreateQuery() in OpenGL backend. virtual void DILIGENT_CALL_TYPE CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) override final; + /// Implementation of IRenderDevice::CreateRenderPass() in OpenGL backend. + virtual void DILIGENT_CALL_TYPE CreateRenderPass(const RenderPassDesc& Desc, + IRenderPass** ppRenderPass) override final; + /// Implementation of IRenderDeviceGL::CreateTextureFromGLHandle(). virtual void DILIGENT_CALL_TYPE CreateTextureFromGLHandle(Uint32 GLHandle, Uint32 GLBindTarget, diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 5734ae75..f47163d8 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -515,6 +515,19 @@ void RenderDeviceGLImpl::CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) ); } +void RenderDeviceGLImpl::CreateRenderPass(const RenderPassDesc& Desc, IRenderPass** ppRenderPass) +{ + //CreateDeviceObject( + // "RenderPass", Desc, ppRenderPass, + // [&]() // + // { + // RenderPassGLImpl* pRenderPassOGL(NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassGLImpl instance", RenderPassGLImpl)(this, Desc)); + // pRenderPassOGL->RenderPassInterface(IID_RenderPass, reinterpret_cast(ppRenderPass)); + // OnCreateDeviceObject(pRenderPassOGL); + // } // + //); +} + bool RenderDeviceGLImpl::CheckExtension(const Char* ExtensionString) { return m_ExtensionStrings.find(ExtensionString) != m_ExtensionStrings.end(); -- cgit v1.2.3 From 8a7504ff49c357ad86d547a35bdfd3258bea72df Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 23 Jul 2020 15:58:46 -0700 Subject: Added render pass object implementation stubs in all backends --- Graphics/GraphicsEngineOpenGL/CMakeLists.txt | 2 + .../include/RenderPassGLImpl.hpp | 54 ++++++++++++++++++++++ .../src/RenderDeviceGLImpl.cpp | 22 +++++---- .../GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp | 47 +++++++++++++++++++ 4 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 Graphics/GraphicsEngineOpenGL/include/RenderPassGLImpl.hpp create mode 100644 Graphics/GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt index 1072d067..52251b68 100644 --- a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt +++ b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt @@ -20,6 +20,7 @@ set(INCLUDE include/PipelineStateGLImpl.hpp include/QueryGLImpl.hpp include/RenderDeviceGLImpl.hpp + include/RenderPassGLImpl.hpp include/SamplerGLImpl.hpp include/ShaderGLImpl.hpp include/ShaderResourceBindingGLImpl.hpp @@ -71,6 +72,7 @@ set(SOURCE src/PipelineStateGLImpl.cpp src/QueryGLImpl.cpp src/RenderDeviceGLImpl.cpp + src/RenderPassGLImpl.cpp src/SamplerGLImpl.cpp src/ShaderGLImpl.cpp src/ShaderResourceBindingGLImpl.cpp diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderPassGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderPassGLImpl.hpp new file mode 100644 index 00000000..e5d77333 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/RenderPassGLImpl.hpp @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RenderPassGLImpl class + +#include "RenderDeviceGL.h" +#include "RenderPassBase.hpp" +#include "RenderDeviceGLImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Render pass implementation in Direct3D11 backend. +class RenderPassGLImpl final : public RenderPassBase +{ +public: + using TRenderPassBase = RenderPassBase; + + RenderPassGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDevice, + const RenderPassDesc& Desc); + ~RenderPassGLImpl(); +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index f47163d8..bc38d364 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -46,6 +46,7 @@ #include "ShaderResourceBindingGLImpl.hpp" #include "FenceGLImpl.hpp" #include "QueryGLImpl.hpp" +#include "RenderPassGLImpl.hpp" #include "EngineMemory.h" #include "StringTools.hpp" @@ -75,7 +76,8 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters, sizeof(PipelineStateGLImpl), sizeof(ShaderResourceBindingGLImpl), sizeof(FenceGLImpl), - sizeof(QueryGLImpl) + sizeof(QueryGLImpl), + sizeof(RenderPassGLImpl) } }, // Device caps must be filled in before the constructor of Pipeline Cache is called! @@ -517,15 +519,15 @@ void RenderDeviceGLImpl::CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) void RenderDeviceGLImpl::CreateRenderPass(const RenderPassDesc& Desc, IRenderPass** ppRenderPass) { - //CreateDeviceObject( - // "RenderPass", Desc, ppRenderPass, - // [&]() // - // { - // RenderPassGLImpl* pRenderPassOGL(NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassGLImpl instance", RenderPassGLImpl)(this, Desc)); - // pRenderPassOGL->RenderPassInterface(IID_RenderPass, reinterpret_cast(ppRenderPass)); - // OnCreateDeviceObject(pRenderPassOGL); - // } // - //); + CreateDeviceObject( + "RenderPass", Desc, ppRenderPass, + [&]() // + { + RenderPassGLImpl* pRenderPassOGL(NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassGLImpl instance", RenderPassGLImpl)(this, Desc)); + pRenderPassOGL->QueryInterface(IID_RenderPass, reinterpret_cast(ppRenderPass)); + OnCreateDeviceObject(pRenderPassOGL); + } // + ); } bool RenderDeviceGLImpl::CheckExtension(const Char* ExtensionString) diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp new file mode 100644 index 00000000..2a9d0609 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "RenderPassGLImpl.hpp" +#include "EngineMemory.h" + +namespace Diligent +{ + +RenderPassGLImpl::RenderPassGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDevice, + const RenderPassDesc& Desc) : + TRenderPassBase{pRefCounters, pDevice, Desc} +{ +} + +RenderPassGLImpl::~RenderPassGLImpl() +{ +} + +} // namespace Diligent -- cgit v1.2.3 From 16dd04efc73e4093a991a517f786ebaf03f3f6d1 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 24 Jul 2020 21:18:48 -0700 Subject: Added framebuffer object implementation stubs --- Graphics/GraphicsEngineOpenGL/CMakeLists.txt | 2 + .../include/FramebufferGLImpl.hpp | 54 ++++++++++++++++++++++ .../include/RenderDeviceGLImpl.hpp | 4 ++ .../GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp | 47 +++++++++++++++++++ .../src/RenderDeviceGLImpl.cpp | 15 +++++- 5 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp create mode 100644 Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt index 52251b68..76c51a8c 100644 --- a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt +++ b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt @@ -9,6 +9,7 @@ set(INCLUDE include/DeviceContextGLImpl.hpp include/FBOCache.hpp include/FenceGLImpl.hpp + include/FramebufferGLImpl.hpp include/GLContext.hpp include/GLContextState.hpp include/GLObjectWrapper.hpp @@ -63,6 +64,7 @@ set(SOURCE src/EngineFactoryOpenGL.cpp src/FBOCache.cpp src/FenceGLImpl.cpp + src/FramebufferGLImpl.cpp src/GLContextState.cpp src/GLObjectWrapper.cpp src/GLProgramResourceCache.cpp diff --git a/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp new file mode 100644 index 00000000..8144ffe3 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp @@ -0,0 +1,54 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::FramebufferGLImpl class + +#include "RenderDeviceGL.h" +#include "FramebufferBase.hpp" +#include "RenderDeviceGLImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Render pass implementation in Direct3D11 backend. +class FramebufferGLImpl final : public FramebufferBase +{ +public: + using TFramebufferBase = FramebufferBase; + + FramebufferGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDevice, + const FramebufferDesc& Desc); + ~FramebufferGLImpl(); +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp index 39084c3e..dbdb51c8 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp @@ -117,6 +117,10 @@ public: virtual void DILIGENT_CALL_TYPE CreateRenderPass(const RenderPassDesc& Desc, IRenderPass** ppRenderPass) override final; + /// Implementation of IRenderDevice::CreateFramebuffer() in OpenGL backend. + virtual void DILIGENT_CALL_TYPE CreateFramebuffer(const FramebufferDesc& Desc, + IFramebuffer** ppFramebuffer) override final; + /// Implementation of IRenderDeviceGL::CreateTextureFromGLHandle(). virtual void DILIGENT_CALL_TYPE CreateTextureFromGLHandle(Uint32 GLHandle, Uint32 GLBindTarget, diff --git a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp new file mode 100644 index 00000000..6ec1d1f1 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "pch.h" + +#include "FramebufferGLImpl.hpp" +#include "EngineMemory.h" + +namespace Diligent +{ + +FramebufferGLImpl::FramebufferGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDevice, + const FramebufferDesc& Desc) : + TFramebufferBase{pRefCounters, pDevice, Desc} +{ +} + +FramebufferGLImpl::~FramebufferGLImpl() +{ +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index bc38d364..6506c5df 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -47,6 +47,7 @@ #include "FenceGLImpl.hpp" #include "QueryGLImpl.hpp" #include "RenderPassGLImpl.hpp" +#include "FramebufferGLImpl.hpp" #include "EngineMemory.h" #include "StringTools.hpp" @@ -77,7 +78,8 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters, sizeof(ShaderResourceBindingGLImpl), sizeof(FenceGLImpl), sizeof(QueryGLImpl), - sizeof(RenderPassGLImpl) + sizeof(RenderPassGLImpl), + sizeof(FramebufferGLImpl) } }, // Device caps must be filled in before the constructor of Pipeline Cache is called! @@ -530,6 +532,17 @@ void RenderDeviceGLImpl::CreateRenderPass(const RenderPassDesc& Desc, IRenderPas ); } +void RenderDeviceGLImpl::CreateFramebuffer(const FramebufferDesc& Desc, IFramebuffer** ppFramebuffer) +{ + CreateDeviceObject("Framebuffer", Desc, ppFramebuffer, + [&]() // + { + FramebufferGLImpl* pFramebufferGL(NEW_RC_OBJ(m_FramebufferAllocator, "FramebufferGLImpl instance", FramebufferGLImpl)(this, Desc)); + pFramebufferGL->QueryInterface(IID_Framebuffer, reinterpret_cast(ppFramebuffer)); + OnCreateDeviceObject(pFramebufferGL); + }); +} + bool RenderDeviceGLImpl::CheckExtension(const Char* ExtensionString) { return m_ExtensionStrings.find(ExtensionString) != m_ExtensionStrings.end(); -- cgit v1.2.3 From 8798aa2e94602372a61c362d5c3f288cc07388c9 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 26 Jul 2020 19:16:18 -0700 Subject: Added BeginRenderPass, NextSubpass, and EndRenderPass device context methods --- .../GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp | 9 +++++++++ Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp | 14 ++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp index e80e0d04..8b2651fd 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp @@ -110,6 +110,15 @@ public: ITextureView* pDepthStencil, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + /// Implementation of IDeviceContext::BeginRenderPass() in Direct3D11 backend. + virtual void DILIGENT_CALL_TYPE BeginRenderPass(const BeginRenderPassAttribs& Attribs) override final; + + /// Implementation of IDeviceContext::NextSubpass() in Direct3D11 backend. + virtual void DILIGENT_CALL_TYPE NextSubpass() override final; + + /// Implementation of IDeviceContext::EndRenderPass() in Direct3D11 backend. + virtual void DILIGENT_CALL_TYPE EndRenderPass() override final; + // clang-format off /// Implementation of IDeviceContext::Draw() in OpenGL backend. diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index f6308229..bee081fb 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -403,6 +403,20 @@ void DeviceContextGLImpl::ResetRenderTargets() m_ContextState.InvalidateFBO(); } +void DeviceContextGLImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) +{ + UNEXPECTED("Method not implemented"); +} + +void DeviceContextGLImpl::NextSubpass() +{ + UNEXPECTED("Method not implemented"); +} + +void DeviceContextGLImpl::EndRenderPass() +{ + UNEXPECTED("Method not implemented"); +} void DeviceContextGLImpl::BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding) { -- cgit v1.2.3 From b875435c82aa5efbea55ee17719c4a57b171a811 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 31 Jul 2020 23:31:05 -0700 Subject: Base implementation of BeginRenderPass/NextSubpass/EndRenderPass methods --- Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp | 4 ++++ Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp | 3 +++ 2 files changed, 7 insertions(+) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp index 8b2651fd..ad9ff03b 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp @@ -35,6 +35,8 @@ #include "BufferGLImpl.hpp" #include "TextureBaseGL.hpp" #include "QueryGLImpl.hpp" +#include "FramebufferGLImpl.hpp" +#include "RenderPassGLImpl.hpp" #include "PipelineStateGLImpl.hpp" namespace Diligent @@ -47,6 +49,8 @@ struct DeviceContextGLImplTraits using PipelineStateType = PipelineStateGLImpl; using DeviceType = RenderDeviceGLImpl; using QueryType = QueryGLImpl; + using FramebufferType = FramebufferGLImpl; + using RenderPassType = RenderPassGLImpl; }; /// Device context implementation in OpenGL backend. diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index bee081fb..c585137b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -405,16 +405,19 @@ void DeviceContextGLImpl::ResetRenderTargets() void DeviceContextGLImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) { + TDeviceContextBase::BeginRenderPass(Attribs); UNEXPECTED("Method not implemented"); } void DeviceContextGLImpl::NextSubpass() { + TDeviceContextBase::NextSubpass(); UNEXPECTED("Method not implemented"); } void DeviceContextGLImpl::EndRenderPass() { + TDeviceContextBase::EndRenderPass(); UNEXPECTED("Method not implemented"); } -- cgit v1.2.3 From 812fc38d1b0957ed96d93e023b7322d65c5d3f5d Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 1 Aug 2020 18:18:48 -0700 Subject: Updated EndRenderPass to optionally update resource states --- Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp | 2 +- Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp index ad9ff03b..52b3481b 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp @@ -121,7 +121,7 @@ public: virtual void DILIGENT_CALL_TYPE NextSubpass() override final; /// Implementation of IDeviceContext::EndRenderPass() in Direct3D11 backend. - virtual void DILIGENT_CALL_TYPE EndRenderPass() override final; + virtual void DILIGENT_CALL_TYPE EndRenderPass(bool UpdateResourceStates) override final; // clang-format off diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index c585137b..d1df47e3 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -415,9 +415,9 @@ void DeviceContextGLImpl::NextSubpass() UNEXPECTED("Method not implemented"); } -void DeviceContextGLImpl::EndRenderPass() +void DeviceContextGLImpl::EndRenderPass(bool UpdateResourceStates) { - TDeviceContextBase::EndRenderPass(); + TDeviceContextBase::EndRenderPass(UpdateResourceStates); UNEXPECTED("Method not implemented"); } -- cgit v1.2.3 From 3ce2d21558fa0568ab7d332a5c300a661e444f44 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 4 Aug 2020 19:21:19 -0700 Subject: Added more renderpass-related checks --- Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index d1df47e3..6d353e35 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -147,6 +147,11 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState) void DeviceContextGLImpl::TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) { + if (m_pActiveRenderPass) + { + LOG_ERROR_MESSAGE("State transitions are not allowed inside a render pass."); + return; + } } void DeviceContextGLImpl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) @@ -1037,6 +1042,11 @@ void DeviceContextGLImpl::ClearRenderTarget(ITextureView* pView, const float* RG void DeviceContextGLImpl::Flush() { + if (m_pActiveRenderPass != nullptr) + { + LOG_ERROR_MESSAGE("Flushing device context inside an active render pass."); + } + glFlush(); } @@ -1396,6 +1406,7 @@ void DeviceContextGLImpl::GenerateMips(ITextureView* pTexView) void DeviceContextGLImpl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) { + VERIFY(m_pActiveRenderPass == nullptr, "State transitions are not allowed inside a render pass"); } void DeviceContextGLImpl::ResolveTextureSubresource(ITexture* pSrcTexture, -- cgit v1.2.3 From a72d485f4b157d5c8fb488bc2afb3b9278e465b7 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 6 Aug 2020 20:41:08 -0700 Subject: Treating subpass render target and depth stencil attachments as current RT and DS buffers --- Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 6d353e35..c06c7d3e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -378,6 +378,14 @@ void DeviceContextGLImpl::SetRenderTargets(Uint32 NumRen ITextureView* pDepthStencil, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) { +#ifdef DILIGENT_DEVELOPMENT + if (m_pActiveRenderPass != nullptr) + { + LOG_ERROR_MESSAGE("Calling SetRenderTargets inside active render pass is invalid. End the render pass first"); + return; + } +#endif + if (TDeviceContextBase::SetRenderTargets(NumRenderTargets, ppRenderTargets, pDepthStencil)) { if (m_NumBoundRenderTargets == 1 && m_pBoundRenderTargets[0] && m_pBoundRenderTargets[0]->GetTexture()->GetGLHandle() == 0) -- cgit v1.2.3 From fd6ecbc3e52569119c4e0ff30236bd23f2757737 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 8 Aug 2020 16:48:40 -0700 Subject: Implemented unified render pass attachment state updates within subpasses and after the render pass ends --- Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp | 2 +- Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp index 52b3481b..ad9ff03b 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp @@ -121,7 +121,7 @@ public: virtual void DILIGENT_CALL_TYPE NextSubpass() override final; /// Implementation of IDeviceContext::EndRenderPass() in Direct3D11 backend. - virtual void DILIGENT_CALL_TYPE EndRenderPass(bool UpdateResourceStates) override final; + virtual void DILIGENT_CALL_TYPE EndRenderPass() override final; // clang-format off diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index c06c7d3e..478be058 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -428,9 +428,9 @@ void DeviceContextGLImpl::NextSubpass() UNEXPECTED("Method not implemented"); } -void DeviceContextGLImpl::EndRenderPass(bool UpdateResourceStates) +void DeviceContextGLImpl::EndRenderPass() { - TDeviceContextBase::EndRenderPass(UpdateResourceStates); + TDeviceContextBase::EndRenderPass(); UNEXPECTED("Method not implemented"); } -- cgit v1.2.3 From 80d0d972308444d949eb1c363fb81864143c0762 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 10 Aug 2020 18:45:28 -0700 Subject: Initial implementation of render passes in GL backend --- .../include/DeviceContextGLImpl.hpp | 6 + Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp | 7 +- .../include/FramebufferGLImpl.hpp | 12 ++ .../src/DeviceContextGLImpl.cpp | 54 +++++- Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp | 213 +++++++++++---------- .../GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp | 29 ++- .../src/RenderDeviceGLImpl.cpp | 6 +- 7 files changed, 219 insertions(+), 108 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') 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 + #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 m_BoundWritableTextures; @@ -274,6 +278,8 @@ private: bool m_IsDefaultFBOBound = false; GLObjectWrappers::GLFrameBufferObj m_DefaultFBO; + + std::vector 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 m_TexIdToKey; + std::unordered_multimap 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 + #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 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(); + pColorTexGL->AttachToFramebuffer(RTVDesc, GL_COLOR_ATTACHMENT0 + rt); + } + } + + if (pDSV != nullptr) + { + const auto& DSVDesc = pDSV->GetDesc(); + auto* pDepthTexGL = pDSV->GetTexture(); + 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(); - pColorTexGL->AttachToFramebuffer(RTVDesc, GL_COLOR_ATTACHMENT0 + rt); - } - } - - if (pDSV != nullptr) - { - const auto& DSVDesc = pDSV->GetDesc(); - auto* pDepthTexGL = pDSV->GetTexture(); - 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(m_Desc.ppAttachments[RTAttachmentRef.AttachmentIndex]); + } + } + + if (SubpassDesc.pDepthStencilAttachment != nullptr && SubpassDesc.pDepthStencilAttachment->AttachmentIndex != ATTACHMENT_UNUSED) + { + pDSV = ValidatedCast(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()->GetContextState(); + + FramebufferGLImpl* pFramebufferGL(NEW_RC_OBJ(m_FramebufferAllocator, "FramebufferGLImpl instance", FramebufferGLImpl)(this, GLState, Desc)); pFramebufferGL->QueryInterface(IID_Framebuffer, reinterpret_cast(ppFramebuffer)); OnCreateDeviceObject(pFramebufferGL); }); -- cgit v1.2.3 From 5a7eefa4b133574d28400b0e3cb4d4c415e1bf8e Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 10 Aug 2020 21:26:05 -0700 Subject: Implemented render pass MS resolve in OpenGL --- .../include/DeviceContextGLImpl.hpp | 1 + .../include/FramebufferGLImpl.hpp | 16 +++++++- .../src/DeviceContextGLImpl.cpp | 43 +++++++++++++++++++++- .../GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp | 20 +++++++++- 4 files changed, 74 insertions(+), 6 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') 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 m_SubpassFramebuffers; + std::vector 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()->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(FBODesc.Width), static_cast(FBODesc.Height), + 0, 0, static_cast(FBODesc.Width), static_cast(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(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(m_Desc.ppAttachments[RslvAttachmentRef.AttachmentIndex]); + } + } + ResolveFBO = FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRsvlViews, nullptr); + } + + m_SubpassFramebuffers.emplace_back(std::move(RenderTargetFBO), std::move(ResolveFBO)); } } -- cgit v1.2.3 From 1ecb28239bb09ce028afbe9d8e5254ca5c480e88 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 10 Aug 2020 22:31:08 -0700 Subject: OpenGL backend: enabled handling of default framebuffer in render passes --- .../src/DeviceContextGLImpl.cpp | 30 ++++++++----- .../GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp | 52 +++++++++++++++++++++- 2 files changed, 70 insertions(+), 12 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 37e4a3f4..3b3122bf 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -424,6 +424,22 @@ void DeviceContextGLImpl::BeginSubpass() VERIFY_EXPR(m_SubpassIndex < RPDesc.SubpassCount); const auto& SubpassDesc = RPDesc.pSubpasses[m_SubpassIndex]; const auto& FBDesc = m_pBoundFramebuffer->GetDesc(); + + const auto& RenderTargetFBO = m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex).RenderTarget; + if (RenderTargetFBO != 0) + { + m_ContextState.BindFBO(RenderTargetFBO); + } + else + { + GLuint DefaultFBOHandle = m_pSwapChain->GetDefaultFBO(); + if (m_DefaultFBO != DefaultFBOHandle) + { + m_DefaultFBO = GLObjectWrappers::GLFrameBufferObj{true, GLObjectWrappers::GLFBOCreateReleaseHelper(DefaultFBOHandle)}; + } + m_ContextState.BindFBO(m_DefaultFBO); + } + for (Uint32 rt = 0; rt < SubpassDesc.RenderTargetAttachmentCount; ++rt) { const auto& RTAttachmentRef = SubpassDesc.pRenderTargetAttachments[rt]; @@ -464,8 +480,8 @@ void DeviceContextGLImpl::EndSubpass() { 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"); + glBindFramebuffer(GL_READ_FRAMEBUFFER, SubpassFBOs.RenderTarget); + DEV_CHECK_GL_ERROR("Failed to bind subpass render target FBO as read framebuffer"); GLuint ResolveDstFBO = SubpassFBOs.Resolve; if (ResolveDstFBO == 0) @@ -481,7 +497,7 @@ void DeviceContextGLImpl::EndSubpass() GL_COLOR_BUFFER_BIT, GL_NEAREST // Filter is ignored ); - DEV_CHECK_GL_ERROR("glBlitFramebuffer() failed when resolving multi-sampled texture"); + DEV_CHECK_GL_ERROR("glBlitFramebuffer() failed when resolving multi-sampled attachments"); } m_ContextState.InvalidateFBO(); } @@ -495,7 +511,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).RenderTarget); + SetViewports(1, nullptr, 0, 0); BeginSubpass(); @@ -504,20 +520,14 @@ void DeviceContextGLImpl::BeginRenderPass(const BeginRenderPassAttribs& Attribs) void DeviceContextGLImpl::NextSubpass() { EndSubpass(); - TDeviceContextBase::NextSubpass(); - - m_ContextState.BindFBO(m_pBoundFramebuffer->GetSubpassFramebuffer(m_SubpassIndex).RenderTarget); - BeginSubpass(); } void DeviceContextGLImpl::EndRenderPass() { EndSubpass(); - TDeviceContextBase::EndRenderPass(); - m_ContextState.InvalidateFBO(); } diff --git a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp index 51abf1ba..c84d9816 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp @@ -34,6 +34,50 @@ namespace Diligent { +static bool UseDefaultFBO(Uint32 NumRenderTargets, + TextureViewGLImpl* ppRTVs[], + TextureViewGLImpl* pDSV) +{ + bool useDefaultFBO = false; + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) + { + if (ppRTVs[rt] != nullptr && ppRTVs[rt]->GetHandle() == 0) + { + if (rt == 0) + { + useDefaultFBO = true; + } + else + { + LOG_ERROR_AND_THROW("In OpenGL, swap chain back buffer can be the only render target in the framebuffer " + "and cannot be combined with any other render target."); + } + } + } + + if (pDSV != nullptr) + { + if (useDefaultFBO && pDSV->GetHandle() != 0) + { + LOG_ERROR_AND_THROW("In OpenGL, swap chain back buffer can only be paired with the default depth-stencil buffer."); + } + + if (pDSV->GetHandle() == 0) + { + if (!useDefaultFBO && NumRenderTargets > 0) + { + LOG_ERROR_AND_THROW("In OpenGL, the swap chain's depth-stencil buffer can only be paired with its back buffer."); + } + else + { + useDefaultFBO = true; + } + } + } + + return useDefaultFBO; +} + FramebufferGLImpl::FramebufferGLImpl(IReferenceCounters* pRefCounters, RenderDeviceGLImpl* pDevice, GLContextState& CtxState, @@ -62,7 +106,9 @@ FramebufferGLImpl::FramebufferGLImpl(IReferenceCounters* pRefCounters, { pDSV = ValidatedCast(m_Desc.ppAttachments[SubpassDesc.pDepthStencilAttachment->AttachmentIndex]); } - auto RenderTargetFBO = FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRTVs, pDSV); + auto RenderTargetFBO = UseDefaultFBO(SubpassDesc.RenderTargetAttachmentCount, ppRTVs, pDSV) ? + GLObjectWrappers::GLFrameBufferObj{false} : + FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRTVs, pDSV); GLObjectWrappers::GLFrameBufferObj ResolveFBO{false}; if (SubpassDesc.pResolveAttachments != nullptr) @@ -76,7 +122,9 @@ FramebufferGLImpl::FramebufferGLImpl(IReferenceCounters* pRefCounters, ppRsvlViews[rt] = ValidatedCast(m_Desc.ppAttachments[RslvAttachmentRef.AttachmentIndex]); } } - ResolveFBO = FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRsvlViews, nullptr); + ResolveFBO = UseDefaultFBO(SubpassDesc.RenderTargetAttachmentCount, ppRsvlViews, nullptr) ? + GLObjectWrappers::GLFrameBufferObj{false} : + FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRsvlViews, nullptr); } m_SubpassFramebuffers.emplace_back(std::move(RenderTargetFBO), std::move(ResolveFBO)); -- cgit v1.2.3 From 9a1c196f3dd5d14a3a8c101ea96d26e41bb0507e Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 10 Aug 2020 22:51:05 -0700 Subject: OpenGL backend: enabled copying textures to default framebuffer --- Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp index 06e49cd6..86b5ef40 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp @@ -579,7 +579,10 @@ void TextureBaseGL::CopyData(DeviceContextGLImpl* pDeviceCtxGL, } #if GL_ARB_copy_image - if (glCopyImageSubData) + const bool IsDefaultBackBuffer = GetGLHandle() == 0; + // We can't use glCopyImageSubData with the proxy texture of a default framebuffer + // because we don't have the texture handle. Resort to quad rendering in this case. + if (glCopyImageSubData && !IsDefaultBackBuffer) { GLint SrcSliceY = (SrcTexDesc.Type == RESOURCE_DIM_TEX_1D_ARRAY) ? SrcSlice : 0; GLint SrcSliceZ = (SrcTexDesc.Type == RESOURCE_DIM_TEX_2D_ARRAY) ? SrcSlice : 0; -- cgit v1.2.3 From e70a221012b367b17d5723df0ab01834a221e544 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 10 Aug 2020 23:45:43 -0700 Subject: OpenGL backend: added required memory barriers for framebuffer attachments --- .../src/DeviceContextGLImpl.cpp | 38 +++++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 3b3122bf..4650e9de 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -445,26 +445,46 @@ void DeviceContextGLImpl::BeginSubpass() const auto& RTAttachmentRef = SubpassDesc.pRenderTargetAttachments[rt]; if (RTAttachmentRef.AttachmentIndex != ATTACHMENT_UNUSED) { + auto* const pRTV = ValidatedCast(FBDesc.ppAttachments[RTAttachmentRef.AttachmentIndex]); + if (pRTV == nullptr) + continue; + + auto* const pColorTexGL = pRTV->GetTexture(); + pColorTexGL->TextureMemoryBarrier( + GL_FRAMEBUFFER_BARRIER_BIT, // Reads and writes via framebuffer object attachments after the + // barrier will reflect data written by shaders prior to the barrier. + // Additionally, framebuffer writes issued after the barrier will wait + // on the completion of all shader writes issued prior to the barrier. + m_ContextState); + 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) + if (SubpassDesc.pDepthStencilAttachment != nullptr) { - 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) + const auto DepthAttachmentIndex = SubpassDesc.pDepthStencilAttachment->AttachmentIndex; + if (DepthAttachmentIndex != ATTACHMENT_UNUSED) { - 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); + auto* const pDSV = ValidatedCast(FBDesc.ppAttachments[DepthAttachmentIndex]); + if (pDSV != nullptr) + { + auto* pDepthTexGL = pDSV->GetTexture(); + pDepthTexGL->TextureMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT, m_ContextState); + + const auto& AttachmentDesc = RPDesc.pAttachments[DepthAttachmentIndex]; + auto FirstLastUse = m_pActiveRenderPass->GetAttachmentFirstLastUse(DepthAttachmentIndex); + if (FirstLastUse.first == m_SubpassIndex && AttachmentDesc.LoadOp == ATTACHMENT_LOAD_OP_CLEAR) + { + const auto& ClearVal = m_AttachmentClearValues[DepthAttachmentIndex].DepthStencil; + ClearDepthStencil(pDSV, CLEAR_DEPTH_FLAG | CLEAR_STENCIL_FLAG, ClearVal.Depth, ClearVal.Stencil, RESOURCE_STATE_TRANSITION_MODE_NONE); + } + } } } } -- cgit v1.2.3 From 9526f305abcfd14ce186a94cd70a6ea1352b1786 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 15 Aug 2020 12:23:56 -0700 Subject: GL backend: a number of minor updates --- .../src/DeviceContextGLImpl.cpp | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 4650e9de..8b10e196 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -255,10 +255,10 @@ void DeviceContextGLImpl::SetViewports(Uint32 NumViewports, const Viewport* pVie // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glViewportIndexed.xhtml glViewportIndexedf(0, BottomLeftX, BottomLeftY, vp.Width, vp.Height); } - CHECK_GL_ERROR("Failed to set viewport"); + DEV_CHECK_GL_ERROR("Failed to set viewport"); glDepthRangef(vp.MinDepth, vp.MaxDepth); - CHECK_GL_ERROR("Failed to set depth range"); + DEV_CHECK_GL_ERROR("Failed to set depth range"); } else { @@ -268,9 +268,9 @@ void DeviceContextGLImpl::SetViewports(Uint32 NumViewports, const Viewport* pVie float BottomLeftY = static_cast(RTHeight) - (vp.TopLeftY + vp.Height); float BottomLeftX = vp.TopLeftX; glViewportIndexedf(i, BottomLeftX, BottomLeftY, vp.Width, vp.Height); - CHECK_GL_ERROR("Failed to set viewport #", i); + DEV_CHECK_GL_ERROR("Failed to set viewport #", i); glDepthRangef(vp.MinDepth, vp.MaxDepth); - CHECK_GL_ERROR("Failed to set depth range for viewport #", i); + DEV_CHECK_GL_ERROR("Failed to set depth range for viewport #", i); } } } @@ -301,7 +301,7 @@ void DeviceContextGLImpl::SetScissorRects(Uint32 NumRects, const Rect* pRects, U auto width = Rect.right - Rect.left; auto height = Rect.bottom - Rect.top; glScissor(Rect.left, glBottom, width, height); - CHECK_GL_ERROR("Failed to set scissor rect"); + DEV_CHECK_GL_ERROR("Failed to set scissor rect"); } else { @@ -312,7 +312,7 @@ void DeviceContextGLImpl::SetScissorRects(Uint32 NumRects, const Rect* pRects, U auto width = Rect.right - Rect.left; auto height = Rect.bottom - Rect.top; glScissorIndexed(sr, Rect.left, glBottom, width, height); - CHECK_GL_ERROR("Failed to set scissor rect #", sr); + DEV_CHECK_GL_ERROR("Failed to set scissor rect #", sr); } } } @@ -324,6 +324,8 @@ void DeviceContextGLImpl::SetSwapChain(ISwapChainGL* pSwapChain) void DeviceContextGLImpl::CommitRenderTargets() { + VERIFY(m_pActiveRenderPass == nullptr, "This method must not be called inside render pass"); + if (!m_IsDefaultFBOBound && m_NumBoundRenderTargets == 0 && !m_pBoundDepthStencil) return; @@ -332,7 +334,7 @@ void DeviceContextGLImpl::CommitRenderTargets() GLuint DefaultFBOHandle = m_pSwapChain->GetDefaultFBO(); if (m_DefaultFBO != DefaultFBOHandle) { - m_DefaultFBO = GLObjectWrappers::GLFrameBufferObj(true, GLObjectWrappers::GLFBOCreateReleaseHelper(DefaultFBOHandle)); + m_DefaultFBO = GLObjectWrappers::GLFrameBufferObj{true, GLObjectWrappers::GLFBOCreateReleaseHelper(DefaultFBOHandle)}; } m_ContextState.BindFBO(m_DefaultFBO); } @@ -671,7 +673,7 @@ void DeviceContextGLImpl::BindProgramResources(Uint32& NewMemoryBarriers, IShade m_ContextState.BindTexture(-1, pTexViewGL->GetBindTarget(), pTexViewGL->GetHandle()); GLint IsImmutable = 0; glGetTexParameteriv(pTexViewGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable); - CHECK_GL_ERROR("glGetTexParameteriv() failed"); + DEV_CHECK_GL_ERROR("glGetTexParameteriv() failed"); VERIFY(IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()"); m_ContextState.BindTexture(-1, pTexViewGL->GetBindTarget(), GLObjectWrappers::GLTextureObj::Null()); } @@ -1030,7 +1032,7 @@ void DeviceContextGLImpl::DispatchCompute(const DispatchComputeAttribs& Attribs) #if GL_ARB_compute_shader m_pPipelineState->CommitProgram(m_ContextState); glDispatchCompute(Attribs.ThreadGroupCountX, Attribs.ThreadGroupCountY, Attribs.ThreadGroupCountZ); - CHECK_GL_ERROR("glDispatchCompute() failed"); + DEV_CHECK_GL_ERROR("glDispatchCompute() failed"); PostDraw(); #else @@ -1057,10 +1059,10 @@ void DeviceContextGLImpl::DispatchComputeIndirect(const DispatchComputeIndirectA constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, pBufferGL->m_GlBuffer, ResetVAO); - CHECK_GL_ERROR("Failed to bind a buffer for dispatch indirect command"); + DEV_CHECK_GL_ERROR("Failed to bind a buffer for dispatch indirect command"); glDispatchComputeIndirect(Attribs.DispatchArgsByteOffset); - CHECK_GL_ERROR("glDispatchComputeIndirect() failed"); + DEV_CHECK_GL_ERROR("glDispatchComputeIndirect() failed"); m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); @@ -1106,7 +1108,7 @@ void DeviceContextGLImpl::ClearDepthStencil(ITextureView* pView // blend function, logical operation, stenciling, texture mapping, and depth-buffering // are ignored by glClear. glClear(glClearFlags); - CHECK_GL_ERROR("glClear() failed"); + DEV_CHECK_GL_ERROR("glClear() failed"); m_ContextState.EnableDepthWrites(DepthWritesEnabled); m_ContextState.EnableScissorTest(ScissorTestEnabled); } @@ -1119,8 +1121,6 @@ void DeviceContextGLImpl::ClearRenderTarget(ITextureView* pView, const float* RG VERIFY_EXPR(pView != nullptr); Int32 RTIndex = -1; - VERIFY(pView->GetDesc().ViewType == TEXTURE_VIEW_RENDER_TARGET, "Incorrect view type: render target is expected"); - CHECK_DYNAMIC_TYPE(TextureViewGLImpl, pView); for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt) { if (m_pBoundRenderTargets[rt] == pView) @@ -1159,7 +1159,7 @@ void DeviceContextGLImpl::ClearRenderTarget(ITextureView* pView, const float* RG m_ContextState.SetColorWriteMask(RTIndex, COLOR_MASK_ALL, bIndependentBlend); glClearBufferfv(GL_COLOR, RTIndex, RGBA); - CHECK_GL_ERROR("glClearBufferfv() failed"); + DEV_CHECK_GL_ERROR("glClearBufferfv() failed"); m_ContextState.SetColorWriteMask(RTIndex, WriteMask, bIndependentBlend); m_ContextState.EnableScissorTest(ScissorTestEnabled); @@ -1196,7 +1196,7 @@ void DeviceContextGLImpl::SignalFence(IFence* pFence, Uint64 Value) GL_SYNC_GPU_COMMANDS_COMPLETE, // Condition must always be GL_SYNC_GPU_COMMANDS_COMPLETE 0 // Flags, must be 0 )}; - CHECK_GL_ERROR("Failed to create gl fence"); + DEV_CHECK_GL_ERROR("Failed to create gl fence"); auto* pFenceGLImpl = ValidatedCast(pFence); pFenceGLImpl->AddPendingFence(std::move(GLFence), Value); } @@ -1229,7 +1229,7 @@ void DeviceContextGLImpl::BeginQuery(IQuery* pQuery) case QUERY_TYPE_OCCLUSION: #if GL_SAMPLES_PASSED glBeginQuery(GL_SAMPLES_PASSED, glQuery); - CHECK_GL_ERROR("Failed to begin GL_SAMPLES_PASSED query"); + DEV_CHECK_GL_ERROR("Failed to begin GL_SAMPLES_PASSED query"); #else LOG_ERROR_MESSAGE_ONCE("GL_SAMPLES_PASSED query is not supported by this device"); #endif @@ -1237,13 +1237,13 @@ void DeviceContextGLImpl::BeginQuery(IQuery* pQuery) case QUERY_TYPE_BINARY_OCCLUSION: glBeginQuery(GL_ANY_SAMPLES_PASSED, glQuery); - CHECK_GL_ERROR("Failed to begin GL_ANY_SAMPLES_PASSED query"); + DEV_CHECK_GL_ERROR("Failed to begin GL_ANY_SAMPLES_PASSED query"); break; case QUERY_TYPE_PIPELINE_STATISTICS: #if GL_PRIMITIVES_GENERATED glBeginQuery(GL_PRIMITIVES_GENERATED, glQuery); - CHECK_GL_ERROR("Failed to begin GL_PRIMITIVES_GENERATED query"); + DEV_CHECK_GL_ERROR("Failed to begin GL_PRIMITIVES_GENERATED query"); #else LOG_ERROR_MESSAGE_ONCE("GL_PRIMITIVES_GENERATED query is not supported by this device"); #endif @@ -1266,26 +1266,26 @@ void DeviceContextGLImpl::EndQuery(IQuery* pQuery) case QUERY_TYPE_OCCLUSION: #if GL_SAMPLES_PASSED glEndQuery(GL_SAMPLES_PASSED); - CHECK_GL_ERROR("Failed to end GL_SAMPLES_PASSED query"); + DEV_CHECK_GL_ERROR("Failed to end GL_SAMPLES_PASSED query"); #endif break; case QUERY_TYPE_BINARY_OCCLUSION: glEndQuery(GL_ANY_SAMPLES_PASSED); - CHECK_GL_ERROR("Failed to end GL_ANY_SAMPLES_PASSED query"); + DEV_CHECK_GL_ERROR("Failed to end GL_ANY_SAMPLES_PASSED query"); break; case QUERY_TYPE_PIPELINE_STATISTICS: #if GL_PRIMITIVES_GENERATED glEndQuery(GL_PRIMITIVES_GENERATED); - CHECK_GL_ERROR("Failed to end GL_PRIMITIVES_GENERATED query"); + DEV_CHECK_GL_ERROR("Failed to end GL_PRIMITIVES_GENERATED query"); #endif break; case QUERY_TYPE_TIMESTAMP: #if GL_ARB_timer_query glQueryCounter(pQueryGLImpl->GetGlQueryHandle(), GL_TIMESTAMP); - CHECK_GL_ERROR("glQueryCounter failed"); + DEV_CHECK_GL_ERROR("glQueryCounter failed"); #else LOG_ERROR_MESSAGE_ONCE("Timer queries are not supported by this device"); #endif @@ -1525,7 +1525,7 @@ void DeviceContextGLImpl::GenerateMips(ITextureView* pTexView) auto BindTarget = pTexViewGL->GetBindTarget(); m_ContextState.BindTexture(-1, BindTarget, pTexViewGL->GetHandle()); glGenerateMipmap(BindTarget); - CHECK_GL_ERROR("Failed to generate mip maps"); + DEV_CHECK_GL_ERROR("Failed to generate mip maps"); m_ContextState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj::Null()); } -- cgit v1.2.3