git.s-ol.nu ~forks/DiligentCore / be8197d
OpenGL backend: reorganized headers, removed signature methods implemented by the base class assiduous 6 months ago
47 changed file(s) with 1384 addition(s) and 1340 deletion(s). Raw diff Collapse all Expand all
1414 include/GLContextState.hpp
1515 include/GLObjectWrapper.hpp
1616 include/ShaderResourceCacheGL.hpp
17 include/ShaderVariableGL.hpp
17 include/ShaderVariableManagerGL.hpp
1818 include/ShaderResourcesGL.hpp
1919 include/GLTypeConversions.hpp
2020 include/pch.h
2121 include/PipelineStateGLImpl.hpp
2222 include/PipelineResourceSignatureGLImpl.hpp
23 include/PipelineResourceAttribsGL.hpp
2324 include/QueryGLImpl.hpp
2425 include/RenderDeviceGLImpl.hpp
2526 include/RenderPassGLImpl.hpp
6970 src/GLContextState.cpp
7071 src/GLObjectWrapper.cpp
7172 src/ShaderResourceCacheGL.cpp
72 src/ShaderVariableGL.cpp
73 src/ShaderVariableManagerGL.cpp
7374 src/ShaderResourcesGL.cpp
7475 src/GLTypeConversions.cpp
7576 src/PipelineStateGLImpl.cpp
2626
2727 #pragma once
2828
29 #include "EngineGLImplTraits.hpp"
2930 #include "BufferGL.h"
3031 #include "BufferBase.hpp"
32 #include "BufferViewGLImpl.hpp" // Required by BufferBase
3133 #include "GLObjectWrapper.hpp"
3234 #include "AsyncWritableResource.hpp"
33 #include "BaseInterfacesGL.h"
34 #include "BufferViewGLImpl.hpp"
35 #include "RenderDeviceGLImpl.hpp"
3635 #include "GLContextState.hpp"
3736
3837 namespace Diligent
9594 const GLenum m_GLUsageHint;
9695 };
9796
98 void BufferGLImpl::BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLContextState)
97 void BufferGLImpl::BufferMemoryBarrier(MEMORY_BARRIER RequiredBarriers, GLContextState& GLState)
9998 {
10099 #if GL_ARB_shader_image_load_store
101100 # ifdef DILIGENT_DEBUG
106105 }
107106 # endif
108107
109 GLContextState.EnsureMemoryBarrier(RequiredBarriers, this);
108 GLState.EnsureMemoryBarrier(RequiredBarriers, this);
110109 #endif
111110 }
112111
2626
2727 #pragma once
2828
29 #include "EngineGLImplTraits.hpp"
2930 #include "BufferViewGL.h"
30 #include "BaseInterfacesGL.h"
3131 #include "BufferViewBase.hpp"
3232 #include "GLObjectWrapper.hpp"
33 #include "RenderDeviceGLImpl.hpp"
3433
3534 namespace Diligent
3635 {
4847 BufferGLImpl* pBuffer,
4948 bool bIsDefaultView);
5049
50 ~BufferViewGLImpl();
51
5152 /// Queries the specific interface, see IObject::QueryInterface() for details
5253 virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
5354
2828
2929 #include <vector>
3030
31 #include "EngineGLImplTraits.hpp"
3132 #include "DeviceContextGL.h"
3233 #include "DeviceContextBase.hpp"
33 #include "BaseInterfacesGL.h"
34 #include "GLContextState.hpp"
35 #include "GLObjectWrapper.hpp"
34
35 // GL object implementations are required by DeviceContextBase
3636 #include "BufferGLImpl.hpp"
3737 #include "TextureBaseGL.hpp"
3838 #include "QueryGLImpl.hpp"
3939 #include "FramebufferGLImpl.hpp"
4040 #include "RenderPassGLImpl.hpp"
4141 #include "PipelineStateGLImpl.hpp"
42 #include "BottomLevelASBase.hpp"
43 #include "TopLevelASBase.hpp"
4442 #include "ShaderResourceBindingGLImpl.hpp"
43
44 #include "GLContextState.hpp"
45 #include "GLObjectWrapper.hpp"
4546
4647 namespace Diligent
4748 {
49
50 class TextureBaseGL;
51 class ShaderResourceBindingGLImpl;
4852
4953 /// Device context implementation in OpenGL backend.
5054 class DeviceContextGLImpl final : public DeviceContextBase<EngineGLImplTraits>
3232 #include <deque>
3333 #include <atomic>
3434
35 #include "EngineGLImplTraits.hpp"
3536 #include "FenceGL.h"
36 #include "RenderDeviceGL.h"
3737 #include "FenceBase.hpp"
3838 #include "GLObjectWrapper.hpp"
39 #include "RenderDeviceGLImpl.hpp"
4039
4140 namespace Diligent
4241 {
3131
3232 #include <vector>
3333
34 #include "RenderDeviceGL.h"
34 #include "EngineGLImplTraits.hpp"
3535 #include "FramebufferBase.hpp"
36 #include "RenderDeviceGLImpl.hpp"
3736 #include "GLObjectWrapper.hpp"
3837
3938 namespace Diligent
4039 {
40
41 class GLContextState;
4142
4243 /// Framebuffer implementation in OpenGL backend.
4344 class FramebufferGLImpl final : public FramebufferBase<EngineGLImplTraits>
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 /// \file
30 /// Declaration of Diligent::PipelineResourceAttribsGL struct
31
32 #include "BasicTypes.h"
33 #include "DebugUtilities.hpp"
34
35 namespace Diligent
36 {
37
38 // sizeof(PipelineResourceAttribsGL) == 8, x64
39 struct PipelineResourceAttribsGL
40 {
41 private:
42 static constexpr Uint32 _SamplerIndBits = 31;
43 static constexpr Uint32 _SamplerAssignedBits = 1;
44
45 public:
46 static constexpr Uint32 InvalidCacheOffset = ~0u;
47 static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1;
48
49 // clang-format off
50 const Uint32 CacheOffset; // SRB and Signature use the same cache offsets for static resources.
51 // Binding == BaseBinding[Range] + CacheOffset
52 const Uint32 SamplerInd : _SamplerIndBits; // ImtblSamplerAssigned == true: index of the immutable sampler in m_ImmutableSamplers.
53 // ImtblSamplerAssigned == false: index of the assigned sampler in m_Desc.Resources.
54 const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag
55 // clang-format on
56
57 PipelineResourceAttribsGL(Uint32 _CacheOffset,
58 Uint32 _SamplerInd,
59 bool _ImtblSamplerAssigned) noexcept :
60 // clang-format off
61 CacheOffset {_CacheOffset },
62 SamplerInd {_SamplerInd },
63 ImtblSamplerAssigned{_ImtblSamplerAssigned ? 1u : 0u}
64 // clang-format on
65 {
66 VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value");
67 VERIFY(!_ImtblSamplerAssigned || SamplerInd != InvalidSamplerInd, "Immutable sampler is assigned, but sampler index is not valid");
68 }
69
70 bool IsSamplerAssigned() const
71 {
72 return SamplerInd != InvalidSamplerInd;
73 }
74
75 bool IsImmutableSamplerAssigned() const
76 {
77 return ImtblSamplerAssigned != 0;
78 }
79 };
80
81 } // namespace Diligent
3131
3232 #include <array>
3333
34 #include "EngineGLImplTraits.hpp"
35 #include "PipelineResourceAttribsGL.hpp"
3436 #include "PipelineResourceSignatureBase.hpp"
35 #include "ShaderResourceCacheGL.hpp"
3637 #include "ShaderResourcesGL.hpp"
3738 #include "SRBMemoryAllocator.hpp"
39
40 // ShaderVariableManagerGL, ShaderResourceCacheGL, and ShaderResourceBindingGLImpl
41 // are required by PipelineResourceSignatureBase
42 #include "ShaderResourceCacheGL.hpp"
43 #include "ShaderVariableManagerGL.hpp"
44 #include "ShaderResourceBindingGLImpl.hpp"
3845
3946 namespace Diligent
4047 {
4148
4249 class RenderDeviceGLImpl;
43 class ShaderVariableManagerGL;
4450
4551 enum BINDING_RANGE : Uint32
4652 {
6773 bool bIsDeviceInternal = false);
6874 ~PipelineResourceSignatureGLImpl();
6975
70 // sizeof(ResourceAttribs) == 8, x64
71 struct ResourceAttribs
72 {
73 private:
74 static constexpr Uint32 _SamplerIndBits = 31;
75 static constexpr Uint32 _SamplerAssignedBits = 1;
76
77 public:
78 static constexpr Uint32 InvalidCacheOffset = ~0u;
79 static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1;
80
81 // clang-format off
82 const Uint32 CacheOffset; // SRB and Signature use the same cache offsets for static resources.
83 // Binding == BaseBinding[Range] + CacheOffset
84 const Uint32 SamplerInd : _SamplerIndBits; // ImtblSamplerAssigned == true: index of the immutable sampler in m_ImmutableSamplers.
85 // ImtblSamplerAssigned == false: index of the assigned sampler in m_Desc.Resources.
86 const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag
87 // clang-format on
88
89 ResourceAttribs(Uint32 _CacheOffset,
90 Uint32 _SamplerInd,
91 bool _ImtblSamplerAssigned) noexcept :
92 // clang-format off
93 CacheOffset {_CacheOffset },
94 SamplerInd {_SamplerInd },
95 ImtblSamplerAssigned{_ImtblSamplerAssigned ? 1u : 0u}
96 // clang-format on
97 {
98 VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value");
99 VERIFY(!_ImtblSamplerAssigned || SamplerInd != InvalidSamplerInd, "Immutable sampler is assigned, but sampler index is not valid");
100 }
101
102 bool IsSamplerAssigned() const { return SamplerInd != InvalidSamplerInd; }
103 bool IsImmutableSamplerAssigned() const { return ImtblSamplerAssigned != 0; }
104 };
76 using ResourceAttribs = PipelineResourceAttribsGL;
10577
10678 const ResourceAttribs& GetResourceAttribs(Uint32 ResIndex) const
10779 {
10880 VERIFY_EXPR(ResIndex < m_Desc.NumResources);
10981 return m_pResourceAttribs[ResIndex];
110 }
111
112 bool HasDynamicResources() const
113 {
114 const auto IndexRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC);
115 return IndexRange.second > IndexRange.first;
11682 }
11783
11884 using TBindings = std::array<Uint32, BINDING_RANGE_COUNT>;
13197 Bindings[i] += m_BindingCount[i];
13298 }
13399 }
134
135 /// Implementation of IPipelineResourceSignature::CreateShaderResourceBinding.
136 virtual void DILIGENT_CALL_TYPE CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding,
137 bool InitStaticResources) override final;
138
139 /// Implementation of IPipelineResourceSignature::GetStaticVariableByName.
140 virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name) override final;
141
142 /// Implementation of IPipelineResourceSignature::GetStaticVariableByIndex.
143 virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final;
144
145 /// Implementation of IPipelineResourceSignature::GetStaticVariableCount.
146 virtual Uint32 DILIGENT_CALL_TYPE GetStaticVariableCount(SHADER_TYPE ShaderType) const override final;
147
148 /// Implementation of IPipelineResourceSignature::BindStaticResources.
149 virtual void DILIGENT_CALL_TYPE BindStaticResources(Uint32 ShaderFlags,
150 IResourceMapping* pResourceMapping,
151 Uint32 Flags) override final;
152100
153101 /// Implementation of IPipelineResourceSignature::IsCompatibleWith.
154102 virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineResourceSignature* pPRS) const override final
2727 #pragma once
2828
2929 #include <vector>
30
31 #include "EngineGLImplTraits.hpp"
3032 #include "PipelineStateGL.h"
3133 #include "PipelineStateBase.hpp"
32 #include "RenderDevice.h"
34
35 #include "PipelineResourceSignatureGLImpl.hpp" // Requiured by PipelineStateBase
36 #include "ShaderGLImpl.hpp"
37
3338 #include "GLObjectWrapper.hpp"
3439 #include "GLContext.hpp"
35 #include "RenderDeviceGLImpl.hpp"
36 #include "ShaderVariableGL.hpp"
37 #include "ShaderGLImpl.hpp"
38 #include "PipelineResourceSignatureGLImpl.hpp"
3940
4041 namespace Diligent
4142 {
2929 /// \file
3030 /// Declaration of Diligent::QueryGLImpl class
3131
32 #include "EngineGLImplTraits.hpp"
3233 #include "QueryGL.h"
33 #include "RenderDeviceGL.h"
3434 #include "QueryBase.hpp"
3535 #include "GLObjectWrapper.hpp"
36 #include "RenderDeviceGLImpl.hpp"
3736
3837 namespace Diligent
3938 {
2929 /// \file
3030 /// Declaration of Diligent::RenderPassGLImpl class
3131
32 #include "RenderDeviceGL.h"
32 #include "EngineGLImplTraits.hpp"
3333 #include "RenderPassBase.hpp"
34 #include "RenderDeviceGLImpl.hpp"
3534
3635 namespace Diligent
3736 {
2626
2727 #pragma once
2828
29 #include "BaseInterfacesGL.h"
29 #include "EngineGLImplTraits.hpp"
3030 #include "SamplerGL.h"
3131 #include "SamplerBase.hpp"
32 #include "RenderDevice.h"
3332 #include "GLObjectWrapper.hpp"
34 #include "RenderDeviceGLImpl.hpp"
3533
3634 namespace Diligent
3735 {
2626
2727 #pragma once
2828
29 #include "BaseInterfacesGL.h"
29 #include "EngineGLImplTraits.hpp"
3030 #include "ShaderGL.h"
3131 #include "ShaderBase.hpp"
32 #include "RenderDevice.h"
3332 #include "GLObjectWrapper.hpp"
34 #include "RenderDeviceGLImpl.hpp"
3533 #include "ShaderResourcesGL.hpp"
3634
3735 namespace Diligent
2929 /// \file
3030 /// Declaration of Diligent::ShaderResourceBindingGLImpl class
3131
32 #include "EngineGLImplTraits.hpp"
3233 #include "ShaderResourceBindingGL.h"
33 #include "RenderDeviceGL.h"
3434 #include "ShaderResourceBindingBase.hpp"
3535 #include "ShaderResourcesGL.hpp"
36
37 // ShaderResourceCacheGL and ShaderVariableManagerGL are required by ShaderResourceBindingBase
3638 #include "ShaderResourceCacheGL.hpp"
37 #include "ShaderVariableGL.hpp"
38 #include "PipelineResourceSignatureGLImpl.hpp"
39 #include "ShaderVariableManagerGL.hpp"
3940
4041 namespace Diligent
4142 {
43
44 class PipelineResourceSignatureGLImpl;
4245
4346 /// Shader resource binding object implementation in OpenGL backend.
4447 class ShaderResourceBindingGLImpl final : public ShaderResourceBindingBase<EngineGLImplTraits>
+0
-486
Graphics/GraphicsEngineOpenGL/include/ShaderVariableGL.hpp less more
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 // ShaderVariableManagerGL class manages resource bindings for all stages in a pipeline
30
31 //
32 //
33 // To program resource cache
34 //
35 // A A A A A A A A
36 // | | | | | | | |
37 // Binding Binding Binding Binding Binding Binding Binding Binding
38 // ___________________ ____|__________|__________________|________|______________|___________|______________|____________|____________
39 // | | | | | | | | | | | | | | |
40 // | ShaderResourcesGL |--------------->| UB[0] | UB[1] | ... | Sam[0] | Sam[1] | ... | Img[0] | Img[1] | ... | SSBOs[0] | SSBOs[1] | ... |
41 // |___________________| |__________|__________|_______|________|________|_______|________|________|_______|__________|__________|_______|
42 // A A A A
43 // | | | |
44 // Ref Ref Ref Ref
45 // .-==========================-. _____|____________________________________|________________________|____________________________|______________
46 // || || | | | | | | | | | | |
47 // __|| ShaderVariableManagerGL ||------->| UBInfo[0] | UBInfo[1] | ... | SamInfo[0] | SamInfo[1] | ... | ImgInfo[0] | ... | SSBO[0] | ... |
48 // | || || |___________|___________|_______|____________|____________|_______|____________|_________|___________|__________|
49 // | '-==========================-' / \
50 // | Ref Ref
51 // | / \
52 // | ___________________ ________V________________________________________________V_____________________________________________________
53 // | | | | | | | | | | | | | | | |
54 // | | ShaderResourcesGL |--------------->| UB[0] | UB[1] | ... | Sam[0] | Sam[1] | ... | Img[0] | Img[1] | ... | SSBOs[0] | SSBOs[1] | ... |
55 // | |___________________| |__________|__________|_______|________|________|_______|________|________|_______|__________|__________|_______|
56 // | | | | | | | | |
57 // | Binding Binding Binding Binding Binding Binding Binding Binding
58 // | | | | | | | | |
59 // | _______________________ ____V___________V________________V_________V________________V________V________________V___________V_____________
60 // | | | | | | | |
61 // '-->| ShaderResourceCacheGL |----------->| Uinform Buffers | Textures | Images | Storge Buffers |
62 // |_______________________| |___________________________|___________________________|___________________________|___________________________|
63 //
64 //
65 // Note that ShaderResourcesGL are kept by PipelineStateGLImpl. ShaderVariableManagerGL class is either part of the same PSO class,
66 // or part of ShaderResourceBindingGLImpl object that keeps a strong reference to the pipeline. So all references from GLVariableBase
67 // are always valid.
68
69 #include <array>
70
71 #include "Object.h"
72 #include "ShaderResourceVariableBase.hpp"
73 #include "ShaderResourceCacheGL.hpp"
74 #include "PipelineResourceSignatureGLImpl.hpp"
75
76 namespace Diligent
77 {
78
79 // sizeof(ShaderVariableManagerGL) == 48 (x64, msvc, Release)
80 class ShaderVariableManagerGL
81 {
82 public:
83 ShaderVariableManagerGL(IObject& Owner, ShaderResourceCacheGL& ResourceCache) noexcept :
84 m_Owner(Owner),
85 m_ResourceCache{ResourceCache}
86 {}
87
88 ~ShaderVariableManagerGL();
89
90 void Destroy(IMemoryAllocator& Allocator);
91
92 // No copies, only moves are allowed
93 // clang-format off
94 ShaderVariableManagerGL (const ShaderVariableManagerGL&) = delete;
95 ShaderVariableManagerGL& operator = (const ShaderVariableManagerGL&) = delete;
96 ShaderVariableManagerGL ( ShaderVariableManagerGL&&) = default;
97 ShaderVariableManagerGL& operator = ( ShaderVariableManagerGL&&) = delete;
98 // clang-format on
99
100 void Initialize(const PipelineResourceSignatureGLImpl& Signature,
101 IMemoryAllocator& Allocator,
102 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
103 Uint32 NumAllowedTypes,
104 SHADER_TYPE ShaderType);
105
106 static size_t GetRequiredMemorySize(const PipelineResourceSignatureGLImpl& Signature,
107 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
108 Uint32 NumAllowedTypes,
109 SHADER_TYPE ShaderType);
110
111 using ResourceAttribs = PipelineResourceSignatureGLImpl::ResourceAttribs;
112
113 const PipelineResourceDesc& GetResourceDesc(Uint32 Index) const
114 {
115 VERIFY_EXPR(m_pSignature);
116 return m_pSignature->GetResourceDesc(Index);
117 }
118 const ResourceAttribs& GetAttribs(Uint32 Index) const
119 {
120 VERIFY_EXPR(m_pSignature);
121 return m_pSignature->GetResourceAttribs(Index);
122 }
123
124
125 struct GLVariableBase : public ShaderVariableBase<ShaderVariableManagerGL>
126 {
127 public:
128 using TBase = ShaderVariableBase<ShaderVariableManagerGL>;
129 GLVariableBase(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
130 TBase{ParentLayout},
131 m_ResIndex{ResIndex}
132 {}
133
134 const PipelineResourceDesc& GetDesc() const { return m_ParentManager.GetResourceDesc(m_ResIndex); }
135 const ResourceAttribs& GetAttribs() const { return m_ParentManager.GetAttribs(m_ResIndex); }
136
137 virtual SHADER_RESOURCE_VARIABLE_TYPE DILIGENT_CALL_TYPE GetType() const override final
138 {
139 return GetDesc().VarType;
140 }
141
142 virtual void DILIGENT_CALL_TYPE GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final
143 {
144 const auto& Desc = GetDesc();
145 ResourceDesc.Name = Desc.Name;
146 ResourceDesc.Type = Desc.ResourceType;
147 ResourceDesc.ArraySize = Desc.ArraySize;
148 }
149
150 virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final
151 {
152 return m_ParentManager.GetVariableIndex(*this);
153 }
154
155 private:
156 const Uint32 m_ResIndex;
157 };
158
159
160 struct UniformBuffBindInfo final : GLVariableBase
161 {
162 UniformBuffBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
163 GLVariableBase{ParentLayout, ResIndex}
164 {}
165
166 // Non-virtual function
167 void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
168
169 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
170 {
171 BindResource(pObject, 0);
172 }
173
174 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
175 Uint32 FirstElement,
176 Uint32 NumElements) override final
177 {
178 const auto& Desc = GetDesc();
179 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
180 for (Uint32 elem = 0; elem < NumElements; ++elem)
181 BindResource(ppObjects[elem], FirstElement + elem);
182 }
183
184 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
185 {
186 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
187 return m_ParentManager.m_ResourceCache.IsUBBound(GetAttribs().CacheOffset + ArrayIndex);
188 }
189 };
190
191
192 struct TextureBindInfo final : GLVariableBase
193 {
194 TextureBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
195 GLVariableBase{ParentLayout, ResIndex}
196 {}
197
198 // Non-virtual function
199 void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
200
201 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
202 {
203 BindResource(pObject, 0);
204 }
205
206 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
207 Uint32 FirstElement,
208 Uint32 NumElements) override final
209 {
210 const auto& Desc = GetDesc();
211 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
212 for (Uint32 elem = 0; elem < NumElements; ++elem)
213 BindResource(ppObjects[elem], FirstElement + elem);
214 }
215
216 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
217 {
218 const auto& Desc = GetDesc();
219 VERIFY_EXPR(ArrayIndex < Desc.ArraySize);
220 const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
221 return m_ParentManager.m_ResourceCache.IsTextureBound(GetAttribs().CacheOffset + ArrayIndex, IsTexView);
222 }
223 };
224
225
226 struct ImageBindInfo final : GLVariableBase
227 {
228 ImageBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
229 GLVariableBase{ParentLayout, ResIndex}
230 {}
231
232 // Provide non-virtual function
233 void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
234
235 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
236 {
237 BindResource(pObject, 0);
238 }
239
240 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
241 Uint32 FirstElement,
242 Uint32 NumElements) override final
243 {
244 const auto& Desc = GetDesc();
245 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
246 for (Uint32 elem = 0; elem < NumElements; ++elem)
247 BindResource(ppObjects[elem], FirstElement + elem);
248 }
249
250 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
251 {
252 const auto& Desc = GetDesc();
253 VERIFY_EXPR(ArrayIndex < Desc.ArraySize);
254 const bool IsImgView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
255 return m_ParentManager.m_ResourceCache.IsImageBound(GetAttribs().CacheOffset + ArrayIndex, IsImgView);
256 }
257 };
258
259
260 struct StorageBufferBindInfo final : GLVariableBase
261 {
262 StorageBufferBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
263 GLVariableBase{ParentLayout, ResIndex}
264 {}
265
266 // Non-virtual function
267 void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
268
269 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
270 {
271 BindResource(pObject, 0);
272 }
273
274 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
275 Uint32 FirstElement,
276 Uint32 NumElements) override final
277 {
278 const auto& Desc = GetDesc();
279 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
280 for (Uint32 elem = 0; elem < NumElements; ++elem)
281 BindResource(ppObjects[elem], FirstElement + elem);
282 }
283
284 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
285 {
286 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
287 return m_ParentManager.m_ResourceCache.IsSSBOBound(GetAttribs().CacheOffset + ArrayIndex);
288 }
289 };
290
291
292 // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive
293 // while Layout is alive
294 void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags);
295
296 #ifdef DILIGENT_DEVELOPMENT
297 bool dvpVerifyBindings(const ShaderResourceCacheGL& ResourceCache) const;
298 #endif
299
300 IShaderResourceVariable* GetVariable(const Char* Name) const;
301 IShaderResourceVariable* GetVariable(Uint32 Index) const;
302
303 IObject& GetOwner() { return m_Owner; }
304
305 Uint32 GetVariableCount() const;
306
307 // clang-format off
308 Uint32 GetNumUBs() const { return (m_TextureOffset - m_UBOffset) / sizeof(UniformBuffBindInfo); }
309 Uint32 GetNumTextures() const { return (m_ImageOffset - m_TextureOffset) / sizeof(TextureBindInfo); }
310 Uint32 GetNumImages() const { return (m_StorageBufferOffset - m_ImageOffset) / sizeof(ImageBindInfo) ; }
311 Uint32 GetNumStorageBuffers() const { return (m_VariableEndOffset - m_StorageBufferOffset) / sizeof(StorageBufferBindInfo); }
312 // clang-format on
313
314 template <typename ResourceType> Uint32 GetNumResources() const;
315
316 template <typename ResourceType>
317 const ResourceType& GetConstResource(Uint32 ResIndex) const
318 {
319 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>(), ")");
320 auto Offset = GetResourceOffset<ResourceType>();
321 return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
322 }
323
324 Uint32 GetVariableIndex(const GLVariableBase& Var) const;
325
326 private:
327 struct ResourceCounters
328 {
329 Uint32 NumUBs = 0;
330 Uint32 NumTextures = 0;
331 Uint32 NumImages = 0;
332 Uint32 NumStorageBlocks = 0;
333 };
334 static void CountResources(const PipelineResourceSignatureGLImpl& Signature,
335 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
336 Uint32 NumAllowedTypes,
337 SHADER_TYPE ShaderType,
338 ResourceCounters& Counters);
339
340 template <typename HandlerType>
341 static void ProcessSignatureResources(const PipelineResourceSignatureGLImpl& Signature,
342 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
343 Uint32 NumAllowedTypes,
344 SHADER_TYPE ShaderType,
345 HandlerType Handler);
346
347 // Offsets in bytes
348 using OffsetType = Uint16;
349
350 template <typename ResourceType> OffsetType GetResourceOffset() const;
351
352 template <typename ResourceType>
353 ResourceType& GetResource(Uint32 ResIndex) const
354 {
355 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>() - 1, ")");
356 auto Offset = GetResourceOffset<ResourceType>();
357 return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
358 }
359
360 template <typename ResourceType>
361 IShaderResourceVariable* GetResourceByName(const Char* Name) const;
362
363 template <typename THandleUB,
364 typename THandleTexture,
365 typename THandleImage,
366 typename THandleStorageBuffer>
367 void HandleResources(THandleUB HandleUB,
368 THandleTexture HandleTexture,
369 THandleImage HandleImage,
370 THandleStorageBuffer HandleStorageBuffer)
371 {
372 for (Uint32 ub = 0; ub < GetNumResources<UniformBuffBindInfo>(); ++ub)
373 HandleUB(GetResource<UniformBuffBindInfo>(ub));
374
375 for (Uint32 s = 0; s < GetNumResources<TextureBindInfo>(); ++s)
376 HandleTexture(GetResource<TextureBindInfo>(s));
377
378 for (Uint32 i = 0; i < GetNumResources<ImageBindInfo>(); ++i)
379 HandleImage(GetResource<ImageBindInfo>(i));
380
381 for (Uint32 s = 0; s < GetNumResources<StorageBufferBindInfo>(); ++s)
382 HandleStorageBuffer(GetResource<StorageBufferBindInfo>(s));
383 }
384
385 template <typename THandleUB,
386 typename THandleTexture,
387 typename THandleImage,
388 typename THandleStorageBuffer>
389 void HandleConstResources(THandleUB HandleUB,
390 THandleTexture HandleTexture,
391 THandleImage HandleImage,
392 THandleStorageBuffer HandleStorageBuffer) const
393 {
394 for (Uint32 ub = 0; ub < GetNumResources<UniformBuffBindInfo>(); ++ub)
395 HandleUB(GetConstResource<UniformBuffBindInfo>(ub));
396
397 for (Uint32 s = 0; s < GetNumResources<TextureBindInfo>(); ++s)
398 HandleTexture(GetConstResource<TextureBindInfo>(s));
399
400 for (Uint32 i = 0; i < GetNumResources<ImageBindInfo>(); ++i)
401 HandleImage(GetConstResource<ImageBindInfo>(i));
402
403 for (Uint32 s = 0; s < GetNumResources<StorageBufferBindInfo>(); ++s)
404 HandleStorageBuffer(GetConstResource<StorageBufferBindInfo>(s));
405 }
406
407 friend class ShaderVariableIndexLocator;
408 friend class ShaderVariableLocator;
409
410 private:
411 PipelineResourceSignatureGLImpl const* m_pSignature = nullptr;
412
413 IObject& m_Owner;
414 // No need to use shared pointer, as the resource cache is either part of the same
415 // ShaderGLImpl object, or ShaderResourceBindingGLImpl object
416 ShaderResourceCacheGL& m_ResourceCache;
417 void* m_ResourceBuffer = nullptr;
418
419 static constexpr OffsetType m_UBOffset = 0;
420 OffsetType m_TextureOffset = 0;
421 OffsetType m_ImageOffset = 0;
422 OffsetType m_StorageBufferOffset = 0;
423 OffsetType m_VariableEndOffset = 0;
424
425 #ifdef DILIGENT_DEBUG
426 IMemoryAllocator* m_pDbgAllocator = nullptr;
427 #endif
428 };
429
430
431 template <>
432 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::UniformBuffBindInfo>() const
433 {
434 return GetNumUBs();
435 }
436
437 template <>
438 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::TextureBindInfo>() const
439 {
440 return GetNumTextures();
441 }
442
443 template <>
444 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::ImageBindInfo>() const
445 {
446 return GetNumImages();
447 }
448
449 template <>
450 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::StorageBufferBindInfo>() const
451 {
452 return GetNumStorageBuffers();
453 }
454
455
456
457 template <>
458 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
459 GetResourceOffset<ShaderVariableManagerGL::UniformBuffBindInfo>() const
460 {
461 return m_UBOffset;
462 }
463
464 template <>
465 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
466 GetResourceOffset<ShaderVariableManagerGL::TextureBindInfo>() const
467 {
468 return m_TextureOffset;
469 }
470
471 template <>
472 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
473 GetResourceOffset<ShaderVariableManagerGL::ImageBindInfo>() const
474 {
475 return m_ImageOffset;
476 }
477
478 template <>
479 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
480 GetResourceOffset<ShaderVariableManagerGL::StorageBufferBindInfo>() const
481 {
482 return m_StorageBufferOffset;
483 }
484
485 } // namespace Diligent
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 // ShaderVariableManagerGL class manages resource bindings for all stages in a pipeline
30
31 //
32 //
33 // To program resource cache
34 //
35 // A A A A A A A A
36 // | | | | | | | |
37 // Binding Binding Binding Binding Binding Binding Binding Binding
38 // ___________________ ____|__________|__________________|________|______________|___________|______________|____________|____________
39 // | | | | | | | | | | | | | | |
40 // | ShaderResourcesGL |--------------->| UB[0] | UB[1] | ... | Sam[0] | Sam[1] | ... | Img[0] | Img[1] | ... | SSBOs[0] | SSBOs[1] | ... |
41 // |___________________| |__________|__________|_______|________|________|_______|________|________|_______|__________|__________|_______|
42 // A A A A
43 // | | | |
44 // Ref Ref Ref Ref
45 // .-==========================-. _____|____________________________________|________________________|____________________________|______________
46 // || || | | | | | | | | | | |
47 // __|| ShaderVariableManagerGL ||------->| UBInfo[0] | UBInfo[1] | ... | SamInfo[0] | SamInfo[1] | ... | ImgInfo[0] | ... | SSBO[0] | ... |
48 // | || || |___________|___________|_______|____________|____________|_______|____________|_________|___________|__________|
49 // | '-==========================-' / \
50 // | Ref Ref
51 // | / \
52 // | ___________________ ________V________________________________________________V_____________________________________________________
53 // | | | | | | | | | | | | | | | |
54 // | | ShaderResourcesGL |--------------->| UB[0] | UB[1] | ... | Sam[0] | Sam[1] | ... | Img[0] | Img[1] | ... | SSBOs[0] | SSBOs[1] | ... |
55 // | |___________________| |__________|__________|_______|________|________|_______|________|________|_______|__________|__________|_______|
56 // | | | | | | | | |
57 // | Binding Binding Binding Binding Binding Binding Binding Binding
58 // | | | | | | | | |
59 // | _______________________ ____V___________V________________V_________V________________V________V________________V___________V_____________
60 // | | | | | | | |
61 // '-->| ShaderResourceCacheGL |----------->| Uinform Buffers | Textures | Images | Storge Buffers |
62 // |_______________________| |___________________________|___________________________|___________________________|___________________________|
63 //
64 //
65 // Note that ShaderResourcesGL are kept by PipelineStateGLImpl. ShaderVariableManagerGL class is either part of the same PSO class,
66 // or part of ShaderResourceBindingGLImpl object that keeps a strong reference to the pipeline. So all references from GLVariableBase
67 // are always valid.
68
69 #include <array>
70
71 #include "Object.h"
72 #include "PipelineResourceAttribsGL.hpp"
73 #include "ShaderResourceVariableBase.hpp"
74 #include "ShaderResourceCacheGL.hpp"
75
76 namespace Diligent
77 {
78
79 class PipelineResourceSignatureGLImpl;
80
81 // sizeof(ShaderVariableManagerGL) == 48 (x64, msvc, Release)
82 class ShaderVariableManagerGL
83 {
84 public:
85 ShaderVariableManagerGL(IObject& Owner, ShaderResourceCacheGL& ResourceCache) noexcept :
86 m_Owner(Owner),
87 m_ResourceCache{ResourceCache}
88 {}
89
90 ~ShaderVariableManagerGL();
91
92 void Destroy(IMemoryAllocator& Allocator);
93
94 // No copies, only moves are allowed
95 // clang-format off
96 ShaderVariableManagerGL (const ShaderVariableManagerGL&) = delete;
97 ShaderVariableManagerGL& operator = (const ShaderVariableManagerGL&) = delete;
98 ShaderVariableManagerGL ( ShaderVariableManagerGL&&) = default;
99 ShaderVariableManagerGL& operator = ( ShaderVariableManagerGL&&) = delete;
100 // clang-format on
101
102 void Initialize(const PipelineResourceSignatureGLImpl& Signature,
103 IMemoryAllocator& Allocator,
104 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
105 Uint32 NumAllowedTypes,
106 SHADER_TYPE ShaderType);
107
108 static size_t GetRequiredMemorySize(const PipelineResourceSignatureGLImpl& Signature,
109 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
110 Uint32 NumAllowedTypes,
111 SHADER_TYPE ShaderType);
112
113 using ResourceAttribs = PipelineResourceAttribsGL;
114
115 // These two methods can't be implemented in the header because they depend on PipelineResourceSignatureGLImpl
116 const PipelineResourceDesc& GetResourceDesc(Uint32 Index) const;
117 const ResourceAttribs& GetAttribs(Uint32 Index) const;
118
119
120 struct GLVariableBase : public ShaderVariableBase<ShaderVariableManagerGL>
121 {
122 public:
123 using TBase = ShaderVariableBase<ShaderVariableManagerGL>;
124 GLVariableBase(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
125 TBase{ParentLayout},
126 m_ResIndex{ResIndex}
127 {}
128
129 const PipelineResourceDesc& GetDesc() const { return m_ParentManager.GetResourceDesc(m_ResIndex); }
130 const ResourceAttribs& GetAttribs() const { return m_ParentManager.GetAttribs(m_ResIndex); }
131
132 virtual SHADER_RESOURCE_VARIABLE_TYPE DILIGENT_CALL_TYPE GetType() const override final
133 {
134 return GetDesc().VarType;
135 }
136
137 virtual void DILIGENT_CALL_TYPE GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final
138 {
139 const auto& Desc = GetDesc();
140 ResourceDesc.Name = Desc.Name;
141 ResourceDesc.Type = Desc.ResourceType;
142 ResourceDesc.ArraySize = Desc.ArraySize;
143 }
144
145 virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final
146 {
147 return m_ParentManager.GetVariableIndex(*this);
148 }
149
150 private:
151 const Uint32 m_ResIndex;
152 };
153
154
155 struct UniformBuffBindInfo final : GLVariableBase
156 {
157 UniformBuffBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
158 GLVariableBase{ParentLayout, ResIndex}
159 {}
160
161 // Non-virtual function
162 void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
163
164 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
165 {
166 BindResource(pObject, 0);
167 }
168
169 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
170 Uint32 FirstElement,
171 Uint32 NumElements) override final
172 {
173 const auto& Desc = GetDesc();
174 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
175 for (Uint32 elem = 0; elem < NumElements; ++elem)
176 BindResource(ppObjects[elem], FirstElement + elem);
177 }
178
179 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
180 {
181 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
182 return m_ParentManager.m_ResourceCache.IsUBBound(GetAttribs().CacheOffset + ArrayIndex);
183 }
184 };
185
186
187 struct TextureBindInfo final : GLVariableBase
188 {
189 TextureBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
190 GLVariableBase{ParentLayout, ResIndex}
191 {}
192
193 // Non-virtual function
194 void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
195
196 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
197 {
198 BindResource(pObject, 0);
199 }
200
201 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
202 Uint32 FirstElement,
203 Uint32 NumElements) override final
204 {
205 const auto& Desc = GetDesc();
206 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
207 for (Uint32 elem = 0; elem < NumElements; ++elem)
208 BindResource(ppObjects[elem], FirstElement + elem);
209 }
210
211 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
212 {
213 const auto& Desc = GetDesc();
214 VERIFY_EXPR(ArrayIndex < Desc.ArraySize);
215 const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
216 return m_ParentManager.m_ResourceCache.IsTextureBound(GetAttribs().CacheOffset + ArrayIndex, IsTexView);
217 }
218 };
219
220
221 struct ImageBindInfo final : GLVariableBase
222 {
223 ImageBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
224 GLVariableBase{ParentLayout, ResIndex}
225 {}
226
227 // Provide non-virtual function
228 void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
229
230 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
231 {
232 BindResource(pObject, 0);
233 }
234
235 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
236 Uint32 FirstElement,
237 Uint32 NumElements) override final
238 {
239 const auto& Desc = GetDesc();
240 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
241 for (Uint32 elem = 0; elem < NumElements; ++elem)
242 BindResource(ppObjects[elem], FirstElement + elem);
243 }
244
245 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
246 {
247 const auto& Desc = GetDesc();
248 VERIFY_EXPR(ArrayIndex < Desc.ArraySize);
249 const bool IsImgView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
250 return m_ParentManager.m_ResourceCache.IsImageBound(GetAttribs().CacheOffset + ArrayIndex, IsImgView);
251 }
252 };
253
254
255 struct StorageBufferBindInfo final : GLVariableBase
256 {
257 StorageBufferBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
258 GLVariableBase{ParentLayout, ResIndex}
259 {}
260
261 // Non-virtual function
262 void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
263
264 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
265 {
266 BindResource(pObject, 0);
267 }
268
269 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
270 Uint32 FirstElement,
271 Uint32 NumElements) override final
272 {
273 const auto& Desc = GetDesc();
274 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
275 for (Uint32 elem = 0; elem < NumElements; ++elem)
276 BindResource(ppObjects[elem], FirstElement + elem);
277 }
278
279 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
280 {
281 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
282 return m_ParentManager.m_ResourceCache.IsSSBOBound(GetAttribs().CacheOffset + ArrayIndex);
283 }
284 };
285
286
287 // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive
288 // while Layout is alive
289 void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags);
290
291 #ifdef DILIGENT_DEVELOPMENT
292 bool dvpVerifyBindings(const ShaderResourceCacheGL& ResourceCache) const;
293 #endif
294
295 IShaderResourceVariable* GetVariable(const Char* Name) const;
296 IShaderResourceVariable* GetVariable(Uint32 Index) const;
297
298 IObject& GetOwner() { return m_Owner; }
299
300 Uint32 GetVariableCount() const;
301
302 // clang-format off
303 Uint32 GetNumUBs() const { return (m_TextureOffset - m_UBOffset) / sizeof(UniformBuffBindInfo); }
304 Uint32 GetNumTextures() const { return (m_ImageOffset - m_TextureOffset) / sizeof(TextureBindInfo); }
305 Uint32 GetNumImages() const { return (m_StorageBufferOffset - m_ImageOffset) / sizeof(ImageBindInfo) ; }
306 Uint32 GetNumStorageBuffers() const { return (m_VariableEndOffset - m_StorageBufferOffset) / sizeof(StorageBufferBindInfo); }
307 // clang-format on
308
309 template <typename ResourceType> Uint32 GetNumResources() const;
310
311 template <typename ResourceType>
312 const ResourceType& GetConstResource(Uint32 ResIndex) const
313 {
314 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>(), ")");
315 auto Offset = GetResourceOffset<ResourceType>();
316 return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
317 }
318
319 Uint32 GetVariableIndex(const GLVariableBase& Var) const;
320
321 private:
322 struct ResourceCounters
323 {
324 Uint32 NumUBs = 0;
325 Uint32 NumTextures = 0;
326 Uint32 NumImages = 0;
327 Uint32 NumStorageBlocks = 0;
328 };
329 static void CountResources(const PipelineResourceSignatureGLImpl& Signature,
330 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
331 Uint32 NumAllowedTypes,
332 SHADER_TYPE ShaderType,
333 ResourceCounters& Counters);
334
335 template <typename HandlerType>
336 static void ProcessSignatureResources(const PipelineResourceSignatureGLImpl& Signature,
337 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
338 Uint32 NumAllowedTypes,
339 SHADER_TYPE ShaderType,
340 HandlerType Handler);
341
342 // Offsets in bytes
343 using OffsetType = Uint16;
344
345 template <typename ResourceType> OffsetType GetResourceOffset() const;
346
347 template <typename ResourceType>
348 ResourceType& GetResource(Uint32 ResIndex) const
349 {
350 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>() - 1, ")");
351 auto Offset = GetResourceOffset<ResourceType>();
352 return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
353 }
354
355 template <typename ResourceType>
356 IShaderResourceVariable* GetResourceByName(const Char* Name) const;
357
358 template <typename THandleUB,
359 typename THandleTexture,
360 typename THandleImage,
361 typename THandleStorageBuffer>
362 void HandleResources(THandleUB HandleUB,
363 THandleTexture HandleTexture,
364 THandleImage HandleImage,
365 THandleStorageBuffer HandleStorageBuffer)
366 {
367 for (Uint32 ub = 0; ub < GetNumResources<UniformBuffBindInfo>(); ++ub)
368 HandleUB(GetResource<UniformBuffBindInfo>(ub));
369
370 for (Uint32 s = 0; s < GetNumResources<TextureBindInfo>(); ++s)
371 HandleTexture(GetResource<TextureBindInfo>(s));
372
373 for (Uint32 i = 0; i < GetNumResources<ImageBindInfo>(); ++i)
374 HandleImage(GetResource<ImageBindInfo>(i));
375
376 for (Uint32 s = 0; s < GetNumResources<StorageBufferBindInfo>(); ++s)
377 HandleStorageBuffer(GetResource<StorageBufferBindInfo>(s));
378 }
379
380 template <typename THandleUB,
381 typename THandleTexture,
382 typename THandleImage,
383 typename THandleStorageBuffer>
384 void HandleConstResources(THandleUB HandleUB,
385 THandleTexture HandleTexture,
386 THandleImage HandleImage,
387 THandleStorageBuffer HandleStorageBuffer) const
388 {
389 for (Uint32 ub = 0; ub < GetNumResources<UniformBuffBindInfo>(); ++ub)
390 HandleUB(GetConstResource<UniformBuffBindInfo>(ub));
391
392 for (Uint32 s = 0; s < GetNumResources<TextureBindInfo>(); ++s)
393 HandleTexture(GetConstResource<TextureBindInfo>(s));
394
395 for (Uint32 i = 0; i < GetNumResources<ImageBindInfo>(); ++i)
396 HandleImage(GetConstResource<ImageBindInfo>(i));
397
398 for (Uint32 s = 0; s < GetNumResources<StorageBufferBindInfo>(); ++s)
399 HandleStorageBuffer(GetConstResource<StorageBufferBindInfo>(s));
400 }
401
402 friend class ShaderVariableIndexLocator;
403 friend class ShaderVariableLocator;
404
405 private:
406 PipelineResourceSignatureGLImpl const* m_pSignature = nullptr;
407
408 IObject& m_Owner;
409 // No need to use shared pointer, as the resource cache is either part of the same
410 // ShaderGLImpl object, or ShaderResourceBindingGLImpl object
411 ShaderResourceCacheGL& m_ResourceCache;
412 void* m_ResourceBuffer = nullptr;
413
414 static constexpr OffsetType m_UBOffset = 0;
415 OffsetType m_TextureOffset = 0;
416 OffsetType m_ImageOffset = 0;
417 OffsetType m_StorageBufferOffset = 0;
418 OffsetType m_VariableEndOffset = 0;
419
420 #ifdef DILIGENT_DEBUG
421 IMemoryAllocator* m_pDbgAllocator = nullptr;
422 #endif
423 };
424
425
426 template <>
427 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::UniformBuffBindInfo>() const
428 {
429 return GetNumUBs();
430 }
431
432 template <>
433 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::TextureBindInfo>() const
434 {
435 return GetNumTextures();
436 }
437
438 template <>
439 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::ImageBindInfo>() const
440 {
441 return GetNumImages();
442 }
443
444 template <>
445 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::StorageBufferBindInfo>() const
446 {
447 return GetNumStorageBuffers();
448 }
449
450
451
452 template <>
453 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
454 GetResourceOffset<ShaderVariableManagerGL::UniformBuffBindInfo>() const
455 {
456 return m_UBOffset;
457 }
458
459 template <>
460 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
461 GetResourceOffset<ShaderVariableManagerGL::TextureBindInfo>() const
462 {
463 return m_TextureOffset;
464 }
465
466 template <>
467 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
468 GetResourceOffset<ShaderVariableManagerGL::ImageBindInfo>() const
469 {
470 return m_ImageOffset;
471 }
472
473 template <>
474 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
475 GetResourceOffset<ShaderVariableManagerGL::StorageBufferBindInfo>() const
476 {
477 return m_StorageBufferOffset;
478 }
479
480 } // namespace Diligent
2626
2727 #pragma once
2828
29 #include "BaseInterfacesGL.h"
29 #include "EngineGLImplTraits.hpp"
3030 #include "TextureGL.h"
3131 #include "TextureBase.hpp"
32 #include "RenderDevice.h"
32 #include "TextureViewGLImpl.hpp" // Required by TextureBase
3333 #include "GLObjectWrapper.hpp"
34 #include "TextureViewGLImpl.hpp"
3534 #include "AsyncWritableResource.hpp"
36 #include "RenderDeviceGLImpl.hpp"
3735 #include "GLContextState.hpp"
3836
3937 namespace Diligent
2626
2727 #pragma once
2828
29 #include "BaseInterfacesGL.h"
29 #include "EngineGLImplTraits.hpp"
3030 #include "TextureViewGL.h"
3131 #include "TextureViewBase.hpp"
32 #include "RenderDevice.h"
3332 #include "GLObjectWrapper.hpp"
34 #include "RenderDeviceGLImpl.hpp"
3533
3634 namespace Diligent
3735 {
38
39 class FixedBlockMemoryAllocator;
4036
4137 /// Texture view implementation in OpenGL backend.
4238 class TextureViewGLImpl final : public TextureViewBase<EngineGLImplTraits>
2727 #pragma once
2828
2929 #include <cstring>
30
3031 #include "GraphicsTypes.h"
3132 #include "Buffer.h"
3233 #include "InputLayout.h"
3334 #include "LockHelper.hpp"
3435 #include "HashUtils.hpp"
3536 #include "DeviceContextBase.hpp"
36 #include "BaseInterfacesGL.h"
3737
3838 namespace Diligent
3939 {
2727 #include "pch.h"
2828
2929 #include "BufferGLImpl.hpp"
30
3031 #include "RenderDeviceGLImpl.hpp"
32 #include "DeviceContextGLImpl.hpp"
33
3134 #include "GLTypeConversions.hpp"
32 #include "BufferViewGLImpl.hpp"
33 #include "DeviceContextGLImpl.hpp"
3435 #include "EngineMemory.h"
3536
3637 namespace Diligent
2626
2727 #include "pch.h"
2828
29 #include "BufferViewGLImpl.hpp"
30
2931 #include "RenderDeviceGLImpl.hpp"
3032 #include "DeviceContextGLImpl.hpp"
31 #include "BufferViewGLImpl.hpp"
3233 #include "BufferGLImpl.hpp"
34
3335 #include "GLTypeConversions.hpp"
3436
3537 namespace Diligent
102104
103105 IMPLEMENT_QUERY_INTERFACE(BufferViewGLImpl, IID_BufferViewGL, TBuffViewBase)
104106
107 BufferViewGLImpl::~BufferViewGLImpl()
108 {
109 }
110
105111 } // namespace Diligent
2525 */
2626
2727 #include "pch.h"
28
29 #include "DeviceContextGLImpl.hpp"
30
2831 #include <iostream>
2932 #include <fstream>
3033 #include <string>
3134 #include <array>
3235
3336 #include "SwapChainGL.h"
34 #include "DeviceContextGLImpl.hpp"
37
3538 #include "RenderDeviceGLImpl.hpp"
36 #include "GLTypeConversions.hpp"
37
3839 #include "BufferGLImpl.hpp"
3940 #include "ShaderGLImpl.hpp"
40 #include "VAOCache.hpp"
4141 #include "Texture1D_OGL.hpp"
4242 #include "Texture1DArray_OGL.hpp"
4343 #include "Texture2D_OGL.hpp"
4444 #include "Texture2DArray_OGL.hpp"
4545 #include "Texture3D_OGL.hpp"
4646 #include "SamplerGLImpl.hpp"
47 #include "GraphicsAccessories.hpp"
4847 #include "BufferViewGLImpl.hpp"
4948 #include "PipelineStateGLImpl.hpp"
5049 #include "FenceGLImpl.hpp"
5150 #include "ShaderResourceBindingGLImpl.hpp"
5251
53 using namespace std;
52 #include "GLTypeConversions.hpp"
53 #include "VAOCache.hpp"
54 #include "GraphicsAccessories.hpp"
55
5456
5557 namespace Diligent
5658 {
2727 #include "pch.h"
2828
2929 #include "FenceGLImpl.hpp"
30 #include "RenderDeviceGLImpl.hpp"
3031 #include "EngineMemory.h"
3132
3233 namespace Diligent
2727 #include "pch.h"
2828
2929 #include "FramebufferGLImpl.hpp"
30 #include "RenderDeviceGLImpl.hpp"
31 #include "TextureViewGLImpl.hpp"
3032 #include "FBOCache.hpp"
31 #include "TextureViewGLImpl.hpp"
33 #include "GLContextState.hpp"
3234
3335 namespace Diligent
3436 {
2727 #include "pch.h"
2828
2929 #include "GLContextState.hpp"
30
31 #include "BufferViewGLImpl.hpp"
32 #include "RenderDeviceGLImpl.hpp"
3033 #include "TextureBaseGL.hpp"
3134 #include "SamplerGLImpl.hpp"
35
3236 #include "AsyncWritableResource.hpp"
3337 #include "GLTypeConversions.hpp"
34 #include "BufferViewGLImpl.hpp"
35 #include "RenderDeviceGLImpl.hpp"
3638
3739 using namespace GLObjectWrappers;
3840
2727 #include "pch.h"
2828 #include "PipelineResourceSignatureGLImpl.hpp"
2929 #include "RenderDeviceGLImpl.hpp"
30 #include "ShaderResourceBindingGLImpl.hpp"
31 #include "ShaderVariableGL.hpp"
3230
3331 namespace Diligent
3432 {
420418 State.SetProgram(GLObjectWrappers::GLProgramObj::Null());
421419 }
422420
423 void PipelineResourceSignatureGLImpl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding,
424 bool InitStaticResources)
425 {
426 CreateShaderResourceBindingImpl(ppShaderResourceBinding, InitStaticResources);
427 }
428
429421 void PipelineResourceSignatureGLImpl::InitializeStaticSRBResources(IShaderResourceBinding* pSRB) const
430422 {
431423 InitializeStaticSRBResourcesImpl(ValidatedCast<ShaderResourceBindingGLImpl>(pSRB),
434426 CopyStaticResources(pSRBGL->GetResourceCache());
435427 } //
436428 );
437 }
438
439 Uint32 PipelineResourceSignatureGLImpl::GetStaticVariableCount(SHADER_TYPE ShaderType) const
440 {
441 return GetStaticVariableCountImpl(ShaderType);
442 }
443
444 IShaderResourceVariable* PipelineResourceSignatureGLImpl::GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name)
445 {
446 return GetStaticVariableByNameImpl(ShaderType, Name);
447 }
448
449 IShaderResourceVariable* PipelineResourceSignatureGLImpl::GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index)
450 {
451 return GetStaticVariableByIndexImpl(ShaderType, Index);
452 }
453
454 void PipelineResourceSignatureGLImpl::BindStaticResources(Uint32 ShaderFlags,
455 IResourceMapping* pResMapping,
456 Uint32 Flags)
457 {
458 BindStaticResourcesImpl(ShaderFlags, pResMapping, Flags);
459429 }
460430
461431 void PipelineResourceSignatureGLImpl::CopyStaticResources(ShaderResourceCacheGL& DstResourceCache) const
3131 #endif
3232
3333 #include "PipelineStateGLImpl.hpp"
34
3435 #include "RenderDeviceGLImpl.hpp"
35 #include "ShaderGLImpl.hpp"
36 #include "DeviceContextGLImpl.hpp"
3637 #include "ShaderResourceBindingGLImpl.hpp"
38
3739 #include "EngineMemory.h"
38 #include "DeviceContextGLImpl.hpp"
3940
4041 namespace Diligent
4142 {
2727 #include "pch.h"
2828
2929 #include "QueryGLImpl.hpp"
30 #include "RenderDeviceGLImpl.hpp"
3031 #include "EngineMemory.h"
3132
3233 namespace Diligent
3030
3131 #include "BufferGLImpl.hpp"
3232 #include "ShaderGLImpl.hpp"
33 #include "VAOCache.hpp"
3433 #include "Texture1D_OGL.hpp"
3534 #include "Texture1DArray_OGL.hpp"
3635 #include "Texture2D_OGL.hpp"
4039 #include "TextureCubeArray_OGL.hpp"
4140 #include "SamplerGLImpl.hpp"
4241 #include "DeviceContextGLImpl.hpp"
43 #include "GLTypeConversions.hpp"
4442 #include "PipelineStateGLImpl.hpp"
4543 #include "ShaderResourceBindingGLImpl.hpp"
4644 #include "FenceGLImpl.hpp"
4846 #include "RenderPassGLImpl.hpp"
4947 #include "FramebufferGLImpl.hpp"
5048 #include "PipelineResourceSignatureGLImpl.hpp"
49
50 #include "GLTypeConversions.hpp"
51 #include "VAOCache.hpp"
5152 #include "EngineMemory.h"
5253 #include "StringTools.hpp"
5354
2727 #include "pch.h"
2828
2929 #include "RenderPassGLImpl.hpp"
30 #include "RenderDeviceGLImpl.hpp"
3031 #include "EngineMemory.h"
3132
3233 namespace Diligent
2626
2727 #include "pch.h"
2828
29 #include "ShaderGLImpl.hpp"
30
2931 #include <array>
3032
31 #include "ShaderGLImpl.hpp"
3233 #include "RenderDeviceGLImpl.hpp"
3334 #include "DeviceContextGLImpl.hpp"
3435 #include "DataBlobImpl.hpp"
2525 */
2626
2727 #include "pch.h"
28
2829 #include "ShaderResourceBindingGLImpl.hpp"
30
31 #include "RenderDeviceGLImpl.hpp"
2932 #include "PipelineStateGLImpl.hpp"
3033 #include "ShaderGLImpl.hpp"
34 #include "PipelineResourceSignatureGLImpl.hpp"
35
3136 #include "FixedBlockMemoryAllocator.hpp"
3237
3338 namespace Diligent
2626
2727 #include "pch.h"
2828 #include "ShaderResourceCacheGL.hpp"
29 #include "RenderDeviceGLImpl.hpp"
2930 #include "PipelineResourceSignatureGLImpl.hpp"
3031 #include "GLTypeConversions.hpp"
3132
2525 */
2626
2727 #include "pch.h"
28
29 #include "ShaderResourcesGL.hpp"
30
2831 #include <unordered_set>
32
33 #include "RenderDeviceGLImpl.hpp"
2934 #include "GLContextState.hpp"
30 #include "ShaderResourcesGL.hpp"
31 #include "RenderDeviceGLImpl.hpp"
32 #include "ShaderResourceBindingBase.hpp"
3335 #include "ShaderResourceVariableBase.hpp"
3436 #include "Align.hpp"
3537
+0
-682
Graphics/GraphicsEngineOpenGL/src/ShaderVariableGL.cpp less more
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #include "pch.h"
28 #include <array>
29 #include "ShaderVariableGL.hpp"
30 #include "PipelineResourceSignatureGLImpl.hpp"
31 #include "Align.hpp"
32 #include "PlatformMisc.hpp"
33 #include "ShaderBase.hpp"
34
35 namespace Diligent
36 {
37
38 void ShaderVariableManagerGL::CountResources(const PipelineResourceSignatureGLImpl& Signature,
39 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
40 Uint32 NumAllowedTypes,
41 const SHADER_TYPE ShaderType,
42 ResourceCounters& Counters)
43 {
44 ProcessSignatureResources(
45 Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
46 [&](Uint32 Index) //
47 {
48 const auto& ResDesc = Signature.GetResourceDesc(Index);
49 static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range");
50 switch (PipelineResourceToBindingRange(ResDesc))
51 {
52 // clang-format off
53 case BINDING_RANGE_UNIFORM_BUFFER: ++Counters.NumUBs; break;
54 case BINDING_RANGE_TEXTURE: ++Counters.NumTextures; break;
55 case BINDING_RANGE_IMAGE: ++Counters.NumImages; break;
56 case BINDING_RANGE_STORAGE_BUFFER: ++Counters.NumStorageBlocks; break;
57 // clang-format on
58 default:
59 UNEXPECTED("Unsupported resource type.");
60 }
61 });
62 }
63
64 template <typename HandlerType>
65 void ShaderVariableManagerGL::ProcessSignatureResources(const PipelineResourceSignatureGLImpl& Signature,
66 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
67 Uint32 NumAllowedTypes,
68 SHADER_TYPE ShaderType,
69 HandlerType Handler)
70 {
71 const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
72
73 for (Uint32 var_type = 0; var_type < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; ++var_type)
74 {
75 const auto VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(var_type);
76 if (IsAllowedType(VarType, AllowedTypeBits))
77 {
78 const auto ResIdxRange = Signature.GetResourceIndexRange(VarType);
79 for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r)
80 {
81 const auto& Res = Signature.GetResourceDesc(r);
82 VERIFY_EXPR(Res.VarType == VarType);
83
84 if ((Res.ShaderStages & ShaderType) == 0)
85 continue;
86
87 if (Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER)
88 continue;
89
90 Handler(r);
91 }
92 }
93 }
94 }
95
96 size_t ShaderVariableManagerGL::GetRequiredMemorySize(const PipelineResourceSignatureGLImpl& Signature,
97 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
98 Uint32 NumAllowedTypes,
99 SHADER_TYPE ShaderType)
100 {
101 ResourceCounters Counters;
102 CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters);
103
104 // clang-format off
105 size_t RequiredSize = Counters.NumUBs * sizeof(UniformBuffBindInfo) +
106 Counters.NumTextures * sizeof(TextureBindInfo) +
107 Counters.NumImages * sizeof(ImageBindInfo) +
108 Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo);
109 // clang-format on
110 return RequiredSize;
111 }
112
113 void ShaderVariableManagerGL::Initialize(const PipelineResourceSignatureGLImpl& Signature,
114 IMemoryAllocator& Allocator,
115 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
116 Uint32 NumAllowedTypes,
117 SHADER_TYPE ShaderType)
118 {
119 #ifdef DILIGENT_DEBUG
120 m_pDbgAllocator = &Allocator;
121 #endif
122
123 ResourceCounters Counters;
124 CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters);
125
126 m_pSignature = &Signature;
127
128 // Initialize offsets
129 size_t CurrentOffset = 0;
130
131 auto AdvanceOffset = [&CurrentOffset](size_t NumBytes) //
132 {
133 constexpr size_t MaxOffset = std::numeric_limits<OffsetType>::max();
134 VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")");
135 (void)MaxOffset;
136 auto Offset = static_cast<OffsetType>(CurrentOffset);
137 CurrentOffset += NumBytes;
138 return Offset;
139 };
140
141 // clang-format off
142 auto UBOffset = AdvanceOffset(Counters.NumUBs * sizeof(UniformBuffBindInfo) ); (void)UBOffset; // To suppress warning
143 m_TextureOffset = AdvanceOffset(Counters.NumTextures * sizeof(TextureBindInfo) );
144 m_ImageOffset = AdvanceOffset(Counters.NumImages * sizeof(ImageBindInfo) );
145 m_StorageBufferOffset = AdvanceOffset(Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo));
146 m_VariableEndOffset = AdvanceOffset(0);
147 // clang-format off
148 auto TotalMemorySize = m_VariableEndOffset;
149 VERIFY_EXPR(TotalMemorySize == GetRequiredMemorySize(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType));
150
151 if (TotalMemorySize)
152 {
153 m_ResourceBuffer = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", TotalMemorySize);
154 }
155
156 // clang-format off
157 VERIFY_EXPR(Counters.NumUBs == GetNumUBs() );
158 VERIFY_EXPR(Counters.NumTextures == GetNumTextures() );
159 VERIFY_EXPR(Counters.NumImages == GetNumImages() );
160 VERIFY_EXPR(Counters.NumStorageBlocks == GetNumStorageBuffers());
161 // clang-format on
162
163 // Current resource index for every resource type
164 ResourceCounters VarCounters = {};
165
166 ProcessSignatureResources(
167 Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
168 [&](Uint32 Index) //
169 {
170 const auto& ResDesc = Signature.GetResourceDesc(Index);
171 static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range");
172 switch (PipelineResourceToBindingRange(ResDesc))
173 {
174 case BINDING_RANGE_UNIFORM_BUFFER:
175 new (&GetResource<UniformBuffBindInfo>(VarCounters.NumUBs++)) UniformBuffBindInfo{*this, Index};
176 break;
177 case BINDING_RANGE_TEXTURE:
178 new (&GetResource<TextureBindInfo>(VarCounters.NumTextures++)) TextureBindInfo{*this, Index};
179 break;
180 case BINDING_RANGE_IMAGE:
181 new (&GetResource<ImageBindInfo>(VarCounters.NumImages++)) ImageBindInfo{*this, Index};
182 break;
183 case BINDING_RANGE_STORAGE_BUFFER:
184 new (&GetResource<StorageBufferBindInfo>(VarCounters.NumStorageBlocks++)) StorageBufferBindInfo{*this, Index};
185 break;
186 default:
187 UNEXPECTED("Unsupported resource type.");
188 }
189 });
190
191 // clang-format off
192 VERIFY(VarCounters.NumUBs == GetNumUBs(), "Not all UBs are initialized which will cause a crash when dtor is called");
193 VERIFY(VarCounters.NumTextures == GetNumTextures(), "Not all Textures are initialized which will cause a crash when dtor is called");
194 VERIFY(VarCounters.NumImages == GetNumImages(), "Not all Images are initialized which will cause a crash when dtor is called");
195 VERIFY(VarCounters.NumStorageBlocks == GetNumStorageBuffers(), "Not all SSBOs are initialized which will cause a crash when dtor is called");
196 // clang-format on
197 }
198
199 ShaderVariableManagerGL::~ShaderVariableManagerGL()
200 {
201 VERIFY(m_ResourceBuffer == nullptr, "Destroy() has not been called");
202 }
203
204 void ShaderVariableManagerGL::Destroy(IMemoryAllocator& Allocator)
205 {
206 if (m_ResourceBuffer == nullptr)
207 return;
208
209 VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor");
210
211 HandleResources(
212 [&](UniformBuffBindInfo& ub) {
213 ub.~UniformBuffBindInfo();
214 },
215 [&](TextureBindInfo& tex) {
216 tex.~TextureBindInfo();
217 },
218 [&](ImageBindInfo& img) {
219 img.~ImageBindInfo();
220 },
221 [&](StorageBufferBindInfo& ssbo) {
222 ssbo.~StorageBufferBindInfo();
223 });
224
225 Allocator.Free(m_ResourceBuffer);
226 m_ResourceBuffer = nullptr;
227 }
228
229 void ShaderVariableManagerGL::UniformBuffBindInfo::BindResource(IDeviceObject* pBuffer,
230 Uint32 ArrayIndex)
231 {
232 const auto& Desc = GetDesc();
233 const auto& Attr = GetAttribs();
234
235 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
236 auto& ResourceCache = m_ParentManager.m_ResourceCache;
237
238 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER);
239
240 // We cannot use ValidatedCast<> here as the resource retrieved from the
241 // resource mapping can be of wrong type
242 RefCntAutoPtr<BufferGLImpl> pBuffGLImpl(pBuffer, IID_BufferGL);
243 #ifdef DILIGENT_DEVELOPMENT
244 {
245 const auto& CachedUB = ResourceCache.GetConstUB(Attr.CacheOffset + ArrayIndex);
246 VerifyConstantBufferBinding(Desc.Name, Desc.ArraySize, Desc.VarType, Desc.Flags, ArrayIndex, pBuffer, pBuffGLImpl.RawPtr(), CachedUB.pBuffer.RawPtr());
247 }
248 #endif
249
250 ResourceCache.SetUniformBuffer(Attr.CacheOffset + ArrayIndex, std::move(pBuffGLImpl));
251 }
252
253
254
255 void ShaderVariableManagerGL::TextureBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
256 {
257 const auto& Desc = GetDesc();
258 const auto& Attr = GetAttribs();
259
260 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
261 auto& ResourceCache = m_ParentManager.m_ResourceCache;
262
263 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV ||
264 Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT)
265 {
266 // We cannot use ValidatedCast<> here as the resource retrieved from the
267 // resource mapping can be of wrong type
268 RefCntAutoPtr<TextureViewGLImpl> pViewGL(pView, IID_TextureViewGL);
269 #ifdef DILIGENT_DEVELOPMENT
270 {
271 auto& CachedTexSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrayIndex);
272 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
273 pView, pViewGL.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE},
274 RESOURCE_DIM_UNDEFINED, false, CachedTexSampler.pView.RawPtr());
275 if (Attr.IsImmutableSamplerAssigned() && ResourceCache.StaticResourcesInitialized())
276 {
277 VERIFY(CachedTexSampler.pSampler != nullptr, "Immutable samplers must be initialized by PipelineResourceSignatureGLImpl::InitializeSRBResourceCache!");
278 }
279 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT)
280 {
281 DEV_CHECK_ERR(!Attr.IsSamplerAssigned(), "Input attachment must not have assigned sampler.");
282 }
283 }
284 #endif
285 ResourceCache.SetTexture(Attr.CacheOffset + ArrayIndex, std::move(pViewGL), !Attr.IsImmutableSamplerAssigned());
286 }
287 else if (Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV)
288 {
289 // We cannot use ValidatedCast<> here as the resource retrieved from the
290 // resource mapping can be of wrong type
291 RefCntAutoPtr<BufferViewGLImpl> pViewGL(pView, IID_BufferViewGL);
292 #ifdef DILIGENT_DEVELOPMENT
293 {
294 auto& CachedBuffSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrayIndex);
295 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
296 pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE},
297 RESOURCE_DIM_BUFFER, false, CachedBuffSampler.pView.RawPtr());
298 if (pViewGL != nullptr)
299 {
300 const auto& ViewDesc = pViewGL->GetDesc();
301 const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
302 if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW))
303 {
304 LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
305 Desc.Name, ": formatted buffer view is expected.");
306 }
307 }
308 }
309 #endif
310 VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0);
311 ResourceCache.SetTexelBuffer(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
312 }
313 else
314 {
315 UNEXPECTED("Unexpected resource type ", GetShaderResourceTypeLiteralName(Desc.ResourceType), ". Texture SRV or buffer SRV is expected.");
316 }
317 }
318
319
320 void ShaderVariableManagerGL::ImageBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
321 {
322 const auto& Desc = GetDesc();
323 const auto& Attr = GetAttribs();
324
325 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
326 auto& ResourceCache = m_ParentManager.m_ResourceCache;
327
328 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV)
329 {
330 // We cannot use ValidatedCast<> here as the resource retrieved from the
331 // resource mapping can be of wrong type
332 RefCntAutoPtr<TextureViewGLImpl> pViewGL(pView, IID_TextureViewGL);
333 #ifdef DILIGENT_DEVELOPMENT
334 {
335 auto& CachedUAV = ResourceCache.GetConstImage(Attr.CacheOffset + ArrayIndex);
336 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
337 pView, pViewGL.RawPtr(), {TEXTURE_VIEW_UNORDERED_ACCESS},
338 RESOURCE_DIM_UNDEFINED, false, CachedUAV.pView.RawPtr());
339 }
340 #endif
341 ResourceCache.SetTexImage(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
342 }
343 else if (Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV)
344 {
345 // We cannot use ValidatedCast<> here as the resource retrieved from the
346 // resource mapping can be of wrong type
347 RefCntAutoPtr<BufferViewGLImpl> pViewGL(pView, IID_BufferViewGL);
348 #ifdef DILIGENT_DEVELOPMENT
349 {
350 auto& CachedUAV = ResourceCache.GetConstImage(Attr.CacheOffset + ArrayIndex);
351 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
352 pView, pViewGL.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS},
353 RESOURCE_DIM_BUFFER, false, CachedUAV.pView.RawPtr());
354 if (pViewGL != nullptr)
355 {
356 const auto& ViewDesc = pViewGL->GetDesc();
357 const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
358 if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW))
359 {
360 LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
361 Desc.Name, ": formatted buffer view is expected.");
362 }
363 }
364 }
365 #endif
366 VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0);
367 ResourceCache.SetBufImage(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
368 }
369 else
370 {
371 UNEXPECTED("Unexpected resource type ", GetShaderResourceTypeLiteralName(Desc.ResourceType), ". Texture UAV or buffer UAV is expected.");
372 }
373 }
374
375
376
377 void ShaderVariableManagerGL::StorageBufferBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
378 {
379 const auto& Desc = GetDesc();
380 const auto& Attr = GetAttribs();
381
382 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
383 auto& ResourceCache = m_ParentManager.m_ResourceCache;
384 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV ||
385 Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV);
386 VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) == 0);
387
388 // We cannot use ValidatedCast<> here as the resource retrieved from the
389 // resource mapping can be of wrong type
390 RefCntAutoPtr<BufferViewGLImpl> pViewGL(pView, IID_BufferViewGL);
391 #ifdef DILIGENT_DEVELOPMENT
392 {
393 auto& CachedSSBO = ResourceCache.GetConstSSBO(Attr.CacheOffset + ArrayIndex);
394 // HLSL structured buffers are mapped to SSBOs in GLSL
395 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
396 pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE, BUFFER_VIEW_UNORDERED_ACCESS},
397 RESOURCE_DIM_BUFFER, false, CachedSSBO.pBufferView.RawPtr());
398 if (pViewGL != nullptr)
399 {
400 const auto& ViewDesc = pViewGL->GetDesc();
401 const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
402 if (BuffDesc.Mode != BUFFER_MODE_STRUCTURED && BuffDesc.Mode != BUFFER_MODE_RAW)
403 {
404 LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
405 Desc.Name, ": structured buffer view is expected.");
406 }
407 }
408 }
409 #endif
410 ResourceCache.SetSSBO(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
411 }
412
413 void ShaderVariableManagerGL::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags)
414 {
415 if (pResourceMapping == nullptr)
416 {
417 LOG_ERROR_MESSAGE("Failed to bind resources: resource mapping is null");
418 return;
419 }
420
421 if ((Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0)
422 Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL;
423
424 HandleResources(
425 [&](UniformBuffBindInfo& ub) {
426 ub.BindResources<UniformBuffBindInfo>(pResourceMapping, Flags);
427 },
428 [&](TextureBindInfo& tex) {
429 tex.BindResources<TextureBindInfo>(pResourceMapping, Flags);
430 },
431 [&](ImageBindInfo& img) {
432 img.BindResources<ImageBindInfo>(pResourceMapping, Flags);
433 },
434 [&](StorageBufferBindInfo& ssbo) {
435 ssbo.BindResources<StorageBufferBindInfo>(pResourceMapping, Flags);
436 });
437 }
438
439
440 template <typename ResourceType>
441 IShaderResourceVariable* ShaderVariableManagerGL::GetResourceByName(const Char* Name) const
442 {
443 auto NumResources = GetNumResources<ResourceType>();
444 for (Uint32 res = 0; res < NumResources; ++res)
445 {
446 auto& Resource = GetResource<ResourceType>(res);
447 const auto& ResDesc = Resource.GetDesc();
448 if (strcmp(ResDesc.Name, Name) == 0)
449 return &Resource;
450 }
451
452 return nullptr;
453 }
454
455
456 IShaderResourceVariable* ShaderVariableManagerGL::GetVariable(const Char* Name) const
457 {
458 if (auto* pUB = GetResourceByName<UniformBuffBindInfo>(Name))
459 return pUB;
460
461 if (auto* pTexture = GetResourceByName<TextureBindInfo>(Name))
462 return pTexture;
463
464 if (auto* pImage = GetResourceByName<ImageBindInfo>(Name))
465 return pImage;
466
467 if (auto* pSSBO = GetResourceByName<StorageBufferBindInfo>(Name))
468 return pSSBO;
469
470 return nullptr;
471 }
472
473 Uint32 ShaderVariableManagerGL::GetVariableCount() const
474 {
475 return GetNumUBs() + GetNumTextures() + GetNumImages() + GetNumStorageBuffers();
476 }
477
478 class ShaderVariableLocator
479 {
480 public:
481 ShaderVariableLocator(const ShaderVariableManagerGL& _Layout,
482 Uint32 _Index) :
483 // clang-format off
484 Layout {_Layout},
485 Index {_Index}
486 // clang-format on
487 {
488 }
489
490 template <typename ResourceType>
491 IShaderResourceVariable* TryResource(Uint32 NumResources)
492 {
493 if (Index < NumResources)
494 return &Layout.GetResource<ResourceType>(Index);
495 else
496 {
497 Index -= NumResources;
498 return nullptr;
499 }
500 }
501
502 private:
503 ShaderVariableManagerGL const& Layout;
504 Uint32 Index;
505 };
506
507
508 IShaderResourceVariable* ShaderVariableManagerGL::GetVariable(Uint32 Index) const
509 {
510 ShaderVariableLocator VarLocator(*this, Index);
511
512 if (auto* pUB = VarLocator.TryResource<UniformBuffBindInfo>(GetNumUBs()))
513 return pUB;
514
515 if (auto* pTexture = VarLocator.TryResource<TextureBindInfo>(GetNumTextures()))
516 return pTexture;
517
518 if (auto* pImage = VarLocator.TryResource<ImageBindInfo>(GetNumImages()))
519 return pImage;
520
521 if (auto* pSSBO = VarLocator.TryResource<StorageBufferBindInfo>(GetNumStorageBuffers()))
522 return pSSBO;
523
524 LOG_ERROR(Index, " is not a valid variable index.");
525 return nullptr;
526 }
527
528
529
530 class ShaderVariableIndexLocator
531 {
532 public:
533 ShaderVariableIndexLocator(const ShaderVariableManagerGL& _Layout, const ShaderVariableManagerGL::GLVariableBase& Variable) :
534 // clang-format off
535 Layout {_Layout},
536 VarOffset(reinterpret_cast<const Uint8*>(&Variable) - reinterpret_cast<const Uint8*>(_Layout.m_ResourceBuffer))
537 // clang-format on
538 {}
539
540 template <typename ResourceType>
541 bool TryResource(Uint32 NextResourceTypeOffset, Uint32 VarCount)
542 {
543 if (VarOffset < NextResourceTypeOffset)
544 {
545 auto RelativeOffset = VarOffset - Layout.GetResourceOffset<ResourceType>();
546 DEV_CHECK_ERR(RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")");
547 RelativeOffset /= sizeof(ResourceType);
548 VERIFY(RelativeOffset >= 0 && RelativeOffset < VarCount,
549 "Relative offset is out of bounds which either means the variable does not belong to this SRB or "
550 "there is a bug in varaible offsets");
551 Index += static_cast<Uint32>(RelativeOffset);
552 return true;
553 }
554 else
555 {
556 Index += VarCount;
557 return false;
558 }
559 }
560
561 Uint32 GetIndex() const { return Index; }
562
563 private:
564 const ShaderVariableManagerGL& Layout;
565 const size_t VarOffset;
566 Uint32 Index = 0;
567 };
568
569
570 Uint32 ShaderVariableManagerGL::GetVariableIndex(const GLVariableBase& Var) const
571 {
572 if (!m_ResourceBuffer)
573 {
574 LOG_ERROR("This shader resource layout does not have resources");
575 return static_cast<Uint32>(-1);
576 }
577
578 ShaderVariableIndexLocator IdxLocator(*this, Var);
579
580 if (IdxLocator.TryResource<UniformBuffBindInfo>(m_TextureOffset, GetNumUBs()))
581 return IdxLocator.GetIndex();
582
583 if (IdxLocator.TryResource<TextureBindInfo>(m_ImageOffset, GetNumTextures()))
584 return IdxLocator.GetIndex();
585
586 if (IdxLocator.TryResource<ImageBindInfo>(m_StorageBufferOffset, GetNumImages()))
587 return IdxLocator.GetIndex();
588
589 if (IdxLocator.TryResource<StorageBufferBindInfo>(m_VariableEndOffset, GetNumStorageBuffers()))
590 return IdxLocator.GetIndex();
591
592 LOG_ERROR("Failed to get variable index. The variable ", &Var, " does not belong to this shader resource layout");
593 return ~0u;
594 }
595
596 #ifdef DILIGENT_DEVELOPMENT
597 bool ShaderVariableManagerGL::dvpVerifyBindings(const ShaderResourceCacheGL& ResourceCache) const
598 {
599 # define LOG_MISSING_BINDING(VarType, BindInfo, ArrIndex) LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", GetShaderResourcePrintName(Desc, ArrIndex), "'")
600
601 bool BindingsOK = true;
602 HandleConstResources(
603 [&](const UniformBuffBindInfo& ub) //
604 {
605 const auto& Desc = ub.GetDesc();
606 const auto& Attr = ub.GetAttribs();
607 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER);
608 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
609 {
610 if (!ResourceCache.IsUBBound(Attr.CacheOffset + ArrInd))
611 {
612 LOG_MISSING_BINDING("constant buffer", ub, ArrInd);
613 BindingsOK = false;
614 }
615 }
616 },
617
618 [&](const TextureBindInfo& tex) //
619 {
620 const auto& Desc = tex.GetDesc();
621 const auto& Attr = tex.GetAttribs();
622 const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
623 VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
624 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
625 {
626 if (!ResourceCache.IsTextureBound(Attr.CacheOffset + ArrInd, IsTexView))
627 {
628 LOG_MISSING_BINDING("texture", tex, ArrInd);
629 BindingsOK = false;
630 }
631 else
632 {
633 const auto& CachedTex = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrInd);
634 if (Attr.IsImmutableSamplerAssigned() && CachedTex.pSampler == nullptr)
635 {
636 LOG_ERROR_MESSAGE("Immutable sampler is not initialized for texture '", Desc.Name, "'");
637 BindingsOK = false;
638 }
639 }
640 }
641 },
642
643 [&](const ImageBindInfo& img) //
644 {
645 const auto& Desc = img.GetDesc();
646 const auto& Attr = img.GetAttribs();
647 const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
648 VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV);
649 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
650 {
651 if (!ResourceCache.IsImageBound(Attr.CacheOffset + ArrInd, IsTexView))
652 {
653 LOG_MISSING_BINDING("texture UAV", img, ArrInd);
654 BindingsOK = false;
655 }
656 }
657 },
658
659 [&](const StorageBufferBindInfo& ssbo) //
660 {
661 const auto& Desc = ssbo.GetDesc();
662 const auto& Attr = ssbo.GetAttribs();
663 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV ||
664 Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
665 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
666 {
667 if (!ResourceCache.IsSSBOBound(Attr.CacheOffset + ArrInd))
668 {
669 LOG_MISSING_BINDING("buffer", ssbo, ArrInd);
670 BindingsOK = false;
671 }
672 }
673 });
674 # undef LOG_MISSING_BINDING
675
676 return BindingsOK;
677 }
678
679 #endif // DILIGENT_DEVELOPMENT
680
681 } // namespace Diligent
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #include "pch.h"
28
29 #include "ShaderVariableManagerGL.hpp"
30
31 #include <array>
32
33 #include "RenderDeviceGLImpl.hpp"
34 #include "PipelineResourceSignatureGLImpl.hpp"
35 #include "Align.hpp"
36 #include "PlatformMisc.hpp"
37
38 namespace Diligent
39 {
40
41 void ShaderVariableManagerGL::CountResources(const PipelineResourceSignatureGLImpl& Signature,
42 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
43 Uint32 NumAllowedTypes,
44 const SHADER_TYPE ShaderType,
45 ResourceCounters& Counters)
46 {
47 ProcessSignatureResources(
48 Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
49 [&](Uint32 Index) //
50 {
51 const auto& ResDesc = Signature.GetResourceDesc(Index);
52 static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range");
53 switch (PipelineResourceToBindingRange(ResDesc))
54 {
55 // clang-format off
56 case BINDING_RANGE_UNIFORM_BUFFER: ++Counters.NumUBs; break;
57 case BINDING_RANGE_TEXTURE: ++Counters.NumTextures; break;
58 case BINDING_RANGE_IMAGE: ++Counters.NumImages; break;
59 case BINDING_RANGE_STORAGE_BUFFER: ++Counters.NumStorageBlocks; break;
60 // clang-format on
61 default:
62 UNEXPECTED("Unsupported resource type.");
63 }
64 });
65 }
66
67 template <typename HandlerType>
68 void ShaderVariableManagerGL::ProcessSignatureResources(const PipelineResourceSignatureGLImpl& Signature,
69 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
70 Uint32 NumAllowedTypes,
71 SHADER_TYPE ShaderType,
72 HandlerType Handler)
73 {
74 const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
75
76 for (Uint32 var_type = 0; var_type < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; ++var_type)
77 {
78 const auto VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(var_type);
79 if (IsAllowedType(VarType, AllowedTypeBits))
80 {
81 const auto ResIdxRange = Signature.GetResourceIndexRange(VarType);
82 for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r)
83 {
84 const auto& Res = Signature.GetResourceDesc(r);
85 VERIFY_EXPR(Res.VarType == VarType);
86
87 if ((Res.ShaderStages & ShaderType) == 0)
88 continue;
89
90 if (Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER)
91 continue;
92
93 Handler(r);
94 }
95 }
96 }
97 }
98
99 size_t ShaderVariableManagerGL::GetRequiredMemorySize(const PipelineResourceSignatureGLImpl& Signature,
100 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
101 Uint32 NumAllowedTypes,
102 SHADER_TYPE ShaderType)
103 {
104 ResourceCounters Counters;
105 CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters);
106
107 // clang-format off
108 size_t RequiredSize = Counters.NumUBs * sizeof(UniformBuffBindInfo) +
109 Counters.NumTextures * sizeof(TextureBindInfo) +
110 Counters.NumImages * sizeof(ImageBindInfo) +
111 Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo);
112 // clang-format on
113 return RequiredSize;
114 }
115
116 void ShaderVariableManagerGL::Initialize(const PipelineResourceSignatureGLImpl& Signature,
117 IMemoryAllocator& Allocator,
118 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
119 Uint32 NumAllowedTypes,
120 SHADER_TYPE ShaderType)
121 {
122 #ifdef DILIGENT_DEBUG
123 m_pDbgAllocator = &Allocator;
124 #endif
125
126 ResourceCounters Counters;
127 CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters);
128
129 m_pSignature = &Signature;
130
131 // Initialize offsets
132 size_t CurrentOffset = 0;
133
134 auto AdvanceOffset = [&CurrentOffset](size_t NumBytes) //
135 {
136 constexpr size_t MaxOffset = std::numeric_limits<OffsetType>::max();
137 VERIFY(CurrentOffset <= MaxOffset, "Current offser (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")");
138 (void)MaxOffset;
139 auto Offset = static_cast<OffsetType>(CurrentOffset);
140 CurrentOffset += NumBytes;
141 return Offset;
142 };
143
144 // clang-format off
145 auto UBOffset = AdvanceOffset(Counters.NumUBs * sizeof(UniformBuffBindInfo) ); (void)UBOffset; // To suppress warning
146 m_TextureOffset = AdvanceOffset(Counters.NumTextures * sizeof(TextureBindInfo) );
147 m_ImageOffset = AdvanceOffset(Counters.NumImages * sizeof(ImageBindInfo) );
148 m_StorageBufferOffset = AdvanceOffset(Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo));
149 m_VariableEndOffset = AdvanceOffset(0);
150 // clang-format off
151 auto TotalMemorySize = m_VariableEndOffset;
152 VERIFY_EXPR(TotalMemorySize == GetRequiredMemorySize(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType));
153
154 if (TotalMemorySize)
155 {
156 m_ResourceBuffer = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", TotalMemorySize);
157 }
158
159 // clang-format off
160 VERIFY_EXPR(Counters.NumUBs == GetNumUBs() );
161 VERIFY_EXPR(Counters.NumTextures == GetNumTextures() );
162 VERIFY_EXPR(Counters.NumImages == GetNumImages() );
163 VERIFY_EXPR(Counters.NumStorageBlocks == GetNumStorageBuffers());
164 // clang-format on
165
166 // Current resource index for every resource type
167 ResourceCounters VarCounters = {};
168
169 ProcessSignatureResources(
170 Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
171 [&](Uint32 Index) //
172 {
173 const auto& ResDesc = Signature.GetResourceDesc(Index);
174 static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range");
175 switch (PipelineResourceToBindingRange(ResDesc))
176 {
177 case BINDING_RANGE_UNIFORM_BUFFER:
178 new (&GetResource<UniformBuffBindInfo>(VarCounters.NumUBs++)) UniformBuffBindInfo{*this, Index};
179 break;
180 case BINDING_RANGE_TEXTURE:
181 new (&GetResource<TextureBindInfo>(VarCounters.NumTextures++)) TextureBindInfo{*this, Index};
182 break;
183 case BINDING_RANGE_IMAGE:
184 new (&GetResource<ImageBindInfo>(VarCounters.NumImages++)) ImageBindInfo{*this, Index};
185 break;
186 case BINDING_RANGE_STORAGE_BUFFER:
187 new (&GetResource<StorageBufferBindInfo>(VarCounters.NumStorageBlocks++)) StorageBufferBindInfo{*this, Index};
188 break;
189 default:
190 UNEXPECTED("Unsupported resource type.");
191 }
192 });
193
194 // clang-format off
195 VERIFY(VarCounters.NumUBs == GetNumUBs(), "Not all UBs are initialized which will cause a crash when dtor is called");
196 VERIFY(VarCounters.NumTextures == GetNumTextures(), "Not all Textures are initialized which will cause a crash when dtor is called");
197 VERIFY(VarCounters.NumImages == GetNumImages(), "Not all Images are initialized which will cause a crash when dtor is called");
198 VERIFY(VarCounters.NumStorageBlocks == GetNumStorageBuffers(), "Not all SSBOs are initialized which will cause a crash when dtor is called");
199 // clang-format on
200 }
201
202 ShaderVariableManagerGL::~ShaderVariableManagerGL()
203 {
204 VERIFY(m_ResourceBuffer == nullptr, "Destroy() has not been called");
205 }
206
207 void ShaderVariableManagerGL::Destroy(IMemoryAllocator& Allocator)
208 {
209 if (m_ResourceBuffer == nullptr)
210 return;
211
212 VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor");
213
214 HandleResources(
215 [&](UniformBuffBindInfo& ub) {
216 ub.~UniformBuffBindInfo();
217 },
218 [&](TextureBindInfo& tex) {
219 tex.~TextureBindInfo();
220 },
221 [&](ImageBindInfo& img) {
222 img.~ImageBindInfo();
223 },
224 [&](StorageBufferBindInfo& ssbo) {
225 ssbo.~StorageBufferBindInfo();
226 });
227
228 Allocator.Free(m_ResourceBuffer);
229 m_ResourceBuffer = nullptr;
230 }
231
232 void ShaderVariableManagerGL::UniformBuffBindInfo::BindResource(IDeviceObject* pBuffer,
233 Uint32 ArrayIndex)
234 {
235 const auto& Desc = GetDesc();
236 const auto& Attr = GetAttribs();
237
238 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
239 auto& ResourceCache = m_ParentManager.m_ResourceCache;
240
241 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER);
242
243 // We cannot use ValidatedCast<> here as the resource retrieved from the
244 // resource mapping can be of wrong type
245 RefCntAutoPtr<BufferGLImpl> pBuffGLImpl(pBuffer, IID_BufferGL);
246 #ifdef DILIGENT_DEVELOPMENT
247 {
248 const auto& CachedUB = ResourceCache.GetConstUB(Attr.CacheOffset + ArrayIndex);
249 VerifyConstantBufferBinding(Desc.Name, Desc.ArraySize, Desc.VarType, Desc.Flags, ArrayIndex, pBuffer, pBuffGLImpl.RawPtr(), CachedUB.pBuffer.RawPtr());
250 }
251 #endif
252
253 ResourceCache.SetUniformBuffer(Attr.CacheOffset + ArrayIndex, std::move(pBuffGLImpl));
254 }
255
256
257
258 void ShaderVariableManagerGL::TextureBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
259 {
260 const auto& Desc = GetDesc();
261 const auto& Attr = GetAttribs();
262
263 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
264 auto& ResourceCache = m_ParentManager.m_ResourceCache;
265
266 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV ||
267 Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT)
268 {
269 // We cannot use ValidatedCast<> here as the resource retrieved from the
270 // resource mapping can be of wrong type
271 RefCntAutoPtr<TextureViewGLImpl> pViewGL(pView, IID_TextureViewGL);
272 #ifdef DILIGENT_DEVELOPMENT
273 {
274 auto& CachedTexSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrayIndex);
275 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
276 pView, pViewGL.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE},
277 RESOURCE_DIM_UNDEFINED, false, CachedTexSampler.pView.RawPtr());
278 if (Attr.IsImmutableSamplerAssigned() && ResourceCache.StaticResourcesInitialized())
279 {
280 VERIFY(CachedTexSampler.pSampler != nullptr, "Immutable samplers must be initialized by PipelineResourceSignatureGLImpl::InitializeSRBResourceCache!");
281 }
282 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT)
283 {
284 DEV_CHECK_ERR(!Attr.IsSamplerAssigned(), "Input attachment must not have assigned sampler.");
285 }
286 }
287 #endif
288 ResourceCache.SetTexture(Attr.CacheOffset + ArrayIndex, std::move(pViewGL), !Attr.IsImmutableSamplerAssigned());
289 }
290 else if (Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV)
291 {
292 // We cannot use ValidatedCast<> here as the resource retrieved from the
293 // resource mapping can be of wrong type
294 RefCntAutoPtr<BufferViewGLImpl> pViewGL(pView, IID_BufferViewGL);
295 #ifdef DILIGENT_DEVELOPMENT
296 {
297 auto& CachedBuffSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrayIndex);
298 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
299 pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE},
300 RESOURCE_DIM_BUFFER, false, CachedBuffSampler.pView.RawPtr());
301 if (pViewGL != nullptr)
302 {
303 const auto& ViewDesc = pViewGL->GetDesc();
304 const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
305 if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW))
306 {
307 LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
308 Desc.Name, ": formatted buffer view is expected.");
309 }
310 }
311 }
312 #endif
313 VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0);
314 ResourceCache.SetTexelBuffer(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
315 }
316 else
317 {
318 UNEXPECTED("Unexpected resource type ", GetShaderResourceTypeLiteralName(Desc.ResourceType), ". Texture SRV or buffer SRV is expected.");
319 }
320 }
321
322
323 void ShaderVariableManagerGL::ImageBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
324 {
325 const auto& Desc = GetDesc();
326 const auto& Attr = GetAttribs();
327
328 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
329 auto& ResourceCache = m_ParentManager.m_ResourceCache;
330
331 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV)
332 {
333 // We cannot use ValidatedCast<> here as the resource retrieved from the
334 // resource mapping can be of wrong type
335 RefCntAutoPtr<TextureViewGLImpl> pViewGL(pView, IID_TextureViewGL);
336 #ifdef DILIGENT_DEVELOPMENT
337 {
338 auto& CachedUAV = ResourceCache.GetConstImage(Attr.CacheOffset + ArrayIndex);
339 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
340 pView, pViewGL.RawPtr(), {TEXTURE_VIEW_UNORDERED_ACCESS},
341 RESOURCE_DIM_UNDEFINED, false, CachedUAV.pView.RawPtr());
342 }
343 #endif
344 ResourceCache.SetTexImage(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
345 }
346 else if (Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV)
347 {
348 // We cannot use ValidatedCast<> here as the resource retrieved from the
349 // resource mapping can be of wrong type
350 RefCntAutoPtr<BufferViewGLImpl> pViewGL(pView, IID_BufferViewGL);
351 #ifdef DILIGENT_DEVELOPMENT
352 {
353 auto& CachedUAV = ResourceCache.GetConstImage(Attr.CacheOffset + ArrayIndex);
354 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
355 pView, pViewGL.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS},
356 RESOURCE_DIM_BUFFER, false, CachedUAV.pView.RawPtr());
357 if (pViewGL != nullptr)
358 {
359 const auto& ViewDesc = pViewGL->GetDesc();
360 const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
361 if (!((BuffDesc.Mode == BUFFER_MODE_FORMATTED && ViewDesc.Format.ValueType != VT_UNDEFINED) || BuffDesc.Mode == BUFFER_MODE_RAW))
362 {
363 LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
364 Desc.Name, ": formatted buffer view is expected.");
365 }
366 }
367 }
368 #endif
369 VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0);
370 ResourceCache.SetBufImage(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
371 }
372 else
373 {
374 UNEXPECTED("Unexpected resource type ", GetShaderResourceTypeLiteralName(Desc.ResourceType), ". Texture UAV or buffer UAV is expected.");
375 }
376 }
377
378
379
380 void ShaderVariableManagerGL::StorageBufferBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
381 {
382 const auto& Desc = GetDesc();
383 const auto& Attr = GetAttribs();
384
385 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
386 auto& ResourceCache = m_ParentManager.m_ResourceCache;
387 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV ||
388 Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV);
389 VERIFY_EXPR((Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) == 0);
390
391 // We cannot use ValidatedCast<> here as the resource retrieved from the
392 // resource mapping can be of wrong type
393 RefCntAutoPtr<BufferViewGLImpl> pViewGL(pView, IID_BufferViewGL);
394 #ifdef DILIGENT_DEVELOPMENT
395 {
396 auto& CachedSSBO = ResourceCache.GetConstSSBO(Attr.CacheOffset + ArrayIndex);
397 // HLSL structured buffers are mapped to SSBOs in GLSL
398 VerifyResourceViewBinding(Desc.Name, Desc.ArraySize, Desc.VarType, ArrayIndex,
399 pView, pViewGL.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE, BUFFER_VIEW_UNORDERED_ACCESS},
400 RESOURCE_DIM_BUFFER, false, CachedSSBO.pBufferView.RawPtr());
401 if (pViewGL != nullptr)
402 {
403 const auto& ViewDesc = pViewGL->GetDesc();
404 const auto& BuffDesc = pViewGL->GetBuffer()->GetDesc();
405 if (BuffDesc.Mode != BUFFER_MODE_STRUCTURED && BuffDesc.Mode != BUFFER_MODE_RAW)
406 {
407 LOG_ERROR_MESSAGE("Error binding buffer view '", ViewDesc.Name, "' of buffer '", BuffDesc.Name, "' to shader variable '",
408 Desc.Name, ": structured buffer view is expected.");
409 }
410 }
411 }
412 #endif
413 ResourceCache.SetSSBO(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
414 }
415
416 void ShaderVariableManagerGL::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags)
417 {
418 if (pResourceMapping == nullptr)
419 {
420 LOG_ERROR_MESSAGE("Failed to bind resources: resource mapping is null");
421 return;
422 }
423
424 if ((Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0)
425 Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL;
426
427 HandleResources(
428 [&](UniformBuffBindInfo& ub) {
429 ub.BindResources<UniformBuffBindInfo>(pResourceMapping, Flags);
430 },
431 [&](TextureBindInfo& tex) {
432 tex.BindResources<TextureBindInfo>(pResourceMapping, Flags);
433 },
434 [&](ImageBindInfo& img) {
435 img.BindResources<ImageBindInfo>(pResourceMapping, Flags);
436 },
437 [&](StorageBufferBindInfo& ssbo) {
438 ssbo.BindResources<StorageBufferBindInfo>(pResourceMapping, Flags);
439 });
440 }
441
442
443 template <typename ResourceType>
444 IShaderResourceVariable* ShaderVariableManagerGL::GetResourceByName(const Char* Name) const
445 {
446 auto NumResources = GetNumResources<ResourceType>();
447 for (Uint32 res = 0; res < NumResources; ++res)
448 {
449 auto& Resource = GetResource<ResourceType>(res);
450 const auto& ResDesc = Resource.GetDesc();
451 if (strcmp(ResDesc.Name, Name) == 0)
452 return &Resource;
453 }
454
455 return nullptr;
456 }
457
458
459 IShaderResourceVariable* ShaderVariableManagerGL::GetVariable(const Char* Name) const
460 {
461 if (auto* pUB = GetResourceByName<UniformBuffBindInfo>(Name))
462 return pUB;
463
464 if (auto* pTexture = GetResourceByName<TextureBindInfo>(Name))
465 return pTexture;
466
467 if (auto* pImage = GetResourceByName<ImageBindInfo>(Name))
468 return pImage;
469
470 if (auto* pSSBO = GetResourceByName<StorageBufferBindInfo>(Name))
471 return pSSBO;
472
473 return nullptr;
474 }
475
476 Uint32 ShaderVariableManagerGL::GetVariableCount() const
477 {
478 return GetNumUBs() + GetNumTextures() + GetNumImages() + GetNumStorageBuffers();
479 }
480
481 class ShaderVariableLocator
482 {
483 public:
484 ShaderVariableLocator(const ShaderVariableManagerGL& _Layout,
485 Uint32 _Index) :
486 // clang-format off
487 Layout {_Layout},
488 Index {_Index}
489 // clang-format on
490 {
491 }
492
493 template <typename ResourceType>
494 IShaderResourceVariable* TryResource(Uint32 NumResources)
495 {
496 if (Index < NumResources)
497 return &Layout.GetResource<ResourceType>(Index);
498 else
499 {
500 Index -= NumResources;
501 return nullptr;
502 }
503 }
504
505 private:
506 ShaderVariableManagerGL const& Layout;
507 Uint32 Index;
508 };
509
510
511 IShaderResourceVariable* ShaderVariableManagerGL::GetVariable(Uint32 Index) const
512 {
513 ShaderVariableLocator VarLocator(*this, Index);
514
515 if (auto* pUB = VarLocator.TryResource<UniformBuffBindInfo>(GetNumUBs()))
516 return pUB;
517
518 if (auto* pTexture = VarLocator.TryResource<TextureBindInfo>(GetNumTextures()))
519 return pTexture;
520
521 if (auto* pImage = VarLocator.TryResource<ImageBindInfo>(GetNumImages()))
522 return pImage;
523
524 if (auto* pSSBO = VarLocator.TryResource<StorageBufferBindInfo>(GetNumStorageBuffers()))
525 return pSSBO;
526
527 LOG_ERROR(Index, " is not a valid variable index.");
528 return nullptr;
529 }
530
531
532
533 class ShaderVariableIndexLocator
534 {
535 public:
536 ShaderVariableIndexLocator(const ShaderVariableManagerGL& _Layout, const ShaderVariableManagerGL::GLVariableBase& Variable) :
537 // clang-format off
538 Layout {_Layout},
539 VarOffset(reinterpret_cast<const Uint8*>(&Variable) - reinterpret_cast<const Uint8*>(_Layout.m_ResourceBuffer))
540 // clang-format on
541 {}
542
543 template <typename ResourceType>
544 bool TryResource(Uint32 NextResourceTypeOffset, Uint32 VarCount)
545 {
546 if (VarOffset < NextResourceTypeOffset)
547 {
548 auto RelativeOffset = VarOffset - Layout.GetResourceOffset<ResourceType>();
549 DEV_CHECK_ERR(RelativeOffset % sizeof(ResourceType) == 0, "Offset is not multiple of resource type (", sizeof(ResourceType), ")");
550 RelativeOffset /= sizeof(ResourceType);
551 VERIFY(RelativeOffset >= 0 && RelativeOffset < VarCount,
552 "Relative offset is out of bounds which either means the variable does not belong to this SRB or "
553 "there is a bug in varaible offsets");
554 Index += static_cast<Uint32>(RelativeOffset);
555 return true;
556 }
557 else
558 {
559 Index += VarCount;
560 return false;
561 }
562 }
563
564 Uint32 GetIndex() const { return Index; }
565
566 private:
567 const ShaderVariableManagerGL& Layout;
568 const size_t VarOffset;
569 Uint32 Index = 0;
570 };
571
572
573 Uint32 ShaderVariableManagerGL::GetVariableIndex(const GLVariableBase& Var) const
574 {
575 if (!m_ResourceBuffer)
576 {
577 LOG_ERROR("This shader resource layout does not have resources");
578 return static_cast<Uint32>(-1);
579 }
580
581 ShaderVariableIndexLocator IdxLocator(*this, Var);
582
583 if (IdxLocator.TryResource<UniformBuffBindInfo>(m_TextureOffset, GetNumUBs()))
584 return IdxLocator.GetIndex();
585
586 if (IdxLocator.TryResource<TextureBindInfo>(m_ImageOffset, GetNumTextures()))
587 return IdxLocator.GetIndex();
588
589 if (IdxLocator.TryResource<ImageBindInfo>(m_StorageBufferOffset, GetNumImages()))
590 return IdxLocator.GetIndex();
591
592 if (IdxLocator.TryResource<StorageBufferBindInfo>(m_VariableEndOffset, GetNumStorageBuffers()))
593 return IdxLocator.GetIndex();
594
595 LOG_ERROR("Failed to get variable index. The variable ", &Var, " does not belong to this shader resource layout");
596 return ~0u;
597 }
598
599 const PipelineResourceDesc& ShaderVariableManagerGL::GetResourceDesc(Uint32 Index) const
600 {
601 VERIFY_EXPR(m_pSignature);
602 return m_pSignature->GetResourceDesc(Index);
603 }
604
605 const ShaderVariableManagerGL::ResourceAttribs& ShaderVariableManagerGL::GetAttribs(Uint32 Index) const
606 {
607 VERIFY_EXPR(m_pSignature);
608 return m_pSignature->GetResourceAttribs(Index);
609 }
610
611
612 #ifdef DILIGENT_DEVELOPMENT
613 bool ShaderVariableManagerGL::dvpVerifyBindings(const ShaderResourceCacheGL& ResourceCache) const
614 {
615 # define LOG_MISSING_BINDING(VarType, BindInfo, ArrIndex) LOG_ERROR_MESSAGE("No resource is bound to ", VarType, " variable '", GetShaderResourcePrintName(Desc, ArrIndex), "'")
616
617 bool BindingsOK = true;
618 HandleConstResources(
619 [&](const UniformBuffBindInfo& ub) //
620 {
621 const auto& Desc = ub.GetDesc();
622 const auto& Attr = ub.GetAttribs();
623 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER);
624 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
625 {
626 if (!ResourceCache.IsUBBound(Attr.CacheOffset + ArrInd))
627 {
628 LOG_MISSING_BINDING("constant buffer", ub, ArrInd);
629 BindingsOK = false;
630 }
631 }
632 },
633
634 [&](const TextureBindInfo& tex) //
635 {
636 const auto& Desc = tex.GetDesc();
637 const auto& Attr = tex.GetAttribs();
638 const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
639 VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
640 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
641 {
642 if (!ResourceCache.IsTextureBound(Attr.CacheOffset + ArrInd, IsTexView))
643 {
644 LOG_MISSING_BINDING("texture", tex, ArrInd);
645 BindingsOK = false;
646 }
647 else
648 {
649 const auto& CachedTex = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrInd);
650 if (Attr.IsImmutableSamplerAssigned() && CachedTex.pSampler == nullptr)
651 {
652 LOG_ERROR_MESSAGE("Immutable sampler is not initialized for texture '", Desc.Name, "'");
653 BindingsOK = false;
654 }
655 }
656 }
657 },
658
659 [&](const ImageBindInfo& img) //
660 {
661 const auto& Desc = img.GetDesc();
662 const auto& Attr = img.GetAttribs();
663 const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
664 VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV);
665 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
666 {
667 if (!ResourceCache.IsImageBound(Attr.CacheOffset + ArrInd, IsTexView))
668 {
669 LOG_MISSING_BINDING("texture UAV", img, ArrInd);
670 BindingsOK = false;
671 }
672 }
673 },
674
675 [&](const StorageBufferBindInfo& ssbo) //
676 {
677 const auto& Desc = ssbo.GetDesc();
678 const auto& Attr = ssbo.GetAttribs();
679 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV ||
680 Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
681 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
682 {
683 if (!ResourceCache.IsSSBOBound(Attr.CacheOffset + ArrInd))
684 {
685 LOG_MISSING_BINDING("buffer", ssbo, ArrInd);
686 BindingsOK = false;
687 }
688 }
689 });
690 # undef LOG_MISSING_BINDING
691
692 return BindingsOK;
693 }
694
695 #endif // DILIGENT_DEVELOPMENT
696
697 } // namespace Diligent
2525 */
2626
2727 #include "pch.h"
28
29 #include "SwapChainGLImpl.hpp"
30 #include "RenderDeviceGLImpl.hpp"
2831 #include "DeviceContextGLImpl.hpp"
29 #include "RenderDeviceGLImpl.hpp"
30 #include "SwapChainGLImpl.hpp"
3132 #include "GraphicsAccessories.hpp"
3233
3334 namespace Diligent
2929 #include "Texture1DArray_OGL.hpp"
3030 #include "RenderDeviceGLImpl.hpp"
3131 #include "DeviceContextGLImpl.hpp"
32 #include "BufferGLImpl.hpp"
3233 #include "GLTypeConversions.hpp"
33 #include "BufferGLImpl.hpp"
3434
3535 namespace Diligent
3636 {
2929 #include "Texture1D_OGL.hpp"
3030 #include "RenderDeviceGLImpl.hpp"
3131 #include "DeviceContextGLImpl.hpp"
32 #include "BufferGLImpl.hpp"
3233 #include "GLTypeConversions.hpp"
33 #include "BufferGLImpl.hpp"
3434
3535 namespace Diligent
3636 {
2929 #include "Texture2DArray_OGL.hpp"
3030 #include "RenderDeviceGLImpl.hpp"
3131 #include "DeviceContextGLImpl.hpp"
32 #include "BufferGLImpl.hpp"
3233 #include "GLTypeConversions.hpp"
3334 #include "GraphicsAccessories.hpp"
34 #include "BufferGLImpl.hpp"
3535
3636 namespace Diligent
3737 {
2929 #include "Texture2D_OGL.hpp"
3030 #include "RenderDeviceGLImpl.hpp"
3131 #include "DeviceContextGLImpl.hpp"
32 #include "BufferGLImpl.hpp"
3233 #include "GLTypeConversions.hpp"
3334 #include "GraphicsAccessories.hpp"
34 #include "BufferGLImpl.hpp"
3535
3636 namespace Diligent
3737 {
2929 #include "Texture3D_OGL.hpp"
3030 #include "RenderDeviceGLImpl.hpp"
3131 #include "DeviceContextGLImpl.hpp"
32 #include "BufferGLImpl.hpp"
3233 #include "GLTypeConversions.hpp"
3334 #include "GraphicsAccessories.hpp"
34 #include "BufferGLImpl.hpp"
3535
3636 namespace Diligent
3737 {
2727 #include "pch.h"
2828
2929 #include "TextureBaseGL.hpp"
30
3031 #include "RenderDeviceGLImpl.hpp"
32 #include "DeviceContextGLImpl.hpp"
33 #include "TextureViewGLImpl.hpp"
34
3135 #include "GLTypeConversions.hpp"
32 #include "TextureViewGLImpl.hpp"
33 #include "GLContextState.hpp"
34 #include "DeviceContextGLImpl.hpp"
3536 #include "EngineMemory.h"
3637 #include "GraphicsAccessories.hpp"
3738 #include "Align.hpp"
2727 #include "pch.h"
2828
2929 #include "TextureCubeArray_OGL.hpp"
30
3031 #include "RenderDeviceGLImpl.hpp"
3132 #include "DeviceContextGLImpl.hpp"
33 #include "BufferGLImpl.hpp"
34
3235 #include "GLTypeConversions.hpp"
3336 #include "GraphicsAccessories.hpp"
34 #include "BufferGLImpl.hpp"
37
3538
3639 namespace Diligent
3740 {
2727 #include "pch.h"
2828
2929 #include "TextureCube_OGL.hpp"
30
3031 #include "RenderDeviceGLImpl.hpp"
3132 #include "DeviceContextGLImpl.hpp"
33 #include "BufferGLImpl.hpp"
34
3235 #include "GLTypeConversions.hpp"
3336 #include "GraphicsAccessories.hpp"
34 #include "BufferGLImpl.hpp"
3537
3638 namespace Diligent
3739 {