Diligent Engine  v.2.4.g
ShaderResourceBindingBase.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019-2021 Diligent Graphics LLC
3  * Copyright 2015-2019 Egor Yusov
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * In no event and under no legal theory, whether in tort (including negligence),
18  * contract, or otherwise, unless required by applicable law (such as deliberate
19  * and grossly negligent acts) or agreed to in writing, shall any Contributor be
20  * liable for any damages, including any direct, indirect, special, incidental,
21  * or consequential damages of any character arising as a result of this License or
22  * out of the use or inability to use the software (including but not limited to damages
23  * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
24  * all other commercial damages or losses), even if such Contributor has been advised
25  * of the possibility of such damages.
26  */
27 
28 #pragma once
29 
32 
33 #include <array>
34 #include <functional>
35 
36 #include "PrivateConstants.h"
37 #include "ShaderResourceBinding.h"
38 #include "ObjectBase.hpp"
39 #include "GraphicsTypes.h"
40 #include "Constants.h"
41 #include "RefCntAutoPtr.hpp"
42 #include "GraphicsAccessories.hpp"
44 #include "FixedLinearAllocator.hpp"
45 #include "EngineMemory.h"
46 
47 namespace Diligent
48 {
49 
51 
53 template <typename EngineImplTraits>
54 class ShaderResourceBindingBase : public ObjectBase<typename EngineImplTraits::ShaderResourceBindingInterface>
55 {
56 public:
57  // Base interface this class inherits (IShaderResourceBindingD3D12, IShaderResourceBindingVk, etc.)
58  using BaseInterface = typename EngineImplTraits::ShaderResourceBindingInterface;
59 
60  // The type of the pipeline resource signature implementation (PipelineResourceSignatureD3D12Impl, PipelineResourceSignatureVkImpl, etc.).
61  using ResourceSignatureType = typename EngineImplTraits::PipelineResourceSignatureImplType;
62 
63  // The type of the shader resource cache implementation (ShaderResourceCacheD3D12Impl, ShaderResourceCacheVkImpl, etc.)
64  using ShaderResourceCacheImplType = typename EngineImplTraits::ShaderResourceCacheImplType;
65 
66  // The type of the shader resource variable manager (ShaderVariableManagerD3D12Impl, ShaderVariableManagerVkImpl, etc.)
67  using ShaderVariableManagerImplType = typename EngineImplTraits::ShaderVariableManagerImplType;
68 
70 
74  TObjectBase{pRefCounters},
75  m_pPRS{pPRS},
77  {
78  try
79  {
80  m_ActiveShaderStageIndex.fill(-1);
81 
82  const auto NumShaders = GetNumShaders();
83  const auto PipelineType = GetPipelineType();
84  for (Uint32 s = 0; s < NumShaders; ++s)
85  {
86  const auto ShaderType = pPRS->GetActiveShaderStageType(s);
87  const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType);
88 
89  m_ActiveShaderStageIndex[ShaderInd] = static_cast<Int8>(s);
90  }
91 
92 
93  FixedLinearAllocator MemPool{GetRawAllocator()};
94  MemPool.AddSpace<ShaderVariableManagerImplType>(NumShaders);
95  MemPool.Reserve();
96  static_assert(std::is_nothrow_constructible<ShaderVariableManagerImplType, decltype(*this), ShaderResourceCacheImplType&>::value,
97  "Constructor of ShaderVariableManagerImplType must be noexcept, so we can safely construct all managers");
98  m_pShaderVarMgrs = MemPool.ConstructArray<ShaderVariableManagerImplType>(NumShaders, std::ref(*this), std::ref(m_ShaderResourceCache));
99 
100  // The memory is now owned by ShaderResourceBindingBase and will be freed by Destruct().
101  auto* Ptr = MemPool.ReleaseOwnership();
103  (void)Ptr;
104 
105  // It is important to construct all objects before initializing them because if an exception is thrown,
106  // Destruct() will call destructors for all non-null objects.
107 
108  pPRS->InitSRBResourceCache(m_ShaderResourceCache);
109 
110  auto& SRBMemAllocator = pPRS->GetSRBMemoryAllocator();
111  for (Uint32 s = 0; s < NumShaders; ++s)
112  {
113  const auto ShaderType = pPRS->GetActiveShaderStageType(s);
114  const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPRS->GetPipelineType());
115  const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd];
116  VERIFY_EXPR(MgrInd >= 0 && MgrInd < static_cast<int>(NumShaders));
117 
118  auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s);
119 
120  // Initialize vars manager to reference mutable and dynamic variables
121  // Note that the cache has space for all variable types
123  m_pShaderVarMgrs[MgrInd].Initialize(*pPRS, VarDataAllocator, VarTypes, _countof(VarTypes), ShaderType);
124  }
125  }
126  catch (...)
127  {
128  // We must release objects manually as destructor will not be called.
129  Destruct();
130  throw;
131  }
132  }
133 
135  {
136  Destruct();
137  }
138 
139  IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderResourceBinding, TObjectBase)
140 
142  {
143  return m_pPRS->GetDesc().BindingIndex;
144  }
145 
147  {
148  return m_pPRS->GetPipelineType();
149  }
150 
152  {
153  return m_pPRS->GetNumActiveShaderStages();
154  }
155 
158  {
159  return GetSignature();
160  }
161 
162  virtual bool DILIGENT_CALL_TYPE StaticResourcesInitialized() const override final
163  {
165  }
166 
168  {
169  return m_pPRS.template RawPtr<ResourceSignatureType>();
170  }
171 
173  {
176  }
177 
180  {
181  const auto PipelineType = GetPipelineType();
182  if (!IsConsistentShaderType(ShaderType, PipelineType))
183  {
184  LOG_WARNING_MESSAGE("Unable to find mutable/dynamic variable '", Name, "' in shader stage ", GetShaderTypeLiteralName(ShaderType),
185  " as the stage is invalid for ", GetPipelineTypeString(PipelineType), " pipeline resource signature '", m_pPRS->GetDesc().Name, "'.");
186  return nullptr;
187  }
188 
189  const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType);
190  const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd];
191  if (MgrInd < 0)
192  return nullptr;
193 
194  VERIFY_EXPR(static_cast<Uint32>(MgrInd) < GetNumShaders());
195  return m_pShaderVarMgrs[MgrInd].GetVariable(Name);
196  }
197 
200  {
201  const auto PipelineType = GetPipelineType();
202  if (!IsConsistentShaderType(ShaderType, PipelineType))
203  {
204  LOG_WARNING_MESSAGE("Unable to get the number of mutable/dynamic variables in shader stage ", GetShaderTypeLiteralName(ShaderType),
205  " as the stage is invalid for ", GetPipelineTypeString(PipelineType), " pipeline resource signature '", m_pPRS->GetDesc().Name, "'.");
206  return 0;
207  }
208 
209  const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType);
210  const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd];
211  if (MgrInd < 0)
212  return 0;
213 
214  VERIFY_EXPR(static_cast<Uint32>(MgrInd) < GetNumShaders());
215  return m_pShaderVarMgrs[MgrInd].GetVariableCount();
216  }
217 
220  {
221  const auto PipelineType = GetPipelineType();
222  if (!IsConsistentShaderType(ShaderType, PipelineType))
223  {
224  LOG_WARNING_MESSAGE("Unable to get mutable/dynamic variable at index ", Index, " in shader stage ", GetShaderTypeLiteralName(ShaderType),
225  " as the stage is invalid for ", GetPipelineTypeString(PipelineType), " pipeline resource signature '", m_pPRS->GetDesc().Name, "'.");
226  return nullptr;
227  }
228 
229  const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType);
230  const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd];
231  if (MgrInd < 0)
232  return nullptr;
233 
234  VERIFY_EXPR(static_cast<Uint32>(MgrInd) < GetNumShaders());
235  return m_pShaderVarMgrs[MgrInd].GetVariable(Index);
236  }
237 
239  virtual void DILIGENT_CALL_TYPE BindResources(Uint32 ShaderFlags,
240  IResourceMapping* pResMapping,
241  Uint32 Flags) override final
242  {
243  const auto PipelineType = GetPipelineType();
244  for (Int32 ShaderInd = 0; ShaderInd < static_cast<Int32>(m_ActiveShaderStageIndex.size()); ++ShaderInd)
245  {
246  auto VarMngrInd = m_ActiveShaderStageIndex[ShaderInd];
247  if (VarMngrInd >= 0)
248  {
249  // ShaderInd is the shader type pipeline index here
250  const auto ShaderType = GetShaderTypeFromPipelineIndex(ShaderInd, PipelineType);
251  if ((ShaderFlags & ShaderType) != 0)
252  {
253  m_pShaderVarMgrs[VarMngrInd].BindResources(pResMapping, Flags);
254  }
255  }
256  }
257  }
258 
261 
262 private:
263  void Destruct()
264  {
265  if (m_pShaderVarMgrs != nullptr)
266  {
267  auto& SRBMemAllocator = GetSignature()->GetSRBMemoryAllocator();
268  for (Uint32 s = 0; s < GetNumShaders(); ++s)
269  {
270  auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s);
271  m_pShaderVarMgrs[s].Destroy(VarDataAllocator);
272  m_pShaderVarMgrs[s].~ShaderVariableManagerImplType();
273  }
275  }
276  }
277 
278 protected:
283 
284  // Index of the active shader stage that has resources, for every shader
285  // type in the pipeline (given by GetShaderTypePipelineIndex(ShaderType, m_PipelineType)).
286  std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ActiveShaderStageIndex = {-1, -1, -1, -1, -1, -1};
287  static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
288 
290  ShaderVariableManagerImplType* m_pShaderVarMgrs = nullptr; // [GetNumShaders()]
291 
293 };
294 
295 } // namespace Diligent
ObjectBase.hpp
ShaderResourceCacheCommon.hpp
Diligent::ShaderResourceBindingBase< EngineGLImplTraits >::BaseInterface
typename EngineGLImplTraits ::ShaderResourceBindingInterface BaseInterface
Definition: ShaderResourceBindingBase.hpp:58
Diligent::IReferenceCounters
Base interface for a reference counter object that stores the number of strong and weak references an...
Definition: ReferenceCounters.h:44
GraphicsAccessories.hpp
Diligent::IShaderResourceVariable
Shader resource variable.
Definition: ShaderResourceVariable.h:117
Diligent::ShaderResourceBindingBase::SetStaticResourcesInitialized
void SetStaticResourcesInitialized()
Definition: ShaderResourceBindingBase.hpp:172
Diligent::IPipelineResourceSignature
Pipeline resource signature interface.
Definition: PipelineResourceSignature.h:226
Diligent::ShaderResourceBindingBase::GetResourceCache
const ShaderResourceCacheImplType & GetResourceCache() const
Definition: ShaderResourceBindingBase.hpp:260
Diligent::SHADER_TYPE
SHADER_TYPE
Describes the shader type.
Definition: GraphicsTypes.h:65
Diligent::ShaderResourceBindingBase::GetResourceCache
ShaderResourceCacheImplType & GetResourceCache()
Definition: ShaderResourceBindingBase.hpp:259
Flags
Uint32 Flags
Definition: DXBCUtils.cpp:71
Diligent::ShaderResourceBindingBase::m_ActiveShaderStageIndex
std::array< Int8, MAX_SHADERS_IN_PIPELINE > m_ActiveShaderStageIndex
Definition: ShaderResourceBindingBase.hpp:286
Diligent::PIPELINE_TYPE
PIPELINE_TYPE
Pipeline type.
Definition: PipelineState.h:295
Diligent::ShaderResourceBindingBase::GetVariableCount
virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final
Implementation of IShaderResourceBinding::GetVariableCount().
Definition: ShaderResourceBindingBase.hpp:199
Diligent::ShaderResourceBindingBase
Template class implementing base functionality of the shader resource binding.
Definition: ShaderResourceBindingBase.hpp:54
Diligent::SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC
@ SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC
Shader variable binding is dynamic. It can be set multiple times for every instance of shader resourc...
Definition: ShaderResourceVariable.h:62
PrivateConstants.h
Constants.h
Diligent::ObjectBase
Template class implementing base functionality for an object.
Definition: ObjectBase.hpp:66
Diligent::ShaderResourceBindingBase::m_pShaderVarMgrs
ShaderVariableManagerImplType * m_pShaderVarMgrs
Definition: ShaderResourceBindingBase.hpp:290
Diligent::ShaderResourceBindingBase::m_ShaderResourceCache
ShaderResourceCacheImplType m_ShaderResourceCache
Definition: ShaderResourceBindingBase.hpp:287
Diligent::ShaderResourceBindingBase::GetVariableByName
virtual IShaderResourceVariable * GetVariableByName(SHADER_TYPE ShaderType, const char *Name) override final
Implementation of IShaderResourceBinding::GetVariableByName().
Definition: ShaderResourceBindingBase.hpp:179
Diligent::ShaderResourceBindingBase::GetBindingIndex
Uint32 GetBindingIndex() const
Definition: ShaderResourceBindingBase.hpp:141
Diligent::Int32
int32_t Int32
32-bit signed integer
Definition: BasicTypes.h:46
Diligent::SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE
@ SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE
Shader resource bound to the variable is specific to the shader resource binding instance (see Dilige...
Definition: ShaderResourceVariable.h:58
EngineMemory.h
Diligent::Int8
int8_t Int8
8-bit signed integer
Definition: BasicTypes.h:48
Diligent::GetRawAllocator
IMemoryAllocator & GetRawAllocator()
Returns raw memory allocator.
Definition: EngineMemory.cpp:51
Diligent::ShaderResourceBindingBase::BindResources
virtual void BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags) override final
Implementation of IShaderResourceBinding::BindResources().
Definition: ShaderResourceBindingBase.hpp:239
Diligent::IsConsistentShaderType
bool IsConsistentShaderType(SHADER_TYPE ShaderType, PIPELINE_TYPE PipelineType)
Definition: GraphicsAccessories.cpp:1388
IMPLEMENT_QUERY_INTERFACE_IN_PLACE
#define IMPLEMENT_QUERY_INTERFACE_IN_PLACE(InterfaceID, ParentClassName)
Definition: ObjectBase.hpp:59
Diligent::ShaderResourceBindingBase::~ShaderResourceBindingBase
~ShaderResourceBindingBase()
Definition: ShaderResourceBindingBase.hpp:134
FixedLinearAllocator.hpp
Diligent::GetShaderTypePipelineIndex
Int32 GetShaderTypePipelineIndex(SHADER_TYPE ShaderType, PIPELINE_TYPE PipelineType)
Definition: GraphicsAccessories.cpp:1422
Diligent::ShaderResourceBindingBase::GetVariableByIndex
virtual IShaderResourceVariable * GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final
Implementation of IShaderResourceBinding::GetVariableByIndex().
Definition: ShaderResourceBindingBase.hpp:219
Diligent::RefCntAutoPtr< ResourceSignatureType >
DILIGENT_CALL_TYPE
#define DILIGENT_CALL_TYPE
Definition: CommonDefinitions.h:45
Diligent::ShaderResourceBindingBase::ShaderResourceBindingBase
ShaderResourceBindingBase(IReferenceCounters *pRefCounters, ResourceSignatureType *pPRS)
Definition: ShaderResourceBindingBase.hpp:73
Diligent::Uint32
uint32_t Uint32
32-bit unsigned integer
Definition: BasicTypes.h:51
Diligent::ShaderResourceBindingBase::GetNumShaders
Uint32 GetNumShaders() const
Definition: ShaderResourceBindingBase.hpp:151
Diligent::ShaderResourceBindingBase::GetPipelineType
PIPELINE_TYPE GetPipelineType() const
Definition: ShaderResourceBindingBase.hpp:146
Diligent::ShaderResourceBindingBase::ShaderVariableManagerImplType
typename EngineImplTraits::ShaderVariableManagerImplType ShaderVariableManagerImplType
Definition: ShaderResourceBindingBase.hpp:67
Diligent::ShaderResourceBindingBase< EngineGLImplTraits >::ShaderResourceCacheImplType
typename EngineGLImplTraits ::ShaderResourceCacheImplType ShaderResourceCacheImplType
Definition: ShaderResourceBindingBase.hpp:64
ShaderResourceBinding.h
Diligent::ResourceCacheContentType::SRB
@ SRB
Resources of a shader resource binding.
Diligent::GetShaderTypeFromPipelineIndex
SHADER_TYPE GetShaderTypeFromPipelineIndex(Int32 Index, PIPELINE_TYPE PipelineType)
Definition: GraphicsAccessories.cpp:1466
LOG_WARNING_MESSAGE
#define LOG_WARNING_MESSAGE(...)
Definition: Errors.hpp:123
Diligent::ShaderResourceBindingBase::StaticResourcesInitialized
virtual bool StaticResourcesInitialized() const override final
Definition: ShaderResourceBindingBase.hpp:162
Diligent::GetPipelineTypeString
const char * GetPipelineTypeString(PIPELINE_TYPE PipelineType)
Definition: GraphicsAccessories.cpp:1145
VERIFY_EXPR
#define VERIFY_EXPR(...)
Definition: DebugUtilities.hpp:79
Diligent::GetShaderTypeLiteralName
const Char * GetShaderTypeLiteralName(SHADER_TYPE ShaderType)
Returns the literal name of a shader type. For instance, for a pixel shader, "SHADER_TYPE_PIXEL" will...
Definition: GraphicsAccessories.cpp:476
RefCntAutoPtr.hpp
GraphicsTypes.h
Diligent::ShaderResourceBindingBase::GetPipelineResourceSignature
virtual IPipelineResourceSignature * GetPipelineResourceSignature() const override final
Implementation of IShaderResourceBinding::GetPipelineResourceSignature().
Definition: ShaderResourceBindingBase.hpp:157
_countof
#define _countof(_Array)
Definition: AndroidPlatformDefinitions.h:38
Diligent::ShaderResourceBindingBase::GetSignature
ResourceSignatureType * GetSignature() const
Definition: ShaderResourceBindingBase.hpp:167
Diligent::ShaderResourceBindingBase< EngineGLImplTraits >::ResourceSignatureType
typename EngineGLImplTraits ::PipelineResourceSignatureImplType ResourceSignatureType
Definition: ShaderResourceBindingBase.hpp:61
Diligent::ShaderResourceBindingBase::m_bStaticResourcesInitialized
bool m_bStaticResourcesInitialized
Definition: ShaderResourceBindingBase.hpp:292
Diligent::ShaderResourceBindingBase::TObjectBase
ObjectBase< BaseInterface > TObjectBase
Definition: ShaderResourceBindingBase.hpp:69
ShaderType
Uint16 ShaderType
Definition: DXBCUtils.cpp:70
Diligent::IMemoryAllocator::Free
virtual void Free(void *Ptr)=0
Releases memory.
Diligent::ShaderResourceBindingBase::m_pPRS
RefCntAutoPtr< ResourceSignatureType > m_pPRS
Strong reference to pipeline resource signature. We must use strong reference, because shader resourc...
Definition: ShaderResourceBindingBase.hpp:282
Diligent
The library uses Direct3D-style math:
Definition: AdvancedMath.hpp:37
Diligent::SHADER_RESOURCE_VARIABLE_TYPE
SHADER_RESOURCE_VARIABLE_TYPE
Describes the type of the shader resource variable.
Definition: ShaderResourceVariable.h:48
Diligent::IResourceMapping
Resouce mapping.
Definition: ResourceMapping.h:107