From be8197db1cd99a33882ced645bf988c188ded594 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 7 Mar 2021 18:12:24 -0800 Subject: OpenGL backend: reorganized headers, removed signature methods implemented by the base class --- Graphics/GraphicsEngineOpenGL/CMakeLists.txt | 5 +- .../GraphicsEngineOpenGL/include/BufferGLImpl.hpp | 9 +- .../include/BufferViewGLImpl.hpp | 5 +- .../include/DeviceContextGLImpl.hpp | 14 +- .../GraphicsEngineOpenGL/include/FenceGLImpl.hpp | 3 +- .../include/FramebufferGLImpl.hpp | 5 +- .../include/PipelineResourceAttribsGL.hpp | 82 +++ .../include/PipelineResourceSignatureGLImpl.hpp | 70 +-- .../include/PipelineStateGLImpl.hpp | 11 +- .../GraphicsEngineOpenGL/include/QueryGLImpl.hpp | 3 +- .../include/RenderPassGLImpl.hpp | 3 +- .../GraphicsEngineOpenGL/include/SamplerGLImpl.hpp | 4 +- .../GraphicsEngineOpenGL/include/ShaderGLImpl.hpp | 4 +- .../include/ShaderResourceBindingGLImpl.hpp | 9 +- .../include/ShaderVariableGL.hpp | 486 -------------- .../include/ShaderVariableManagerGL.hpp | 481 ++++++++++++++ .../GraphicsEngineOpenGL/include/TextureBaseGL.hpp | 6 +- .../include/TextureViewGLImpl.hpp | 6 +- Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp | 2 +- Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp | 5 +- .../GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp | 8 +- .../src/DeviceContextGLImpl.cpp | 14 +- Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp | 1 + .../GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp | 4 +- .../GraphicsEngineOpenGL/src/GLContextState.cpp | 6 +- .../src/PipelineResourceSignatureGLImpl.cpp | 30 - .../src/PipelineStateGLImpl.cpp | 5 +- Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp | 1 + .../src/RenderDeviceGLImpl.cpp | 5 +- .../GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp | 1 + Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp | 3 +- .../src/ShaderResourceBindingGLImpl.cpp | 5 + .../src/ShaderResourceCacheGL.cpp | 1 + .../GraphicsEngineOpenGL/src/ShaderResourcesGL.cpp | 8 +- .../GraphicsEngineOpenGL/src/ShaderVariableGL.cpp | 682 -------------------- .../src/ShaderVariableManagerGL.cpp | 698 +++++++++++++++++++++ .../GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp | 5 +- .../src/Texture1DArray_OGL.cpp | 2 +- .../GraphicsEngineOpenGL/src/Texture1D_OGL.cpp | 2 +- .../src/Texture2DArray_OGL.cpp | 2 +- .../GraphicsEngineOpenGL/src/Texture2D_OGL.cpp | 2 +- .../GraphicsEngineOpenGL/src/Texture3D_OGL.cpp | 2 +- .../GraphicsEngineOpenGL/src/TextureBaseGL.cpp | 7 +- .../src/TextureCubeArray_OGL.cpp | 5 +- .../GraphicsEngineOpenGL/src/TextureCube_OGL.cpp | 4 +- Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp | 6 +- 46 files changed, 1383 insertions(+), 1339 deletions(-) create mode 100644 Graphics/GraphicsEngineOpenGL/include/PipelineResourceAttribsGL.hpp delete mode 100644 Graphics/GraphicsEngineOpenGL/include/ShaderVariableGL.hpp create mode 100644 Graphics/GraphicsEngineOpenGL/include/ShaderVariableManagerGL.hpp delete mode 100644 Graphics/GraphicsEngineOpenGL/src/ShaderVariableGL.cpp create mode 100644 Graphics/GraphicsEngineOpenGL/src/ShaderVariableManagerGL.cpp (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt index d2853156..f9c10846 100644 --- a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt +++ b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt @@ -15,12 +15,13 @@ set(INCLUDE include/GLContextState.hpp include/GLObjectWrapper.hpp include/ShaderResourceCacheGL.hpp - include/ShaderVariableGL.hpp + include/ShaderVariableManagerGL.hpp include/ShaderResourcesGL.hpp include/GLTypeConversions.hpp include/pch.h include/PipelineStateGLImpl.hpp include/PipelineResourceSignatureGLImpl.hpp + include/PipelineResourceAttribsGL.hpp include/QueryGLImpl.hpp include/RenderDeviceGLImpl.hpp include/RenderPassGLImpl.hpp @@ -70,7 +71,7 @@ set(SOURCE src/GLContextState.cpp src/GLObjectWrapper.cpp src/ShaderResourceCacheGL.cpp - src/ShaderVariableGL.cpp + src/ShaderVariableManagerGL.cpp src/ShaderResourcesGL.cpp src/GLTypeConversions.cpp src/PipelineStateGLImpl.cpp diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp index b4a27125..8620c28a 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.hpp @@ -27,13 +27,12 @@ #pragma once +#include "EngineGLImplTraits.hpp" #include "BufferGL.h" #include "BufferBase.hpp" +#include "BufferViewGLImpl.hpp" // Required by BufferBase #include "GLObjectWrapper.hpp" #include "AsyncWritableResource.hpp" -#include "BaseInterfacesGL.h" -#include "BufferViewGLImpl.hpp" -#include "RenderDeviceGLImpl.hpp" #include "GLContextState.hpp" namespace Diligent @@ -96,7 +95,7 @@ private: const GLenum m_GLUsageHint; }; -void BufferGLImpl::BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLContextState) +void BufferGLImpl::BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLState) { #if GL_ARB_shader_image_load_store # ifdef DILIGENT_DEBUG @@ -107,7 +106,7 @@ void BufferGLImpl::BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContex } # endif - GLContextState.EnsureMemoryBarrier(RequiredBarriers, this); + GLState.EnsureMemoryBarrier(RequiredBarriers, this); #endif } diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.hpp index a61e7e6d..1080a268 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.hpp @@ -27,11 +27,10 @@ #pragma once +#include "EngineGLImplTraits.hpp" #include "BufferViewGL.h" -#include "BaseInterfacesGL.h" #include "BufferViewBase.hpp" #include "GLObjectWrapper.hpp" -#include "RenderDeviceGLImpl.hpp" namespace Diligent { @@ -49,6 +48,8 @@ public: BufferGLImpl* pBuffer, bool bIsDefaultView); + ~BufferViewGLImpl(); + /// Queries the specific interface, see IObject::QueryInterface() for details virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp index 79ea1926..867179af 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp @@ -29,24 +29,28 @@ #include +#include "EngineGLImplTraits.hpp" #include "DeviceContextGL.h" #include "DeviceContextBase.hpp" -#include "BaseInterfacesGL.h" -#include "GLContextState.hpp" -#include "GLObjectWrapper.hpp" + +// GL object implementations are required by DeviceContextBase #include "BufferGLImpl.hpp" #include "TextureBaseGL.hpp" #include "QueryGLImpl.hpp" #include "FramebufferGLImpl.hpp" #include "RenderPassGLImpl.hpp" #include "PipelineStateGLImpl.hpp" -#include "BottomLevelASBase.hpp" -#include "TopLevelASBase.hpp" #include "ShaderResourceBindingGLImpl.hpp" +#include "GLContextState.hpp" +#include "GLObjectWrapper.hpp" + namespace Diligent { +class TextureBaseGL; +class ShaderResourceBindingGLImpl; + /// Device context implementation in OpenGL backend. class DeviceContextGLImpl final : public DeviceContextBase { diff --git a/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.hpp index bd2a78a4..d0095402 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.hpp @@ -33,11 +33,10 @@ #include #include +#include "EngineGLImplTraits.hpp" #include "FenceGL.h" -#include "RenderDeviceGL.h" #include "FenceBase.hpp" #include "GLObjectWrapper.hpp" -#include "RenderDeviceGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp index 67ddc685..83775c2f 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/FramebufferGLImpl.hpp @@ -32,14 +32,15 @@ #include -#include "RenderDeviceGL.h" +#include "EngineGLImplTraits.hpp" #include "FramebufferBase.hpp" -#include "RenderDeviceGLImpl.hpp" #include "GLObjectWrapper.hpp" namespace Diligent { +class GLContextState; + /// Framebuffer implementation in OpenGL backend. class FramebufferGLImpl final : public FramebufferBase { diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineResourceAttribsGL.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineResourceAttribsGL.hpp new file mode 100644 index 00000000..9130f0fa --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineResourceAttribsGL.hpp @@ -0,0 +1,82 @@ +/* + * Copyright 2019-2021 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::PipelineResourceAttribsGL struct + +#include "BasicTypes.h" +#include "DebugUtilities.hpp" + +namespace Diligent +{ + +// sizeof(PipelineResourceAttribsGL) == 8, x64 +struct PipelineResourceAttribsGL +{ +private: + static constexpr Uint32 _SamplerIndBits = 31; + static constexpr Uint32 _SamplerAssignedBits = 1; + +public: + static constexpr Uint32 InvalidCacheOffset = ~0u; + static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1; + + // clang-format off + const Uint32 CacheOffset; // SRB and Signature use the same cache offsets for static resources. + // Binding == BaseBinding[Range] + CacheOffset + const Uint32 SamplerInd : _SamplerIndBits; // ImtblSamplerAssigned == true: index of the immutable sampler in m_ImmutableSamplers. + // ImtblSamplerAssigned == false: index of the assigned sampler in m_Desc.Resources. + const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag + // clang-format on + + PipelineResourceAttribsGL(Uint32 _CacheOffset, + Uint32 _SamplerInd, + bool _ImtblSamplerAssigned) noexcept : + // clang-format off + CacheOffset {_CacheOffset }, + SamplerInd {_SamplerInd }, + ImtblSamplerAssigned{_ImtblSamplerAssigned ? 1u : 0u} + // clang-format on + { + VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value"); + VERIFY(!_ImtblSamplerAssigned || SamplerInd != InvalidSamplerInd, "Immutable sampler is assigned, but sampler index is not valid"); + } + + bool IsSamplerAssigned() const + { + return SamplerInd != InvalidSamplerInd; + } + + bool IsImmutableSamplerAssigned() const + { + return ImtblSamplerAssigned != 0; + } +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp index 9c37301f..c96e627f 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineResourceSignatureGLImpl.hpp @@ -32,16 +32,22 @@ #include +#include "EngineGLImplTraits.hpp" +#include "PipelineResourceAttribsGL.hpp" #include "PipelineResourceSignatureBase.hpp" -#include "ShaderResourceCacheGL.hpp" #include "ShaderResourcesGL.hpp" #include "SRBMemoryAllocator.hpp" +// ShaderVariableManagerGL, ShaderResourceCacheGL, and ShaderResourceBindingGLImpl +// are required by PipelineResourceSignatureBase +#include "ShaderResourceCacheGL.hpp" +#include "ShaderVariableManagerGL.hpp" +#include "ShaderResourceBindingGLImpl.hpp" + namespace Diligent { class RenderDeviceGLImpl; -class ShaderVariableManagerGL; enum BINDING_RANGE : Uint32 { @@ -68,41 +74,7 @@ public: bool bIsDeviceInternal = false); ~PipelineResourceSignatureGLImpl(); - // sizeof(ResourceAttribs) == 8, x64 - struct ResourceAttribs - { - private: - static constexpr Uint32 _SamplerIndBits = 31; - static constexpr Uint32 _SamplerAssignedBits = 1; - - public: - static constexpr Uint32 InvalidCacheOffset = ~0u; - static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1; - - // clang-format off - const Uint32 CacheOffset; // SRB and Signature use the same cache offsets for static resources. - // Binding == BaseBinding[Range] + CacheOffset - const Uint32 SamplerInd : _SamplerIndBits; // ImtblSamplerAssigned == true: index of the immutable sampler in m_ImmutableSamplers. - // ImtblSamplerAssigned == false: index of the assigned sampler in m_Desc.Resources. - const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag - // clang-format on - - ResourceAttribs(Uint32 _CacheOffset, - Uint32 _SamplerInd, - bool _ImtblSamplerAssigned) noexcept : - // clang-format off - CacheOffset {_CacheOffset }, - SamplerInd {_SamplerInd }, - ImtblSamplerAssigned{_ImtblSamplerAssigned ? 1u : 0u} - // clang-format on - { - VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value"); - VERIFY(!_ImtblSamplerAssigned || SamplerInd != InvalidSamplerInd, "Immutable sampler is assigned, but sampler index is not valid"); - } - - bool IsSamplerAssigned() const { return SamplerInd != InvalidSamplerInd; } - bool IsImmutableSamplerAssigned() const { return ImtblSamplerAssigned != 0; } - }; + using ResourceAttribs = PipelineResourceAttribsGL; const ResourceAttribs& GetResourceAttribs(Uint32 ResIndex) const { @@ -110,12 +82,6 @@ public: return m_pResourceAttribs[ResIndex]; } - bool HasDynamicResources() const - { - const auto IndexRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC); - return IndexRange.second > IndexRange.first; - } - using TBindings = std::array; // Applies bindings for resources in this signature to GLProgram. @@ -133,24 +99,6 @@ public: } } - /// Implementation of IPipelineResourceSignature::CreateShaderResourceBinding. - virtual void DILIGENT_CALL_TYPE CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, - bool InitStaticResources) override final; - - /// Implementation of IPipelineResourceSignature::GetStaticVariableByName. - virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name) override final; - - /// Implementation of IPipelineResourceSignature::GetStaticVariableByIndex. - virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; - - /// Implementation of IPipelineResourceSignature::GetStaticVariableCount. - virtual Uint32 DILIGENT_CALL_TYPE GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; - - /// Implementation of IPipelineResourceSignature::BindStaticResources. - virtual void DILIGENT_CALL_TYPE BindStaticResources(Uint32 ShaderFlags, - IResourceMapping* pResourceMapping, - Uint32 Flags) override final; - /// Implementation of IPipelineResourceSignature::IsCompatibleWith. virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineResourceSignature* pPRS) const override final { diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp index 37fef0ba..ded87435 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp @@ -28,15 +28,16 @@ #pragma once #include + +#include "EngineGLImplTraits.hpp" #include "PipelineStateGL.h" #include "PipelineStateBase.hpp" -#include "RenderDevice.h" + +#include "PipelineResourceSignatureGLImpl.hpp" // Requiured by PipelineStateBase +#include "ShaderGLImpl.hpp" + #include "GLObjectWrapper.hpp" #include "GLContext.hpp" -#include "RenderDeviceGLImpl.hpp" -#include "ShaderVariableGL.hpp" -#include "ShaderGLImpl.hpp" -#include "PipelineResourceSignatureGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.hpp index b5a95fad..a4b8959b 100644 --- a/Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/QueryGLImpl.hpp @@ -30,11 +30,10 @@ /// \file /// Declaration of Diligent::QueryGLImpl class +#include "EngineGLImplTraits.hpp" #include "QueryGL.h" -#include "RenderDeviceGL.h" #include "QueryBase.hpp" #include "GLObjectWrapper.hpp" -#include "RenderDeviceGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderPassGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderPassGLImpl.hpp index f307ae15..cbfea449 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderPassGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/RenderPassGLImpl.hpp @@ -30,9 +30,8 @@ /// \file /// Declaration of Diligent::RenderPassGLImpl class -#include "RenderDeviceGL.h" +#include "EngineGLImplTraits.hpp" #include "RenderPassBase.hpp" -#include "RenderDeviceGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.hpp index 3dcc95e7..02d3ce8a 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.hpp @@ -27,12 +27,10 @@ #pragma once -#include "BaseInterfacesGL.h" +#include "EngineGLImplTraits.hpp" #include "SamplerGL.h" #include "SamplerBase.hpp" -#include "RenderDevice.h" #include "GLObjectWrapper.hpp" -#include "RenderDeviceGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp index 31c4686b..487bf2d8 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.hpp @@ -27,12 +27,10 @@ #pragma once -#include "BaseInterfacesGL.h" +#include "EngineGLImplTraits.hpp" #include "ShaderGL.h" #include "ShaderBase.hpp" -#include "RenderDevice.h" #include "GLObjectWrapper.hpp" -#include "RenderDeviceGLImpl.hpp" #include "ShaderResourcesGL.hpp" namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.hpp index 5c585383..1e5c5753 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.hpp @@ -30,17 +30,20 @@ /// \file /// Declaration of Diligent::ShaderResourceBindingGLImpl class +#include "EngineGLImplTraits.hpp" #include "ShaderResourceBindingGL.h" -#include "RenderDeviceGL.h" #include "ShaderResourceBindingBase.hpp" #include "ShaderResourcesGL.hpp" + +// ShaderResourceCacheGL and ShaderVariableManagerGL are required by ShaderResourceBindingBase #include "ShaderResourceCacheGL.hpp" -#include "ShaderVariableGL.hpp" -#include "PipelineResourceSignatureGLImpl.hpp" +#include "ShaderVariableManagerGL.hpp" namespace Diligent { +class PipelineResourceSignatureGLImpl; + /// Shader resource binding object implementation in OpenGL backend. class ShaderResourceBindingGLImpl final : public ShaderResourceBindingBase { diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderVariableGL.hpp b/Graphics/GraphicsEngineOpenGL/include/ShaderVariableGL.hpp deleted file mode 100644 index 944977a5..00000000 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderVariableGL.hpp +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright 2019-2021 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 - -// ShaderVariableManagerGL class manages resource bindings for all stages in a pipeline - -// -// -// To program resource cache -// -// A A A A A A A A -// | | | | | | | | -// Binding Binding Binding Binding Binding Binding Binding Binding -// ___________________ ____|__________|__________________|________|______________|___________|______________|____________|____________ -// | | | | | | | | | | | | | | | -// | ShaderResourcesGL |--------------->| UB[0] | UB[1] | ... | Sam[0] | Sam[1] | ... | Img[0] | Img[1] | ... | SSBOs[0] | SSBOs[1] | ... | -// |___________________| |__________|__________|_______|________|________|_______|________|________|_______|__________|__________|_______| -// A A A A -// | | | | -// Ref Ref Ref Ref -// .-==========================-. _____|____________________________________|________________________|____________________________|______________ -// || || | | | | | | | | | | | -// __|| ShaderVariableManagerGL ||------->| UBInfo[0] | UBInfo[1] | ... | SamInfo[0] | SamInfo[1] | ... | ImgInfo[0] | ... | SSBO[0] | ... | -// | || || |___________|___________|_______|____________|____________|_______|____________|_________|___________|__________| -// | '-==========================-' / \ -// | Ref Ref -// | / \ -// | ___________________ ________V________________________________________________V_____________________________________________________ -// | | | | | | | | | | | | | | | | -// | | ShaderResourcesGL |--------------->| UB[0] | UB[1] | ... | Sam[0] | Sam[1] | ... | Img[0] | Img[1] | ... | SSBOs[0] | SSBOs[1] | ... | -// | |___________________| |__________|__________|_______|________|________|_______|________|________|_______|__________|__________|_______| -// | | | | | | | | | -// | Binding Binding Binding Binding Binding Binding Binding Binding -// | | | | | | | | | -// | _______________________ ____V___________V________________V_________V________________V________V________________V___________V_____________ -// | | | | | | | | -// '-->| ShaderResourceCacheGL |----------->| Uinform Buffers | Textures | Images | Storge Buffers | -// |_______________________| |___________________________|___________________________|___________________________|___________________________| -// -// -// Note that ShaderResourcesGL are kept by PipelineStateGLImpl. ShaderVariableManagerGL class is either part of the same PSO class, -// or part of ShaderResourceBindingGLImpl object that keeps a strong reference to the pipeline. So all references from GLVariableBase -// are always valid. - -#include - -#include "Object.h" -#include "ShaderResourceVariableBase.hpp" -#include "ShaderResourceCacheGL.hpp" -#include "PipelineResourceSignatureGLImpl.hpp" - -namespace Diligent -{ - -// sizeof(ShaderVariableManagerGL) == 48 (x64, msvc, Release) -class ShaderVariableManagerGL -{ -public: - ShaderVariableManagerGL(IObject& Owner, ShaderResourceCacheGL& ResourceCache) noexcept : - m_Owner(Owner), - m_ResourceCache{ResourceCache} - {} - - ~ShaderVariableManagerGL(); - - void Destroy(IMemoryAllocator& Allocator); - - // No copies, only moves are allowed - // clang-format off - ShaderVariableManagerGL (const ShaderVariableManagerGL&) = delete; - ShaderVariableManagerGL& operator = (const ShaderVariableManagerGL&) = delete; - ShaderVariableManagerGL ( ShaderVariableManagerGL&&) = default; - ShaderVariableManagerGL& operator = ( ShaderVariableManagerGL&&) = delete; - // clang-format on - - void Initialize(const PipelineResourceSignatureGLImpl& Signature, - IMemoryAllocator& Allocator, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType); - - static size_t GetRequiredMemorySize(const PipelineResourceSignatureGLImpl& Signature, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType); - - using ResourceAttribs = PipelineResourceSignatureGLImpl::ResourceAttribs; - - const PipelineResourceDesc& GetResourceDesc(Uint32 Index) const - { - VERIFY_EXPR(m_pSignature); - return m_pSignature->GetResourceDesc(Index); - } - const ResourceAttribs& GetAttribs(Uint32 Index) const - { - VERIFY_EXPR(m_pSignature); - return m_pSignature->GetResourceAttribs(Index); - } - - - struct GLVariableBase : public ShaderVariableBase - { - public: - using TBase = ShaderVariableBase; - GLVariableBase(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : - TBase{ParentLayout}, - m_ResIndex{ResIndex} - {} - - const PipelineResourceDesc& GetDesc() const { return m_ParentManager.GetResourceDesc(m_ResIndex); } - const ResourceAttribs& GetAttribs() const { return m_ParentManager.GetAttribs(m_ResIndex); } - - virtual SHADER_RESOURCE_VARIABLE_TYPE DILIGENT_CALL_TYPE GetType() const override final - { - return GetDesc().VarType; - } - - virtual void DILIGENT_CALL_TYPE GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final - { - const auto& Desc = GetDesc(); - ResourceDesc.Name = Desc.Name; - ResourceDesc.Type = Desc.ResourceType; - ResourceDesc.ArraySize = Desc.ArraySize; - } - - virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final - { - return m_ParentManager.GetVariableIndex(*this); - } - - private: - const Uint32 m_ResIndex; - }; - - - struct UniformBuffBindInfo final : GLVariableBase - { - UniformBuffBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : - GLVariableBase{ParentLayout, ResIndex} - {} - - // Non-virtual function - void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); - - virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final - { - BindResource(pObject, 0); - } - - virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, - Uint32 FirstElement, - Uint32 NumElements) override final - { - const auto& Desc = GetDesc(); - VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements); - for (Uint32 elem = 0; elem < NumElements; ++elem) - BindResource(ppObjects[elem], FirstElement + elem); - } - - virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final - { - VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize); - return m_ParentManager.m_ResourceCache.IsUBBound(GetAttribs().CacheOffset + ArrayIndex); - } - }; - - - struct TextureBindInfo final : GLVariableBase - { - TextureBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : - GLVariableBase{ParentLayout, ResIndex} - {} - - // Non-virtual function - void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); - - virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final - { - BindResource(pObject, 0); - } - - virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, - Uint32 FirstElement, - Uint32 NumElements) override final - { - const auto& Desc = GetDesc(); - VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements); - for (Uint32 elem = 0; elem < NumElements; ++elem) - BindResource(ppObjects[elem], FirstElement + elem); - } - - virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final - { - const auto& Desc = GetDesc(); - VERIFY_EXPR(ArrayIndex < Desc.ArraySize); - const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT); - return m_ParentManager.m_ResourceCache.IsTextureBound(GetAttribs().CacheOffset + ArrayIndex, IsTexView); - } - }; - - - struct ImageBindInfo final : GLVariableBase - { - ImageBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : - GLVariableBase{ParentLayout, ResIndex} - {} - - // Provide non-virtual function - void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); - - virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final - { - BindResource(pObject, 0); - } - - virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, - Uint32 FirstElement, - Uint32 NumElements) override final - { - const auto& Desc = GetDesc(); - VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements); - for (Uint32 elem = 0; elem < NumElements; ++elem) - BindResource(ppObjects[elem], FirstElement + elem); - } - - virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final - { - const auto& Desc = GetDesc(); - VERIFY_EXPR(ArrayIndex < Desc.ArraySize); - const bool IsImgView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV); - return m_ParentManager.m_ResourceCache.IsImageBound(GetAttribs().CacheOffset + ArrayIndex, IsImgView); - } - }; - - - struct StorageBufferBindInfo final : GLVariableBase - { - StorageBufferBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : - GLVariableBase{ParentLayout, ResIndex} - {} - - // Non-virtual function - void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); - - virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final - { - BindResource(pObject, 0); - } - - virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, - Uint32 FirstElement, - Uint32 NumElements) override final - { - const auto& Desc = GetDesc(); - VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements); - for (Uint32 elem = 0; elem < NumElements; ++elem) - BindResource(ppObjects[elem], FirstElement + elem); - } - - virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final - { - VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize); - return m_ParentManager.m_ResourceCache.IsSSBOBound(GetAttribs().CacheOffset + ArrayIndex); - } - }; - - - // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive - // while Layout is alive - void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); - -#ifdef DILIGENT_DEVELOPMENT - bool dvpVerifyBindings(const ShaderResourceCacheGL& ResourceCache) const; -#endif - - IShaderResourceVariable* GetVariable(const Char* Name) const; - IShaderResourceVariable* GetVariable(Uint32 Index) const; - - IObject& GetOwner() { return m_Owner; } - - Uint32 GetVariableCount() const; - - // clang-format off - Uint32 GetNumUBs() const { return (m_TextureOffset - m_UBOffset) / sizeof(UniformBuffBindInfo); } - Uint32 GetNumTextures() const { return (m_ImageOffset - m_TextureOffset) / sizeof(TextureBindInfo); } - Uint32 GetNumImages() const { return (m_StorageBufferOffset - m_ImageOffset) / sizeof(ImageBindInfo) ; } - Uint32 GetNumStorageBuffers() const { return (m_VariableEndOffset - m_StorageBufferOffset) / sizeof(StorageBufferBindInfo); } - // clang-format on - - template Uint32 GetNumResources() const; - - template - const ResourceType& GetConstResource(Uint32 ResIndex) const - { - VERIFY(ResIndex < GetNumResources(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources(), ")"); - auto Offset = GetResourceOffset(); - return reinterpret_cast(reinterpret_cast(m_ResourceBuffer) + Offset)[ResIndex]; - } - - Uint32 GetVariableIndex(const GLVariableBase& Var) const; - -private: - struct ResourceCounters - { - Uint32 NumUBs = 0; - Uint32 NumTextures = 0; - Uint32 NumImages = 0; - Uint32 NumStorageBlocks = 0; - }; - static void CountResources(const PipelineResourceSignatureGLImpl& Signature, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType, - ResourceCounters& Counters); - - template - static void ProcessSignatureResources(const PipelineResourceSignatureGLImpl& Signature, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType, - HandlerType Handler); - - // Offsets in bytes - using OffsetType = Uint16; - - template OffsetType GetResourceOffset() const; - - template - ResourceType& GetResource(Uint32 ResIndex) const - { - VERIFY(ResIndex < GetNumResources(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources() - 1, ")"); - auto Offset = GetResourceOffset(); - return reinterpret_cast(reinterpret_cast(m_ResourceBuffer) + Offset)[ResIndex]; - } - - template - IShaderResourceVariable* GetResourceByName(const Char* Name) const; - - template - void HandleResources(THandleUB HandleUB, - THandleTexture HandleTexture, - THandleImage HandleImage, - THandleStorageBuffer HandleStorageBuffer) - { - for (Uint32 ub = 0; ub < GetNumResources(); ++ub) - HandleUB(GetResource(ub)); - - for (Uint32 s = 0; s < GetNumResources(); ++s) - HandleTexture(GetResource(s)); - - for (Uint32 i = 0; i < GetNumResources(); ++i) - HandleImage(GetResource(i)); - - for (Uint32 s = 0; s < GetNumResources(); ++s) - HandleStorageBuffer(GetResource(s)); - } - - template - void HandleConstResources(THandleUB HandleUB, - THandleTexture HandleTexture, - THandleImage HandleImage, - THandleStorageBuffer HandleStorageBuffer) const - { - for (Uint32 ub = 0; ub < GetNumResources(); ++ub) - HandleUB(GetConstResource(ub)); - - for (Uint32 s = 0; s < GetNumResources(); ++s) - HandleTexture(GetConstResource(s)); - - for (Uint32 i = 0; i < GetNumResources(); ++i) - HandleImage(GetConstResource(i)); - - for (Uint32 s = 0; s < GetNumResources(); ++s) - HandleStorageBuffer(GetConstResource(s)); - } - - friend class ShaderVariableIndexLocator; - friend class ShaderVariableLocator; - -private: - PipelineResourceSignatureGLImpl const* m_pSignature = nullptr; - - IObject& m_Owner; - // No need to use shared pointer, as the resource cache is either part of the same - // ShaderGLImpl object, or ShaderResourceBindingGLImpl object - ShaderResourceCacheGL& m_ResourceCache; - void* m_ResourceBuffer = nullptr; - - static constexpr OffsetType m_UBOffset = 0; - OffsetType m_TextureOffset = 0; - OffsetType m_ImageOffset = 0; - OffsetType m_StorageBufferOffset = 0; - OffsetType m_VariableEndOffset = 0; - -#ifdef DILIGENT_DEBUG - IMemoryAllocator* m_pDbgAllocator = nullptr; -#endif -}; - - -template <> -inline Uint32 ShaderVariableManagerGL::GetNumResources() const -{ - return GetNumUBs(); -} - -template <> -inline Uint32 ShaderVariableManagerGL::GetNumResources() const -{ - return GetNumTextures(); -} - -template <> -inline Uint32 ShaderVariableManagerGL::GetNumResources() const -{ - return GetNumImages(); -} - -template <> -inline Uint32 ShaderVariableManagerGL::GetNumResources() const -{ - return GetNumStorageBuffers(); -} - - - -template <> -inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL:: - GetResourceOffset() const -{ - return m_UBOffset; -} - -template <> -inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL:: - GetResourceOffset() const -{ - return m_TextureOffset; -} - -template <> -inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL:: - GetResourceOffset() const -{ - return m_ImageOffset; -} - -template <> -inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL:: - GetResourceOffset() const -{ - return m_StorageBufferOffset; -} - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderVariableManagerGL.hpp b/Graphics/GraphicsEngineOpenGL/include/ShaderVariableManagerGL.hpp new file mode 100644 index 00000000..95719cd3 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderVariableManagerGL.hpp @@ -0,0 +1,481 @@ +/* + * Copyright 2019-2021 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 + +// ShaderVariableManagerGL class manages resource bindings for all stages in a pipeline + +// +// +// To program resource cache +// +// A A A A A A A A +// | | | | | | | | +// Binding Binding Binding Binding Binding Binding Binding Binding +// ___________________ ____|__________|__________________|________|______________|___________|______________|____________|____________ +// | | | | | | | | | | | | | | | +// | ShaderResourcesGL |--------------->| UB[0] | UB[1] | ... | Sam[0] | Sam[1] | ... | Img[0] | Img[1] | ... | SSBOs[0] | SSBOs[1] | ... | +// |___________________| |__________|__________|_______|________|________|_______|________|________|_______|__________|__________|_______| +// A A A A +// | | | | +// Ref Ref Ref Ref +// .-==========================-. _____|____________________________________|________________________|____________________________|______________ +// || || | | | | | | | | | | | +// __|| ShaderVariableManagerGL ||------->| UBInfo[0] | UBInfo[1] | ... | SamInfo[0] | SamInfo[1] | ... | ImgInfo[0] | ... | SSBO[0] | ... | +// | || || |___________|___________|_______|____________|____________|_______|____________|_________|___________|__________| +// | '-==========================-' / \ +// | Ref Ref +// | / \ +// | ___________________ ________V________________________________________________V_____________________________________________________ +// | | | | | | | | | | | | | | | | +// | | ShaderResourcesGL |--------------->| UB[0] | UB[1] | ... | Sam[0] | Sam[1] | ... | Img[0] | Img[1] | ... | SSBOs[0] | SSBOs[1] | ... | +// | |___________________| |__________|__________|_______|________|________|_______|________|________|_______|__________|__________|_______| +// | | | | | | | | | +// | Binding Binding Binding Binding Binding Binding Binding Binding +// | | | | | | | | | +// | _______________________ ____V___________V________________V_________V________________V________V________________V___________V_____________ +// | | | | | | | | +// '-->| ShaderResourceCacheGL |----------->| Uinform Buffers | Textures | Images | Storge Buffers | +// |_______________________| |___________________________|___________________________|___________________________|___________________________| +// +// +// Note that ShaderResourcesGL are kept by PipelineStateGLImpl. ShaderVariableManagerGL class is either part of the same PSO class, +// or part of ShaderResourceBindingGLImpl object that keeps a strong reference to the pipeline. So all references from GLVariableBase +// are always valid. + +#include + +#include "Object.h" +#include "PipelineResourceAttribsGL.hpp" +#include "ShaderResourceVariableBase.hpp" +#include "ShaderResourceCacheGL.hpp" + +namespace Diligent +{ + +class PipelineResourceSignatureGLImpl; + +// sizeof(ShaderVariableManagerGL) == 48 (x64, msvc, Release) +class ShaderVariableManagerGL +{ +public: + ShaderVariableManagerGL(IObject& Owner, ShaderResourceCacheGL& ResourceCache) noexcept : + m_Owner(Owner), + m_ResourceCache{ResourceCache} + {} + + ~ShaderVariableManagerGL(); + + void Destroy(IMemoryAllocator& Allocator); + + // No copies, only moves are allowed + // clang-format off + ShaderVariableManagerGL (const ShaderVariableManagerGL&) = delete; + ShaderVariableManagerGL& operator = (const ShaderVariableManagerGL&) = delete; + ShaderVariableManagerGL ( ShaderVariableManagerGL&&) = default; + ShaderVariableManagerGL& operator = ( ShaderVariableManagerGL&&) = delete; + // clang-format on + + void Initialize(const PipelineResourceSignatureGLImpl& Signature, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderType); + + static size_t GetRequiredMemorySize(const PipelineResourceSignatureGLImpl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderType); + + using ResourceAttribs = PipelineResourceAttribsGL; + + // These two methods can't be implemented in the header because they depend on PipelineResourceSignatureGLImpl + const PipelineResourceDesc& GetResourceDesc(Uint32 Index) const; + const ResourceAttribs& GetAttribs(Uint32 Index) const; + + + struct GLVariableBase : public ShaderVariableBase + { + public: + using TBase = ShaderVariableBase; + GLVariableBase(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : + TBase{ParentLayout}, + m_ResIndex{ResIndex} + {} + + const PipelineResourceDesc& GetDesc() const { return m_ParentManager.GetResourceDesc(m_ResIndex); } + const ResourceAttribs& GetAttribs() const { return m_ParentManager.GetAttribs(m_ResIndex); } + + virtual SHADER_RESOURCE_VARIABLE_TYPE DILIGENT_CALL_TYPE GetType() const override final + { + return GetDesc().VarType; + } + + virtual void DILIGENT_CALL_TYPE GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final + { + const auto& Desc = GetDesc(); + ResourceDesc.Name = Desc.Name; + ResourceDesc.Type = Desc.ResourceType; + ResourceDesc.ArraySize = Desc.ArraySize; + } + + virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final + { + return m_ParentManager.GetVariableIndex(*this); + } + + private: + const Uint32 m_ResIndex; + }; + + + struct UniformBuffBindInfo final : GLVariableBase + { + UniformBuffBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : + GLVariableBase{ParentLayout, ResIndex} + {} + + // Non-virtual function + void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); + + virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final + { + BindResource(pObject, 0); + } + + virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, + Uint32 FirstElement, + Uint32 NumElements) override final + { + const auto& Desc = GetDesc(); + VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements); + for (Uint32 elem = 0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement + elem); + } + + virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final + { + VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize); + return m_ParentManager.m_ResourceCache.IsUBBound(GetAttribs().CacheOffset + ArrayIndex); + } + }; + + + struct TextureBindInfo final : GLVariableBase + { + TextureBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : + GLVariableBase{ParentLayout, ResIndex} + {} + + // Non-virtual function + void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); + + virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final + { + BindResource(pObject, 0); + } + + virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, + Uint32 FirstElement, + Uint32 NumElements) override final + { + const auto& Desc = GetDesc(); + VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements); + for (Uint32 elem = 0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement + elem); + } + + virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final + { + const auto& Desc = GetDesc(); + VERIFY_EXPR(ArrayIndex < Desc.ArraySize); + const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT); + return m_ParentManager.m_ResourceCache.IsTextureBound(GetAttribs().CacheOffset + ArrayIndex, IsTexView); + } + }; + + + struct ImageBindInfo final : GLVariableBase + { + ImageBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : + GLVariableBase{ParentLayout, ResIndex} + {} + + // Provide non-virtual function + void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); + + virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final + { + BindResource(pObject, 0); + } + + virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, + Uint32 FirstElement, + Uint32 NumElements) override final + { + const auto& Desc = GetDesc(); + VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements); + for (Uint32 elem = 0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement + elem); + } + + virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final + { + const auto& Desc = GetDesc(); + VERIFY_EXPR(ArrayIndex < Desc.ArraySize); + const bool IsImgView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV); + return m_ParentManager.m_ResourceCache.IsImageBound(GetAttribs().CacheOffset + ArrayIndex, IsImgView); + } + }; + + + struct StorageBufferBindInfo final : GLVariableBase + { + StorageBufferBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) : + GLVariableBase{ParentLayout, ResIndex} + {} + + // Non-virtual function + void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex); + + virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final + { + BindResource(pObject, 0); + } + + virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, + Uint32 FirstElement, + Uint32 NumElements) override final + { + const auto& Desc = GetDesc(); + VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements); + for (Uint32 elem = 0; elem < NumElements; ++elem) + BindResource(ppObjects[elem], FirstElement + elem); + } + + virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final + { + VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize); + return m_ParentManager.m_ResourceCache.IsSSBOBound(GetAttribs().CacheOffset + ArrayIndex); + } + }; + + + // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive + // while Layout is alive + void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); + +#ifdef DILIGENT_DEVELOPMENT + bool dvpVerifyBindings(const ShaderResourceCacheGL& ResourceCache) const; +#endif + + IShaderResourceVariable* GetVariable(const Char* Name) const; + IShaderResourceVariable* GetVariable(Uint32 Index) const; + + IObject& GetOwner() { return m_Owner; } + + Uint32 GetVariableCount() const; + + // clang-format off + Uint32 GetNumUBs() const { return (m_TextureOffset - m_UBOffset) / sizeof(UniformBuffBindInfo); } + Uint32 GetNumTextures() const { return (m_ImageOffset - m_TextureOffset) / sizeof(TextureBindInfo); } + Uint32 GetNumImages() const { return (m_StorageBufferOffset - m_ImageOffset) / sizeof(ImageBindInfo) ; } + Uint32 GetNumStorageBuffers() const { return (m_VariableEndOffset - m_StorageBufferOffset) / sizeof(StorageBufferBindInfo); } + // clang-format on + + template Uint32 GetNumResources() const; + + template + const ResourceType& GetConstResource(Uint32 ResIndex) const + { + VERIFY(ResIndex < GetNumResources(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources(), ")"); + auto Offset = GetResourceOffset(); + return reinterpret_cast(reinterpret_cast(m_ResourceBuffer) + Offset)[ResIndex]; + } + + Uint32 GetVariableIndex(const GLVariableBase& Var) const; + +private: + struct ResourceCounters + { + Uint32 NumUBs = 0; + Uint32 NumTextures = 0; + Uint32 NumImages = 0; + Uint32 NumStorageBlocks = 0; + }; + static void CountResources(const PipelineResourceSignatureGLImpl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderType, + ResourceCounters& Counters); + + template + static void ProcessSignatureResources(const PipelineResourceSignatureGLImpl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderType, + HandlerType Handler); + + // Offsets in bytes + using OffsetType = Uint16; + + template OffsetType GetResourceOffset() const; + + template + ResourceType& GetResource(Uint32 ResIndex) const + { + VERIFY(ResIndex < GetNumResources(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources() - 1, ")"); + auto Offset = GetResourceOffset(); + return reinterpret_cast(reinterpret_cast(m_ResourceBuffer) + Offset)[ResIndex]; + } + + template + IShaderResourceVariable* GetResourceByName(const Char* Name) const; + + template + void HandleResources(THandleUB HandleUB, + THandleTexture HandleTexture, + THandleImage HandleImage, + THandleStorageBuffer HandleStorageBuffer) + { + for (Uint32 ub = 0; ub < GetNumResources(); ++ub) + HandleUB(GetResource(ub)); + + for (Uint32 s = 0; s < GetNumResources(); ++s) + HandleTexture(GetResource(s)); + + for (Uint32 i = 0; i < GetNumResources(); ++i) + HandleImage(GetResource(i)); + + for (Uint32 s = 0; s < GetNumResources(); ++s) + HandleStorageBuffer(GetResource(s)); + } + + template + void HandleConstResources(THandleUB HandleUB, + THandleTexture HandleTexture, + THandleImage HandleImage, + THandleStorageBuffer HandleStorageBuffer) const + { + for (Uint32 ub = 0; ub < GetNumResources(); ++ub) + HandleUB(GetConstResource(ub)); + + for (Uint32 s = 0; s < GetNumResources(); ++s) + HandleTexture(GetConstResource(s)); + + for (Uint32 i = 0; i < GetNumResources(); ++i) + HandleImage(GetConstResource(i)); + + for (Uint32 s = 0; s < GetNumResources(); ++s) + HandleStorageBuffer(GetConstResource(s)); + } + + friend class ShaderVariableIndexLocator; + friend class ShaderVariableLocator; + +private: + PipelineResourceSignatureGLImpl const* m_pSignature = nullptr; + + IObject& m_Owner; + // No need to use shared pointer, as the resource cache is either part of the same + // ShaderGLImpl object, or ShaderResourceBindingGLImpl object + ShaderResourceCacheGL& m_ResourceCache; + void* m_ResourceBuffer = nullptr; + + static constexpr OffsetType m_UBOffset = 0; + OffsetType m_TextureOffset = 0; + OffsetType m_ImageOffset = 0; + OffsetType m_StorageBufferOffset = 0; + OffsetType m_VariableEndOffset = 0; + +#ifdef DILIGENT_DEBUG + IMemoryAllocator* m_pDbgAllocator = nullptr; +#endif +}; + + +template <> +inline Uint32 ShaderVariableManagerGL::GetNumResources() const +{ + return GetNumUBs(); +} + +template <> +inline Uint32 ShaderVariableManagerGL::GetNumResources() const +{ + return GetNumTextures(); +} + +template <> +inline Uint32 ShaderVariableManagerGL::GetNumResources() const +{ + return GetNumImages(); +} + +template <> +inline Uint32 ShaderVariableManagerGL::GetNumResources() const +{ + return GetNumStorageBuffers(); +} + + + +template <> +inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL:: + GetResourceOffset() const +{ + return m_UBOffset; +} + +template <> +inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL:: + GetResourceOffset() const +{ + return m_TextureOffset; +} + +template <> +inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL:: + GetResourceOffset() const +{ + return m_ImageOffset; +} + +template <> +inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL:: + GetResourceOffset() const +{ + return m_StorageBufferOffset; +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp index 8a6faebb..48320bcf 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.hpp @@ -27,14 +27,12 @@ #pragma once -#include "BaseInterfacesGL.h" +#include "EngineGLImplTraits.hpp" #include "TextureGL.h" #include "TextureBase.hpp" -#include "RenderDevice.h" +#include "TextureViewGLImpl.hpp" // Required by TextureBase #include "GLObjectWrapper.hpp" -#include "TextureViewGLImpl.hpp" #include "AsyncWritableResource.hpp" -#include "RenderDeviceGLImpl.hpp" #include "GLContextState.hpp" namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.hpp index ae50f76c..92e41ffe 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.hpp @@ -27,18 +27,14 @@ #pragma once -#include "BaseInterfacesGL.h" +#include "EngineGLImplTraits.hpp" #include "TextureViewGL.h" #include "TextureViewBase.hpp" -#include "RenderDevice.h" #include "GLObjectWrapper.hpp" -#include "RenderDeviceGLImpl.hpp" namespace Diligent { -class FixedBlockMemoryAllocator; - /// Texture view implementation in OpenGL backend. class TextureViewGLImpl final : public TextureViewBase { diff --git a/Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp b/Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp index a4d8feba..48ece740 100644 --- a/Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp +++ b/Graphics/GraphicsEngineOpenGL/include/VAOCache.hpp @@ -28,13 +28,13 @@ #pragma once #include + #include "GraphicsTypes.h" #include "Buffer.h" #include "InputLayout.h" #include "LockHelper.hpp" #include "HashUtils.hpp" #include "DeviceContextBase.hpp" -#include "BaseInterfacesGL.h" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp index e7d45caf..b7c39022 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp @@ -28,10 +28,11 @@ #include "pch.h" #include "BufferGLImpl.hpp" + #include "RenderDeviceGLImpl.hpp" -#include "GLTypeConversions.hpp" -#include "BufferViewGLImpl.hpp" #include "DeviceContextGLImpl.hpp" + +#include "GLTypeConversions.hpp" #include "EngineMemory.h" namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp index fd44cd20..100d3fe2 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp @@ -27,10 +27,12 @@ #include "pch.h" +#include "BufferViewGLImpl.hpp" + #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" -#include "BufferViewGLImpl.hpp" #include "BufferGLImpl.hpp" + #include "GLTypeConversions.hpp" namespace Diligent @@ -103,4 +105,8 @@ BufferViewGLImpl::BufferViewGLImpl(IReferenceCounters* pRefCounters, IMPLEMENT_QUERY_INTERFACE(BufferViewGLImpl, IID_BufferViewGL, TBuffViewBase) +BufferViewGLImpl::~BufferViewGLImpl() +{ +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index d57de1f7..e2c9bb0e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -26,32 +26,34 @@ */ #include "pch.h" + +#include "DeviceContextGLImpl.hpp" + #include #include #include #include #include "SwapChainGL.h" -#include "DeviceContextGLImpl.hpp" -#include "RenderDeviceGLImpl.hpp" -#include "GLTypeConversions.hpp" +#include "RenderDeviceGLImpl.hpp" #include "BufferGLImpl.hpp" #include "ShaderGLImpl.hpp" -#include "VAOCache.hpp" #include "Texture1D_OGL.hpp" #include "Texture1DArray_OGL.hpp" #include "Texture2D_OGL.hpp" #include "Texture2DArray_OGL.hpp" #include "Texture3D_OGL.hpp" #include "SamplerGLImpl.hpp" -#include "GraphicsAccessories.hpp" #include "BufferViewGLImpl.hpp" #include "PipelineStateGLImpl.hpp" #include "FenceGLImpl.hpp" #include "ShaderResourceBindingGLImpl.hpp" -using namespace std; +#include "GLTypeConversions.hpp" +#include "VAOCache.hpp" +#include "GraphicsAccessories.hpp" + namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp index ce23b5c9..fe88669e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp @@ -28,6 +28,7 @@ #include "pch.h" #include "FenceGLImpl.hpp" +#include "RenderDeviceGLImpl.hpp" #include "EngineMemory.h" namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp index 8e7287b9..832be663 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp @@ -28,8 +28,10 @@ #include "pch.h" #include "FramebufferGLImpl.hpp" -#include "FBOCache.hpp" +#include "RenderDeviceGLImpl.hpp" #include "TextureViewGLImpl.hpp" +#include "FBOCache.hpp" +#include "GLContextState.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp index fa60c34a..75c10a18 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp @@ -28,12 +28,14 @@ #include "pch.h" #include "GLContextState.hpp" + +#include "BufferViewGLImpl.hpp" +#include "RenderDeviceGLImpl.hpp" #include "TextureBaseGL.hpp" #include "SamplerGLImpl.hpp" + #include "AsyncWritableResource.hpp" #include "GLTypeConversions.hpp" -#include "BufferViewGLImpl.hpp" -#include "RenderDeviceGLImpl.hpp" using namespace GLObjectWrappers; diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp index 67c2c5bf..264f30e1 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineResourceSignatureGLImpl.cpp @@ -28,8 +28,6 @@ #include "pch.h" #include "PipelineResourceSignatureGLImpl.hpp" #include "RenderDeviceGLImpl.hpp" -#include "ShaderResourceBindingGLImpl.hpp" -#include "ShaderVariableGL.hpp" namespace Diligent { @@ -421,12 +419,6 @@ void PipelineResourceSignatureGLImpl::ApplyBindings(GLObjectWrappers::GLProgramO State.SetProgram(GLObjectWrappers::GLProgramObj::Null()); } -void PipelineResourceSignatureGLImpl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, - bool InitStaticResources) -{ - CreateShaderResourceBindingImpl(ppShaderResourceBinding, InitStaticResources); -} - void PipelineResourceSignatureGLImpl::InitializeStaticSRBResources(IShaderResourceBinding* pSRB) const { InitializeStaticSRBResourcesImpl(ValidatedCast(pSRB), @@ -437,28 +429,6 @@ void PipelineResourceSignatureGLImpl::InitializeStaticSRBResources(IShaderResour ); } -Uint32 PipelineResourceSignatureGLImpl::GetStaticVariableCount(SHADER_TYPE ShaderType) const -{ - return GetStaticVariableCountImpl(ShaderType); -} - -IShaderResourceVariable* PipelineResourceSignatureGLImpl::GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name) -{ - return GetStaticVariableByNameImpl(ShaderType, Name); -} - -IShaderResourceVariable* PipelineResourceSignatureGLImpl::GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) -{ - return GetStaticVariableByIndexImpl(ShaderType, Index); -} - -void PipelineResourceSignatureGLImpl::BindStaticResources(Uint32 ShaderFlags, - IResourceMapping* pResMapping, - Uint32 Flags) -{ - BindStaticResourcesImpl(ShaderFlags, pResMapping, Flags); -} - void PipelineResourceSignatureGLImpl::CopyStaticResources(ShaderResourceCacheGL& DstResourceCache) const { if (m_pStaticResCache == nullptr) diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index cc1d115d..b9a0931d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -32,11 +32,12 @@ #endif #include "PipelineStateGLImpl.hpp" + #include "RenderDeviceGLImpl.hpp" -#include "ShaderGLImpl.hpp" +#include "DeviceContextGLImpl.hpp" #include "ShaderResourceBindingGLImpl.hpp" + #include "EngineMemory.h" -#include "DeviceContextGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp index be02adca..d59b146a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/QueryGLImpl.cpp @@ -28,6 +28,7 @@ #include "pch.h" #include "QueryGLImpl.hpp" +#include "RenderDeviceGLImpl.hpp" #include "EngineMemory.h" namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 1a92be5f..8cfdba7d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -31,7 +31,6 @@ #include "BufferGLImpl.hpp" #include "ShaderGLImpl.hpp" -#include "VAOCache.hpp" #include "Texture1D_OGL.hpp" #include "Texture1DArray_OGL.hpp" #include "Texture2D_OGL.hpp" @@ -41,7 +40,6 @@ #include "TextureCubeArray_OGL.hpp" #include "SamplerGLImpl.hpp" #include "DeviceContextGLImpl.hpp" -#include "GLTypeConversions.hpp" #include "PipelineStateGLImpl.hpp" #include "ShaderResourceBindingGLImpl.hpp" #include "FenceGLImpl.hpp" @@ -49,6 +47,9 @@ #include "RenderPassGLImpl.hpp" #include "FramebufferGLImpl.hpp" #include "PipelineResourceSignatureGLImpl.hpp" + +#include "GLTypeConversions.hpp" +#include "VAOCache.hpp" #include "EngineMemory.h" #include "StringTools.hpp" diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp index 7ee5fc25..0843af17 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderPassGLImpl.cpp @@ -28,6 +28,7 @@ #include "pch.h" #include "RenderPassGLImpl.hpp" +#include "RenderDeviceGLImpl.hpp" #include "EngineMemory.h" namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp index 931ab3f2..ff20c104 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -27,9 +27,10 @@ #include "pch.h" +#include "ShaderGLImpl.hpp" + #include -#include "ShaderGLImpl.hpp" #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" #include "DataBlobImpl.hpp" diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp index 2538d66b..27f56bdc 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp @@ -26,9 +26,14 @@ */ #include "pch.h" + #include "ShaderResourceBindingGLImpl.hpp" + +#include "RenderDeviceGLImpl.hpp" #include "PipelineStateGLImpl.hpp" #include "ShaderGLImpl.hpp" +#include "PipelineResourceSignatureGLImpl.hpp" + #include "FixedBlockMemoryAllocator.hpp" namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp index 94f2ebfc..436ccafe 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceCacheGL.cpp @@ -27,6 +27,7 @@ #include "pch.h" #include "ShaderResourceCacheGL.hpp" +#include "RenderDeviceGLImpl.hpp" #include "PipelineResourceSignatureGLImpl.hpp" #include "GLTypeConversions.hpp" diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourcesGL.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourcesGL.cpp index 6096d5f9..84211c2c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourcesGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourcesGL.cpp @@ -26,11 +26,13 @@ */ #include "pch.h" -#include -#include "GLContextState.hpp" + #include "ShaderResourcesGL.hpp" + +#include + #include "RenderDeviceGLImpl.hpp" -#include "ShaderResourceBindingBase.hpp" +#include "GLContextState.hpp" #include "ShaderResourceVariableBase.hpp" #include "Align.hpp" diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderVariableGL.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderVariableGL.cpp deleted file mode 100644 index 91a2fa88..00000000 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderVariableGL.cpp +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright 2019-2021 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 -#include "ShaderVariableGL.hpp" -#include "PipelineResourceSignatureGLImpl.hpp" -#include "Align.hpp" -#include "PlatformMisc.hpp" -#include "ShaderBase.hpp" - -namespace Diligent -{ - -void ShaderVariableManagerGL::CountResources(const PipelineResourceSignatureGLImpl& Signature, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - const SHADER_TYPE ShaderType, - ResourceCounters& Counters) -{ - ProcessSignatureResources( - Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, - [&](Uint32 Index) // - { - const auto& ResDesc = Signature.GetResourceDesc(Index); - static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range"); - switch (PipelineResourceToBindingRange(ResDesc)) - { - // clang-format off - case BINDING_RANGE_UNIFORM_BUFFER: ++Counters.NumUBs; break; - case BINDING_RANGE_TEXTURE: ++Counters.NumTextures; break; - case BINDING_RANGE_IMAGE: ++Counters.NumImages; break; - case BINDING_RANGE_STORAGE_BUFFER: ++Counters.NumStorageBlocks; break; - // clang-format on - default: - UNEXPECTED("Unsupported resource type."); - } - }); -} - -template -void ShaderVariableManagerGL::ProcessSignatureResources(const PipelineResourceSignatureGLImpl& Signature, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType, - HandlerType Handler) -{ - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - - for (Uint32 var_type = 0; var_type < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; ++var_type) - { - const auto VarType = static_cast(var_type); - if (IsAllowedType(VarType, AllowedTypeBits)) - { - const auto ResIdxRange = Signature.GetResourceIndexRange(VarType); - for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r) - { - const auto& Res = Signature.GetResourceDesc(r); - VERIFY_EXPR(Res.VarType == VarType); - - if ((Res.ShaderStages & ShaderType) == 0) - continue; - - if (Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER) - continue; - - Handler(r); - } - } - } -} - -size_t ShaderVariableManagerGL::GetRequiredMemorySize(const PipelineResourceSignatureGLImpl& Signature, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType) -{ - ResourceCounters Counters; - CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters); - - // clang-format off - size_t RequiredSize = Counters.NumUBs * sizeof(UniformBuffBindInfo) + - Counters.NumTextures * sizeof(TextureBindInfo) + - Counters.NumImages * sizeof(ImageBindInfo) + - Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo); - // clang-format on - return RequiredSize; -} - -void ShaderVariableManagerGL::Initialize(const PipelineResourceSignatureGLImpl& Signature, - IMemoryAllocator& Allocator, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType) -{ -#ifdef DILIGENT_DEBUG - m_pDbgAllocator = &Allocator; -#endif - - ResourceCounters Counters; - CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters); - - m_pSignature = &Signature; - - // Initialize offsets - size_t CurrentOffset = 0; - - auto AdvanceOffset = [&CurrentOffset](size_t NumBytes) // - { - constexpr size_t MaxOffset = std::numeric_limits::max(); - VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")"); - (void)MaxOffset; - auto Offset = static_cast(CurrentOffset); - CurrentOffset += NumBytes; - return Offset; - }; - - // clang-format off - auto UBOffset = AdvanceOffset(Counters.NumUBs * sizeof(UniformBuffBindInfo) ); (void)UBOffset; // To suppress warning - m_TextureOffset = AdvanceOffset(Counters.NumTextures * sizeof(TextureBindInfo) ); - m_ImageOffset = AdvanceOffset(Counters.NumImages * sizeof(ImageBindInfo) ); - m_StorageBufferOffset = AdvanceOffset(Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo)); - m_VariableEndOffset = AdvanceOffset(0); - // clang-format off - auto TotalMemorySize = m_VariableEndOffset; - VERIFY_EXPR(TotalMemorySize == GetRequiredMemorySize(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType)); - - if (TotalMemorySize) - { - m_ResourceBuffer = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", TotalMemorySize); - } - - // clang-format off - VERIFY_EXPR(Counters.NumUBs == GetNumUBs() ); - VERIFY_EXPR(Counters.NumTextures == GetNumTextures() ); - VERIFY_EXPR(Counters.NumImages == GetNumImages() ); - VERIFY_EXPR(Counters.NumStorageBlocks == GetNumStorageBuffers()); - // clang-format on - - // Current resource index for every resource type - ResourceCounters VarCounters = {}; - - ProcessSignatureResources( - Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, - [&](Uint32 Index) // - { - const auto& ResDesc = Signature.GetResourceDesc(Index); - static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range"); - switch (PipelineResourceToBindingRange(ResDesc)) - { - case BINDING_RANGE_UNIFORM_BUFFER: - new (&GetResource(VarCounters.NumUBs++)) UniformBuffBindInfo{*this, Index}; - break; - case BINDING_RANGE_TEXTURE: - new (&GetResource(VarCounters.NumTextures++)) TextureBindInfo{*this, Index}; - break; - case BINDING_RANGE_IMAGE: - new (&GetResource(VarCounters.NumImages++)) ImageBindInfo{*this, Index}; - break; - case BINDING_RANGE_STORAGE_BUFFER: - new (&GetResource(VarCounters.NumStorageBlocks++)) StorageBufferBindInfo{*this, Index}; - break; - default: - UNEXPECTED("Unsupported resource type."); - } - }); - - // clang-format off - VERIFY(VarCounters.NumUBs == GetNumUBs(), "Not all UBs are initialized which will cause a crash when dtor is called"); - VERIFY(VarCounters.NumTextures == GetNumTextures(), "Not all Textures are initialized which will cause a crash when dtor is called"); - VERIFY(VarCounters.NumImages == GetNumImages(), "Not all Images are initialized which will cause a crash when dtor is called"); - VERIFY(VarCounters.NumStorageBlocks == GetNumStorageBuffers(), "Not all SSBOs are initialized which will cause a crash when dtor is called"); - // clang-format on -} - -ShaderVariableManagerGL::~ShaderVariableManagerGL() -{ - VERIFY(m_ResourceBuffer == nullptr, "Destroy() has not been called"); -} - -void ShaderVariableManagerGL::Destroy(IMemoryAllocator& Allocator) -{ - if (m_ResourceBuffer == nullptr) - return; - - VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor"); - - HandleResources( - [&](UniformBuffBindInfo& ub) { - ub.~UniformBuffBindInfo(); - }, - [&](TextureBindInfo& tex) { - tex.~TextureBindInfo(); - }, - [&](ImageBindInfo& img) { - img.~ImageBindInfo(); - }, - [&](StorageBufferBindInfo& ssbo) { - ssbo.~StorageBufferBindInfo(); - }); - - Allocator.Free(m_ResourceBuffer); - m_ResourceBuffer = nullptr; -} - -void ShaderVariableManagerGL::UniformBuffBindInfo::BindResource(IDeviceObject* pBuffer, - Uint32 ArrayIndex) -{ - const auto& Desc = GetDesc(); - const auto& Attr = GetAttribs(); - - DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1); - auto& ResourceCache = m_ParentManager.m_ResourceCache; - - VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER); - - // We cannot use ValidatedCast<> here as the resource retrieved from the - // resource mapping can be of wrong type - RefCntAutoPtr pBuffGLImpl(pBuffer, IID_BufferGL); -#ifdef DILIGENT_DEVELOPMENT - { - const auto& CachedUB = ResourceCache.GetConstUB(Attr.CacheOffset + ArrayIndex); - VerifyConstantBufferBinding(Desc.Name, Desc.ArraySize, Desc.VarType, Desc.Flags, ArrayIndex, pBuffer, pBuffGLImpl.RawPtr(), CachedUB.pBuffer.RawPtr()); - } -#endif - - ResourceCache.SetUniformBuffer(Attr.CacheOffset + ArrayIndex, std::move(pBuffGLImpl)); -} - - - -void ShaderVariableManagerGL::TextureBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) -{ - const auto& Desc = GetDesc(); - const auto& Attr = GetAttribs(); - - DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1); - auto& ResourceCache = m_ParentManager.m_ResourceCache; - - if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || - Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT) - { - // We cannot use ValidatedCast<> here as the resource retrieved from the - // resource mapping can be of wrong type - RefCntAutoPtr pViewGL(pView, IID_TextureViewGL); -#ifdef DILIGENT_DEVELOPMENT - { - auto& CachedTexSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrayIndex); - VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, - pView, pViewGL.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE}, - RESOURCE_DIM_UNDEFINED, false, CachedTexSampler.pView.RawPtr()); - if (Attr.IsImmutableSamplerAssigned() && ResourceCache.StaticResourcesInitialized()) - { - VERIFY(CachedTexSampler.pSampler != nullptr, "Immutable samplers must be initialized by PipelineResourceSignatureGLImpl::InitializeSRBResourceCache!"); - } - if (Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT) - { - DEV_CHECK_ERR(!Attr.IsSamplerAssigned(), "Input attachment must not have assigned sampler."); - } - } -#endif - ResourceCache.SetTexture(Attr.CacheOffset + ArrayIndex, std::move(pViewGL), !Attr.IsImmutableSamplerAssigned()); - } - else if (Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV) - { - // We cannot use ValidatedCast<> here as the resource retrieved from the - // resource mapping can be of wrong type - RefCntAutoPtr pViewGL(pView, IID_BufferViewGL); -#ifdef DILIGENT_DEVELOPMENT - { - auto& CachedBuffSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrayIndex); - VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, - pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE}, - RESOURCE_DIM_BUFFER, false, CachedBuffSampler.pView.RawPtr()); - if (pViewGL != nullptr) - { - const auto& ViewDesc = pViewGL->GetDesc(); - const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc(); - if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW)) - { - LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", - Desc.Name, ": formatted buffer view is expected."); - } - } - } -#endif - VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0); - ResourceCache.SetTexelBuffer(Attr.CacheOffset + ArrayIndex, std::move(pViewGL)); - } - else - { - UNEXPECTED("Unexpected resource type ", GetShaderResourceTypeLiteralName(Desc.ResourceType), ". Texture SRV or buffer SRV is expected."); - } -} - - -void ShaderVariableManagerGL::ImageBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) -{ - const auto& Desc = GetDesc(); - const auto& Attr = GetAttribs(); - - DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1); - auto& ResourceCache = m_ParentManager.m_ResourceCache; - - if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV) - { - // We cannot use ValidatedCast<> here as the resource retrieved from the - // resource mapping can be of wrong type - RefCntAutoPtr pViewGL(pView, IID_TextureViewGL); -#ifdef DILIGENT_DEVELOPMENT - { - auto& CachedUAV = ResourceCache.GetConstImage(Attr.CacheOffset + ArrayIndex); - VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, - pView, pViewGL.RawPtr(), {TEXTURE_VIEW_UNORDERED_ACCESS}, - RESOURCE_DIM_UNDEFINED, false, CachedUAV.pView.RawPtr()); - } -#endif - ResourceCache.SetTexImage(Attr.CacheOffset + ArrayIndex, std::move(pViewGL)); - } - else if (Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV) - { - // We cannot use ValidatedCast<> here as the resource retrieved from the - // resource mapping can be of wrong type - RefCntAutoPtr pViewGL(pView, IID_BufferViewGL); -#ifdef DILIGENT_DEVELOPMENT - { - auto& CachedUAV = ResourceCache.GetConstImage(Attr.CacheOffset + ArrayIndex); - VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, - pView, pViewGL.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS}, - RESOURCE_DIM_BUFFER, false, CachedUAV.pView.RawPtr()); - if (pViewGL != nullptr) - { - const auto& ViewDesc = pViewGL->GetDesc(); - const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc(); - if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW)) - { - LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", - Desc.Name, ": formatted buffer view is expected."); - } - } - } -#endif - VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0); - ResourceCache.SetBufImage(Attr.CacheOffset + ArrayIndex, std::move(pViewGL)); - } - else - { - UNEXPECTED("Unexpected resource type ", GetShaderResourceTypeLiteralName(Desc.ResourceType), ". Texture UAV or buffer UAV is expected."); - } -} - - - -void ShaderVariableManagerGL::StorageBufferBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) -{ - const auto& Desc = GetDesc(); - const auto& Attr = GetAttribs(); - - DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1); - auto& ResourceCache = m_ParentManager.m_ResourceCache; - VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV || - Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV); - VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) == 0); - - // We cannot use ValidatedCast<> here as the resource retrieved from the - // resource mapping can be of wrong type - RefCntAutoPtr pViewGL(pView, IID_BufferViewGL); -#ifdef DILIGENT_DEVELOPMENT - { - auto& CachedSSBO = ResourceCache.GetConstSSBO(Attr.CacheOffset + ArrayIndex); - // HLSL structured buffers are mapped to SSBOs in GLSL - VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, - pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE, BUFFER_VIEW_UNORDERED_ACCESS}, - RESOURCE_DIM_BUFFER, false, CachedSSBO.pBufferView.RawPtr()); - if (pViewGL != nullptr) - { - const auto& ViewDesc = pViewGL->GetDesc(); - const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc(); - if (BuffDesc.Mode != BUFFER_MODE_STRUCTURED && BuffDesc.Mode != BUFFER_MODE_RAW) - { - LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", - Desc.Name, ": structured buffer view is expected."); - } - } - } -#endif - ResourceCache.SetSSBO(Attr.CacheOffset + ArrayIndex, std::move(pViewGL)); -} - -void ShaderVariableManagerGL::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) -{ - if (pResourceMapping == nullptr) - { - LOG_ERROR_MESSAGE("Failed to bind resources: resource mapping is null"); - return; - } - - if ((Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0) - Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL; - - HandleResources( - [&](UniformBuffBindInfo& ub) { - ub.BindResources(pResourceMapping, Flags); - }, - [&](TextureBindInfo& tex) { - tex.BindResources(pResourceMapping, Flags); - }, - [&](ImageBindInfo& img) { - img.BindResources(pResourceMapping, Flags); - }, - [&](StorageBufferBindInfo& ssbo) { - ssbo.BindResources(pResourceMapping, Flags); - }); -} - - -template -IShaderResourceVariable* ShaderVariableManagerGL::GetResourceByName(const Char* Name) const -{ - auto NumResources = GetNumResources(); - for (Uint32 res = 0; res < NumResources; ++res) - { - auto& Resource = GetResource(res); - const auto& ResDesc = Resource.GetDesc(); - if (strcmp(ResDesc.Name, Name) == 0) - return &Resource; - } - - return nullptr; -} - - -IShaderResourceVariable* ShaderVariableManagerGL::GetVariable(const Char* Name) const -{ - if (auto* pUB = GetResourceByName(Name)) - return pUB; - - if (auto* pTexture = GetResourceByName(Name)) - return pTexture; - - if (auto* pImage = GetResourceByName(Name)) - return pImage; - - if (auto* pSSBO = GetResourceByName(Name)) - return pSSBO; - - return nullptr; -} - -Uint32 ShaderVariableManagerGL::GetVariableCount() const -{ - return GetNumUBs() + GetNumTextures() + GetNumImages() + GetNumStorageBuffers(); -} - -class ShaderVariableLocator -{ -public: - ShaderVariableLocator(const ShaderVariableManagerGL& _Layout, - Uint32 _Index) : - // clang-format off - Layout {_Layout}, - Index {_Index} - // clang-format on - { - } - - template - IShaderResourceVariable* TryResource(Uint32 NumResources) - { - if (Index < NumResources) - return &Layout.GetResource(Index); - else - { - Index -= NumResources; - return nullptr; - } - } - -private: - ShaderVariableManagerGL const& Layout; - Uint32 Index; -}; - - -IShaderResourceVariable* ShaderVariableManagerGL::GetVariable(Uint32 Index) const -{ - ShaderVariableLocator VarLocator(*this, Index); - - if (auto* pUB = VarLocator.TryResource(GetNumUBs())) - return pUB; - - if (auto* pTexture = VarLocator.TryResource(GetNumTextures())) - return pTexture; - - if (auto* pImage = VarLocator.TryResource(GetNumImages())) - return pImage; - - if (auto* pSSBO = VarLocator.TryResource(GetNumStorageBuffers())) - return pSSBO; - - LOG_ERROR(Index, " is not a valid variable index."); - return nullptr; -} - - - -class ShaderVariableIndexLocator -{ -public: - ShaderVariableIndexLocator(const ShaderVariableManagerGL& _Layout, const ShaderVariableManagerGL::GLVariableBase& Variable) : - // clang-format off - Layout {_Layout}, - VarOffset(reinterpret_cast(&Variable) - reinterpret_cast(_Layout.m_ResourceBuffer)) - // clang-format on - {} - - template - bool TryResource(Uint32 NextResourceTypeOffset, Uint32 VarCount) - { - if (VarOffset < NextResourceTypeOffset) - { - auto RelativeOffset = VarOffset - Layout.GetResourceOffset(); - DEV_CHECK_ERR(RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")"); - RelativeOffset /= sizeof(ResourceType); - VERIFY(RelativeOffset >= 0 && RelativeOffset < VarCount, - "Relative offset is out of bounds which either means the variable does not belong to this SRB or " - "there is a bug in varaible offsets"); - Index += static_cast(RelativeOffset); - return true; - } - else - { - Index += VarCount; - return false; - } - } - - Uint32 GetIndex() const { return Index; } - -private: - const ShaderVariableManagerGL& Layout; - const size_t VarOffset; - Uint32 Index = 0; -}; - - -Uint32 ShaderVariableManagerGL::GetVariableIndex(const GLVariableBase& Var) const -{ - if (!m_ResourceBuffer) - { - LOG_ERROR("This shader resource layout does not have resources"); - return static_cast(-1); - } - - ShaderVariableIndexLocator IdxLocator(*this, Var); - - if (IdxLocator.TryResource(m_TextureOffset, GetNumUBs())) - return IdxLocator.GetIndex(); - - if (IdxLocator.TryResource(m_ImageOffset, GetNumTextures())) - return IdxLocator.GetIndex(); - - if (IdxLocator.TryResource(m_StorageBufferOffset, GetNumImages())) - return IdxLocator.GetIndex(); - - if (IdxLocator.TryResource(m_VariableEndOffset, GetNumStorageBuffers())) - return IdxLocator.GetIndex(); - - LOG_ERROR("Failed to get variable index. The variable ", &Var, " does not belong to this shader resource layout"); - return ~0u; -} - -#ifdef DILIGENT_DEVELOPMENT -bool ShaderVariableManagerGL::dvpVerifyBindings(const ShaderResourceCacheGL& ResourceCache) const -{ -# define LOG_MISSING_BINDING(VarType, BindInfo, ArrIndex) LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", GetShaderResourcePrintName(Desc, ArrIndex), "'") - - bool BindingsOK = true; - HandleConstResources( - [&](const UniformBuffBindInfo& ub) // - { - const auto& Desc = ub.GetDesc(); - const auto& Attr = ub.GetAttribs(); - VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER); - for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd) - { - if (!ResourceCache.IsUBBound(Attr.CacheOffset + ArrInd)) - { - LOG_MISSING_BINDING("constant buffer", ub, ArrInd); - BindingsOK = false; - } - } - }, - - [&](const TextureBindInfo& tex) // - { - const auto& Desc = tex.GetDesc(); - const auto& Attr = tex.GetAttribs(); - const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT); - VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV); - for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd) - { - if (!ResourceCache.IsTextureBound(Attr.CacheOffset + ArrInd, IsTexView)) - { - LOG_MISSING_BINDING("texture", tex, ArrInd); - BindingsOK = false; - } - else - { - const auto& CachedTex = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrInd); - if (Attr.IsImmutableSamplerAssigned() && CachedTex.pSampler == nullptr) - { - LOG_ERROR_MESSAGE("Immutable sampler is not initialized for texture '", Desc.Name, "'"); - BindingsOK = false; - } - } - } - }, - - [&](const ImageBindInfo& img) // - { - const auto& Desc = img.GetDesc(); - const auto& Attr = img.GetAttribs(); - const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV); - VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV); - for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd) - { - if (!ResourceCache.IsImageBound(Attr.CacheOffset + ArrInd, IsTexView)) - { - LOG_MISSING_BINDING("texture UAV", img, ArrInd); - BindingsOK = false; - } - } - }, - - [&](const StorageBufferBindInfo& ssbo) // - { - const auto& Desc = ssbo.GetDesc(); - const auto& Attr = ssbo.GetAttribs(); - VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV || - Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV); - for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd) - { - if (!ResourceCache.IsSSBOBound(Attr.CacheOffset + ArrInd)) - { - LOG_MISSING_BINDING("buffer", ssbo, ArrInd); - BindingsOK = false; - } - } - }); -# undef LOG_MISSING_BINDING - - return BindingsOK; -} - -#endif // DILIGENT_DEVELOPMENT - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderVariableManagerGL.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderVariableManagerGL.cpp new file mode 100644 index 00000000..9410e3d3 --- /dev/null +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderVariableManagerGL.cpp @@ -0,0 +1,698 @@ +/* + * Copyright 2019-2021 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 "ShaderVariableManagerGL.hpp" + +#include + +#include "RenderDeviceGLImpl.hpp" +#include "PipelineResourceSignatureGLImpl.hpp" +#include "Align.hpp" +#include "PlatformMisc.hpp" + +namespace Diligent +{ + +void ShaderVariableManagerGL::CountResources(const PipelineResourceSignatureGLImpl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + const SHADER_TYPE ShaderType, + ResourceCounters& Counters) +{ + ProcessSignatureResources( + Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, + [&](Uint32 Index) // + { + const auto& ResDesc = Signature.GetResourceDesc(Index); + static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range"); + switch (PipelineResourceToBindingRange(ResDesc)) + { + // clang-format off + case BINDING_RANGE_UNIFORM_BUFFER: ++Counters.NumUBs; break; + case BINDING_RANGE_TEXTURE: ++Counters.NumTextures; break; + case BINDING_RANGE_IMAGE: ++Counters.NumImages; break; + case BINDING_RANGE_STORAGE_BUFFER: ++Counters.NumStorageBlocks; break; + // clang-format on + default: + UNEXPECTED("Unsupported resource type."); + } + }); +} + +template +void ShaderVariableManagerGL::ProcessSignatureResources(const PipelineResourceSignatureGLImpl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderType, + HandlerType Handler) +{ + const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); + + for (Uint32 var_type = 0; var_type < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; ++var_type) + { + const auto VarType = static_cast(var_type); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + const auto ResIdxRange = Signature.GetResourceIndexRange(VarType); + for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r) + { + const auto& Res = Signature.GetResourceDesc(r); + VERIFY_EXPR(Res.VarType == VarType); + + if ((Res.ShaderStages & ShaderType) == 0) + continue; + + if (Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER) + continue; + + Handler(r); + } + } + } +} + +size_t ShaderVariableManagerGL::GetRequiredMemorySize(const PipelineResourceSignatureGLImpl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderType) +{ + ResourceCounters Counters; + CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters); + + // clang-format off + size_t RequiredSize = Counters.NumUBs * sizeof(UniformBuffBindInfo) + + Counters.NumTextures * sizeof(TextureBindInfo) + + Counters.NumImages * sizeof(ImageBindInfo) + + Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo); + // clang-format on + return RequiredSize; +} + +void ShaderVariableManagerGL::Initialize(const PipelineResourceSignatureGLImpl& Signature, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderType) +{ +#ifdef DILIGENT_DEBUG + m_pDbgAllocator = &Allocator; +#endif + + ResourceCounters Counters; + CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters); + + m_pSignature = &Signature; + + // Initialize offsets + size_t CurrentOffset = 0; + + auto AdvanceOffset = [&CurrentOffset](size_t NumBytes) // + { + constexpr size_t MaxOffset = std::numeric_limits::max(); + VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")"); + (void)MaxOffset; + auto Offset = static_cast(CurrentOffset); + CurrentOffset += NumBytes; + return Offset; + }; + + // clang-format off + auto UBOffset = AdvanceOffset(Counters.NumUBs * sizeof(UniformBuffBindInfo) ); (void)UBOffset; // To suppress warning + m_TextureOffset = AdvanceOffset(Counters.NumTextures * sizeof(TextureBindInfo) ); + m_ImageOffset = AdvanceOffset(Counters.NumImages * sizeof(ImageBindInfo) ); + m_StorageBufferOffset = AdvanceOffset(Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo)); + m_VariableEndOffset = AdvanceOffset(0); + // clang-format off + auto TotalMemorySize = m_VariableEndOffset; + VERIFY_EXPR(TotalMemorySize == GetRequiredMemorySize(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType)); + + if (TotalMemorySize) + { + m_ResourceBuffer = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", TotalMemorySize); + } + + // clang-format off + VERIFY_EXPR(Counters.NumUBs == GetNumUBs() ); + VERIFY_EXPR(Counters.NumTextures == GetNumTextures() ); + VERIFY_EXPR(Counters.NumImages == GetNumImages() ); + VERIFY_EXPR(Counters.NumStorageBlocks == GetNumStorageBuffers()); + // clang-format on + + // Current resource index for every resource type + ResourceCounters VarCounters = {}; + + ProcessSignatureResources( + Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, + [&](Uint32 Index) // + { + const auto& ResDesc = Signature.GetResourceDesc(Index); + static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range"); + switch (PipelineResourceToBindingRange(ResDesc)) + { + case BINDING_RANGE_UNIFORM_BUFFER: + new (&GetResource(VarCounters.NumUBs++)) UniformBuffBindInfo{*this, Index}; + break; + case BINDING_RANGE_TEXTURE: + new (&GetResource(VarCounters.NumTextures++)) TextureBindInfo{*this, Index}; + break; + case BINDING_RANGE_IMAGE: + new (&GetResource(VarCounters.NumImages++)) ImageBindInfo{*this, Index}; + break; + case BINDING_RANGE_STORAGE_BUFFER: + new (&GetResource(VarCounters.NumStorageBlocks++)) StorageBufferBindInfo{*this, Index}; + break; + default: + UNEXPECTED("Unsupported resource type."); + } + }); + + // clang-format off + VERIFY(VarCounters.NumUBs == GetNumUBs(), "Not all UBs are initialized which will cause a crash when dtor is called"); + VERIFY(VarCounters.NumTextures == GetNumTextures(), "Not all Textures are initialized which will cause a crash when dtor is called"); + VERIFY(VarCounters.NumImages == GetNumImages(), "Not all Images are initialized which will cause a crash when dtor is called"); + VERIFY(VarCounters.NumStorageBlocks == GetNumStorageBuffers(), "Not all SSBOs are initialized which will cause a crash when dtor is called"); + // clang-format on +} + +ShaderVariableManagerGL::~ShaderVariableManagerGL() +{ + VERIFY(m_ResourceBuffer == nullptr, "Destroy() has not been called"); +} + +void ShaderVariableManagerGL::Destroy(IMemoryAllocator& Allocator) +{ + if (m_ResourceBuffer == nullptr) + return; + + VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor"); + + HandleResources( + [&](UniformBuffBindInfo& ub) { + ub.~UniformBuffBindInfo(); + }, + [&](TextureBindInfo& tex) { + tex.~TextureBindInfo(); + }, + [&](ImageBindInfo& img) { + img.~ImageBindInfo(); + }, + [&](StorageBufferBindInfo& ssbo) { + ssbo.~StorageBufferBindInfo(); + }); + + Allocator.Free(m_ResourceBuffer); + m_ResourceBuffer = nullptr; +} + +void ShaderVariableManagerGL::UniformBuffBindInfo::BindResource(IDeviceObject* pBuffer, + Uint32 ArrayIndex) +{ + const auto& Desc = GetDesc(); + const auto& Attr = GetAttribs(); + + DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1); + auto& ResourceCache = m_ParentManager.m_ResourceCache; + + VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER); + + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr pBuffGLImpl(pBuffer, IID_BufferGL); +#ifdef DILIGENT_DEVELOPMENT + { + const auto& CachedUB = ResourceCache.GetConstUB(Attr.CacheOffset + ArrayIndex); + VerifyConstantBufferBinding(Desc.Name, Desc.ArraySize, Desc.VarType, Desc.Flags, ArrayIndex, pBuffer, pBuffGLImpl.RawPtr(), CachedUB.pBuffer.RawPtr()); + } +#endif + + ResourceCache.SetUniformBuffer(Attr.CacheOffset + ArrayIndex, std::move(pBuffGLImpl)); +} + + + +void ShaderVariableManagerGL::TextureBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) +{ + const auto& Desc = GetDesc(); + const auto& Attr = GetAttribs(); + + DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1); + auto& ResourceCache = m_ParentManager.m_ResourceCache; + + if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || + Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT) + { + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr pViewGL(pView, IID_TextureViewGL); +#ifdef DILIGENT_DEVELOPMENT + { + auto& CachedTexSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrayIndex); + VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, + pView, pViewGL.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE}, + RESOURCE_DIM_UNDEFINED, false, CachedTexSampler.pView.RawPtr()); + if (Attr.IsImmutableSamplerAssigned() && ResourceCache.StaticResourcesInitialized()) + { + VERIFY(CachedTexSampler.pSampler != nullptr, "Immutable samplers must be initialized by PipelineResourceSignatureGLImpl::InitializeSRBResourceCache!"); + } + if (Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT) + { + DEV_CHECK_ERR(!Attr.IsSamplerAssigned(), "Input attachment must not have assigned sampler."); + } + } +#endif + ResourceCache.SetTexture(Attr.CacheOffset + ArrayIndex, std::move(pViewGL), !Attr.IsImmutableSamplerAssigned()); + } + else if (Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV) + { + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr pViewGL(pView, IID_BufferViewGL); +#ifdef DILIGENT_DEVELOPMENT + { + auto& CachedBuffSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrayIndex); + VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, + pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE}, + RESOURCE_DIM_BUFFER, false, CachedBuffSampler.pView.RawPtr()); + if (pViewGL != nullptr) + { + const auto& ViewDesc = pViewGL->GetDesc(); + const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc(); + if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW)) + { + LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", + Desc.Name, ": formatted buffer view is expected."); + } + } + } +#endif + VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0); + ResourceCache.SetTexelBuffer(Attr.CacheOffset + ArrayIndex, std::move(pViewGL)); + } + else + { + UNEXPECTED("Unexpected resource type ", GetShaderResourceTypeLiteralName(Desc.ResourceType), ". Texture SRV or buffer SRV is expected."); + } +} + + +void ShaderVariableManagerGL::ImageBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) +{ + const auto& Desc = GetDesc(); + const auto& Attr = GetAttribs(); + + DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1); + auto& ResourceCache = m_ParentManager.m_ResourceCache; + + if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV) + { + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr pViewGL(pView, IID_TextureViewGL); +#ifdef DILIGENT_DEVELOPMENT + { + auto& CachedUAV = ResourceCache.GetConstImage(Attr.CacheOffset + ArrayIndex); + VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, + pView, pViewGL.RawPtr(), {TEXTURE_VIEW_UNORDERED_ACCESS}, + RESOURCE_DIM_UNDEFINED, false, CachedUAV.pView.RawPtr()); + } +#endif + ResourceCache.SetTexImage(Attr.CacheOffset + ArrayIndex, std::move(pViewGL)); + } + else if (Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV) + { + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr pViewGL(pView, IID_BufferViewGL); +#ifdef DILIGENT_DEVELOPMENT + { + auto& CachedUAV = ResourceCache.GetConstImage(Attr.CacheOffset + ArrayIndex); + VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, + pView, pViewGL.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS}, + RESOURCE_DIM_BUFFER, false, CachedUAV.pView.RawPtr()); + if (pViewGL != nullptr) + { + const auto& ViewDesc = pViewGL->GetDesc(); + const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc(); + if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW)) + { + LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", + Desc.Name, ": formatted buffer view is expected."); + } + } + } +#endif + VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0); + ResourceCache.SetBufImage(Attr.CacheOffset + ArrayIndex, std::move(pViewGL)); + } + else + { + UNEXPECTED("Unexpected resource type ", GetShaderResourceTypeLiteralName(Desc.ResourceType), ". Texture UAV or buffer UAV is expected."); + } +} + + + +void ShaderVariableManagerGL::StorageBufferBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex) +{ + const auto& Desc = GetDesc(); + const auto& Attr = GetAttribs(); + + DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1); + auto& ResourceCache = m_ParentManager.m_ResourceCache; + VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV || + Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV); + VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) == 0); + + // We cannot use ValidatedCast<> here as the resource retrieved from the + // resource mapping can be of wrong type + RefCntAutoPtr pViewGL(pView, IID_BufferViewGL); +#ifdef DILIGENT_DEVELOPMENT + { + auto& CachedSSBO = ResourceCache.GetConstSSBO(Attr.CacheOffset + ArrayIndex); + // HLSL structured buffers are mapped to SSBOs in GLSL + VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex, + pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE, BUFFER_VIEW_UNORDERED_ACCESS}, + RESOURCE_DIM_BUFFER, false, CachedSSBO.pBufferView.RawPtr()); + if (pViewGL != nullptr) + { + const auto& ViewDesc = pViewGL->GetDesc(); + const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc(); + if (BuffDesc.Mode != BUFFER_MODE_STRUCTURED && BuffDesc.Mode != BUFFER_MODE_RAW) + { + LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '", + Desc.Name, ": structured buffer view is expected."); + } + } + } +#endif + ResourceCache.SetSSBO(Attr.CacheOffset + ArrayIndex, std::move(pViewGL)); +} + +void ShaderVariableManagerGL::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) +{ + if (pResourceMapping == nullptr) + { + LOG_ERROR_MESSAGE("Failed to bind resources: resource mapping is null"); + return; + } + + if ((Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0) + Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL; + + HandleResources( + [&](UniformBuffBindInfo& ub) { + ub.BindResources(pResourceMapping, Flags); + }, + [&](TextureBindInfo& tex) { + tex.BindResources(pResourceMapping, Flags); + }, + [&](ImageBindInfo& img) { + img.BindResources(pResourceMapping, Flags); + }, + [&](StorageBufferBindInfo& ssbo) { + ssbo.BindResources(pResourceMapping, Flags); + }); +} + + +template +IShaderResourceVariable* ShaderVariableManagerGL::GetResourceByName(const Char* Name) const +{ + auto NumResources = GetNumResources(); + for (Uint32 res = 0; res < NumResources; ++res) + { + auto& Resource = GetResource(res); + const auto& ResDesc = Resource.GetDesc(); + if (strcmp(ResDesc.Name, Name) == 0) + return &Resource; + } + + return nullptr; +} + + +IShaderResourceVariable* ShaderVariableManagerGL::GetVariable(const Char* Name) const +{ + if (auto* pUB = GetResourceByName(Name)) + return pUB; + + if (auto* pTexture = GetResourceByName(Name)) + return pTexture; + + if (auto* pImage = GetResourceByName(Name)) + return pImage; + + if (auto* pSSBO = GetResourceByName(Name)) + return pSSBO; + + return nullptr; +} + +Uint32 ShaderVariableManagerGL::GetVariableCount() const +{ + return GetNumUBs() + GetNumTextures() + GetNumImages() + GetNumStorageBuffers(); +} + +class ShaderVariableLocator +{ +public: + ShaderVariableLocator(const ShaderVariableManagerGL& _Layout, + Uint32 _Index) : + // clang-format off + Layout {_Layout}, + Index {_Index} + // clang-format on + { + } + + template + IShaderResourceVariable* TryResource(Uint32 NumResources) + { + if (Index < NumResources) + return &Layout.GetResource(Index); + else + { + Index -= NumResources; + return nullptr; + } + } + +private: + ShaderVariableManagerGL const& Layout; + Uint32 Index; +}; + + +IShaderResourceVariable* ShaderVariableManagerGL::GetVariable(Uint32 Index) const +{ + ShaderVariableLocator VarLocator(*this, Index); + + if (auto* pUB = VarLocator.TryResource(GetNumUBs())) + return pUB; + + if (auto* pTexture = VarLocator.TryResource(GetNumTextures())) + return pTexture; + + if (auto* pImage = VarLocator.TryResource(GetNumImages())) + return pImage; + + if (auto* pSSBO = VarLocator.TryResource(GetNumStorageBuffers())) + return pSSBO; + + LOG_ERROR(Index, " is not a valid variable index."); + return nullptr; +} + + + +class ShaderVariableIndexLocator +{ +public: + ShaderVariableIndexLocator(const ShaderVariableManagerGL& _Layout, const ShaderVariableManagerGL::GLVariableBase& Variable) : + // clang-format off + Layout {_Layout}, + VarOffset(reinterpret_cast(&Variable) - reinterpret_cast(_Layout.m_ResourceBuffer)) + // clang-format on + {} + + template + bool TryResource(Uint32 NextResourceTypeOffset, Uint32 VarCount) + { + if (VarOffset < NextResourceTypeOffset) + { + auto RelativeOffset = VarOffset - Layout.GetResourceOffset(); + DEV_CHECK_ERR(RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")"); + RelativeOffset /= sizeof(ResourceType); + VERIFY(RelativeOffset >= 0 && RelativeOffset < VarCount, + "Relative offset is out of bounds which either means the variable does not belong to this SRB or " + "there is a bug in varaible offsets"); + Index += static_cast(RelativeOffset); + return true; + } + else + { + Index += VarCount; + return false; + } + } + + Uint32 GetIndex() const { return Index; } + +private: + const ShaderVariableManagerGL& Layout; + const size_t VarOffset; + Uint32 Index = 0; +}; + + +Uint32 ShaderVariableManagerGL::GetVariableIndex(const GLVariableBase& Var) const +{ + if (!m_ResourceBuffer) + { + LOG_ERROR("This shader resource layout does not have resources"); + return static_cast(-1); + } + + ShaderVariableIndexLocator IdxLocator(*this, Var); + + if (IdxLocator.TryResource(m_TextureOffset, GetNumUBs())) + return IdxLocator.GetIndex(); + + if (IdxLocator.TryResource(m_ImageOffset, GetNumTextures())) + return IdxLocator.GetIndex(); + + if (IdxLocator.TryResource(m_StorageBufferOffset, GetNumImages())) + return IdxLocator.GetIndex(); + + if (IdxLocator.TryResource(m_VariableEndOffset, GetNumStorageBuffers())) + return IdxLocator.GetIndex(); + + LOG_ERROR("Failed to get variable index. The variable ", &Var, " does not belong to this shader resource layout"); + return ~0u; +} + +const PipelineResourceDesc& ShaderVariableManagerGL::GetResourceDesc(Uint32 Index) const +{ + VERIFY_EXPR(m_pSignature); + return m_pSignature->GetResourceDesc(Index); +} + +const ShaderVariableManagerGL::ResourceAttribs& ShaderVariableManagerGL::GetAttribs(Uint32 Index) const +{ + VERIFY_EXPR(m_pSignature); + return m_pSignature->GetResourceAttribs(Index); +} + + +#ifdef DILIGENT_DEVELOPMENT +bool ShaderVariableManagerGL::dvpVerifyBindings(const ShaderResourceCacheGL& ResourceCache) const +{ +# define LOG_MISSING_BINDING(VarType, BindInfo, ArrIndex) LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", GetShaderResourcePrintName(Desc, ArrIndex), "'") + + bool BindingsOK = true; + HandleConstResources( + [&](const UniformBuffBindInfo& ub) // + { + const auto& Desc = ub.GetDesc(); + const auto& Attr = ub.GetAttribs(); + VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER); + for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd) + { + if (!ResourceCache.IsUBBound(Attr.CacheOffset + ArrInd)) + { + LOG_MISSING_BINDING("constant buffer", ub, ArrInd); + BindingsOK = false; + } + } + }, + + [&](const TextureBindInfo& tex) // + { + const auto& Desc = tex.GetDesc(); + const auto& Attr = tex.GetAttribs(); + const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT); + VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV); + for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd) + { + if (!ResourceCache.IsTextureBound(Attr.CacheOffset + ArrInd, IsTexView)) + { + LOG_MISSING_BINDING("texture", tex, ArrInd); + BindingsOK = false; + } + else + { + const auto& CachedTex = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrInd); + if (Attr.IsImmutableSamplerAssigned() && CachedTex.pSampler == nullptr) + { + LOG_ERROR_MESSAGE("Immutable sampler is not initialized for texture '", Desc.Name, "'"); + BindingsOK = false; + } + } + } + }, + + [&](const ImageBindInfo& img) // + { + const auto& Desc = img.GetDesc(); + const auto& Attr = img.GetAttribs(); + const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV); + VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV); + for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd) + { + if (!ResourceCache.IsImageBound(Attr.CacheOffset + ArrInd, IsTexView)) + { + LOG_MISSING_BINDING("texture UAV", img, ArrInd); + BindingsOK = false; + } + } + }, + + [&](const StorageBufferBindInfo& ssbo) // + { + const auto& Desc = ssbo.GetDesc(); + const auto& Attr = ssbo.GetAttribs(); + VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV || + Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV); + for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd) + { + if (!ResourceCache.IsSSBOBound(Attr.CacheOffset + ArrInd)) + { + LOG_MISSING_BINDING("buffer", ssbo, ArrInd); + BindingsOK = false; + } + } + }); +# undef LOG_MISSING_BINDING + + return BindingsOK; +} + +#endif // DILIGENT_DEVELOPMENT + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp index dbf2e5f0..e8756c67 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp @@ -26,9 +26,10 @@ */ #include "pch.h" -#include "DeviceContextGLImpl.hpp" -#include "RenderDeviceGLImpl.hpp" + #include "SwapChainGLImpl.hpp" +#include "RenderDeviceGLImpl.hpp" +#include "DeviceContextGLImpl.hpp" #include "GraphicsAccessories.hpp" namespace Diligent diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp index a9a00f43..8d49522b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp @@ -30,8 +30,8 @@ #include "Texture1DArray_OGL.hpp" #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" -#include "GLTypeConversions.hpp" #include "BufferGLImpl.hpp" +#include "GLTypeConversions.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp index 92861f93..9ddd61bc 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp @@ -30,8 +30,8 @@ #include "Texture1D_OGL.hpp" #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" -#include "GLTypeConversions.hpp" #include "BufferGLImpl.hpp" +#include "GLTypeConversions.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp index 17fccd91..a544c080 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp @@ -30,9 +30,9 @@ #include "Texture2DArray_OGL.hpp" #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" +#include "BufferGLImpl.hpp" #include "GLTypeConversions.hpp" #include "GraphicsAccessories.hpp" -#include "BufferGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp index 5866059a..7442bf5b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp @@ -30,9 +30,9 @@ #include "Texture2D_OGL.hpp" #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" +#include "BufferGLImpl.hpp" #include "GLTypeConversions.hpp" #include "GraphicsAccessories.hpp" -#include "BufferGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp index 393dfef6..52717652 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp @@ -30,9 +30,9 @@ #include "Texture3D_OGL.hpp" #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" +#include "BufferGLImpl.hpp" #include "GLTypeConversions.hpp" #include "GraphicsAccessories.hpp" -#include "BufferGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp index d38a468d..9facc557 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp @@ -28,11 +28,12 @@ #include "pch.h" #include "TextureBaseGL.hpp" + #include "RenderDeviceGLImpl.hpp" -#include "GLTypeConversions.hpp" -#include "TextureViewGLImpl.hpp" -#include "GLContextState.hpp" #include "DeviceContextGLImpl.hpp" +#include "TextureViewGLImpl.hpp" + +#include "GLTypeConversions.hpp" #include "EngineMemory.h" #include "GraphicsAccessories.hpp" #include "Align.hpp" diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp index 0fd5a5c6..443cb792 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp @@ -28,11 +28,14 @@ #include "pch.h" #include "TextureCubeArray_OGL.hpp" + #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" +#include "BufferGLImpl.hpp" + #include "GLTypeConversions.hpp" #include "GraphicsAccessories.hpp" -#include "BufferGLImpl.hpp" + namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp index 2ee46a45..4caafac2 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp @@ -28,11 +28,13 @@ #include "pch.h" #include "TextureCube_OGL.hpp" + #include "RenderDeviceGLImpl.hpp" #include "DeviceContextGLImpl.hpp" +#include "BufferGLImpl.hpp" + #include "GLTypeConversions.hpp" #include "GraphicsAccessories.hpp" -#include "BufferGLImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp index 43bd9347..240b739b 100644 --- a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp @@ -28,12 +28,14 @@ #include "pch.h" #include "VAOCache.hpp" + #include "RenderDeviceGLImpl.hpp" -#include "GLObjectWrapper.hpp" #include "BufferGLImpl.hpp" +#include "PipelineStateGLImpl.hpp" + +#include "GLObjectWrapper.hpp" #include "GLTypeConversions.hpp" #include "GLContextState.hpp" -#include "PipelineStateGLImpl.hpp" namespace Diligent { -- cgit v1.2.3