git.s-ol.nu ~forks/DiligentCore / 44fe2cc
OpenGL: added SRB memory allocator, some minor improvements azhirnov authored 6 months ago assiduous committed 6 months ago
22 changed file(s) with 328 addition(s) and 332 deletion(s). Raw diff Collapse all Expand all
4646 {
4747
4848 /// Validates pipeline resource signature description and throws an exception in case of an error.
49 void ValidatePipelineResourceSignatureDesc(const PipelineResourceSignatureDesc& Desc, bool ShaderResourceRuntimeArraySupported) noexcept(false);
49 void ValidatePipelineResourceSignatureDesc(const PipelineResourceSignatureDesc& Desc,
50 bool ShaderResourceRuntimeArraySupported,
51 bool AccelStructSupported) noexcept(false);
5052
5153 static constexpr Uint32 InvalidImmutableSamplerIndex = ~0u;
5254 /// Finds an immutable sampler for the resource name 'ResourceName' that is defined in shader stages 'ShaderStages'.
9395 this->m_Desc.ImmutableSamplers = nullptr;
9496 this->m_Desc.CombinedSamplerSuffix = nullptr;
9597
96 ValidatePipelineResourceSignatureDesc(Desc, pDevice->GetDeviceCaps().Features.ShaderResourceRuntimeArray);
98 ValidatePipelineResourceSignatureDesc(Desc,
99 pDevice->GetDeviceCaps().Features.ShaderResourceRuntimeArray,
100 pDevice->GetDeviceCaps().Features.RayTracing);
97101
98102 // Determine shader stages that have any resources as well as
99103 // shader stages that have static resources.
211215 {
212216 VERIFY_EXPR(SampIndex < this->m_Desc.NumImmutableSamplers);
213217 return this->m_Desc.ImmutableSamplers[SampIndex];
218 }
219
220 static Uint32 CalcMaxSignatureBindIndex(const Uint32 SignatureCount,
221 IPipelineResourceSignature* ppResourceSignatures[])
222 {
223 Uint32 MaxSignatureBindingIndex = 0;
224 for (Uint32 i = 0; i < SignatureCount; ++i)
225 {
226 const auto* pSignature = ppResourceSignatures[i];
227 VERIFY(pSignature != nullptr, "Pipeline resource signature at index ", i, " is null. This error should've been caught by ValidatePipelineResourceSignatures.");
228 MaxSignatureBindingIndex = std::max(MaxSignatureBindingIndex, Uint32{pSignature->GetDesc().BindingIndex});
229 }
230 return MaxSignatureBindingIndex;
214231 }
215232
216233 template <typename TPipelineResourceSignature>
470470 m_ActiveShaderStages |= ShaderType;
471471 #ifdef DILIGENT_DEBUG
472472 for (Uint32 i = 0; i + 1 < ShaderStages.size(); ++i)
473 VERIFY_EXPR(ShaderStages[i].Type != ShaderType);
473 VERIFY_EXPR(GetShaderStageType(ShaderStages[i]) != ShaderType);
474474 #endif
475475 }
476476 };
3636
3737 #define LOG_PRS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of a pipeline resource signature '", (Desc.Name ? Desc.Name : ""), "' is invalid: ", ##__VA_ARGS__)
3838
39 void ValidatePipelineResourceSignatureDesc(const PipelineResourceSignatureDesc& Desc, bool ShaderResourceRuntimeArraySupported) noexcept(false)
39 void ValidatePipelineResourceSignatureDesc(const PipelineResourceSignatureDesc& Desc,
40 bool ShaderResourceRuntimeArraySupported,
41 bool AccelStructSupported) noexcept(false)
4042 {
4143 if (Desc.BindingIndex >= MAX_RESOURCE_SIGNATURES)
4244 LOG_PRS_ERROR_AND_THROW("Desc.BindingIndex (", Uint32{Desc.BindingIndex}, ") exceeds the maximum allowed value (", MAX_RESOURCE_SIGNATURES - 1, ").");
8486
8587 if ((Res.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0 && !ShaderResourceRuntimeArraySupported)
8688 {
87 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags: RUNTIME_ARRAY can only be used if ShaderResourceRuntimeArray device feature is enabled.");
88 }
89
89 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].Flags (RUNTIME_ARRAY) can only be used if ShaderResourceRuntimeArray device feature is enabled.");
90 }
91
92 if (Res.ResourceType == SHADER_RESOURCE_TYPE_ACCEL_STRUCT && !AccelStructSupported)
93 {
94 LOG_PRS_ERROR_AND_THROW("Incorrect Desc.Resources[", i, "].ResourceType (ACCEL_STRUCT): acceleration structure is not supported by device.");
95 }
9096 static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please add the new resource type to the switch below");
9197
9298 auto AllowedResourceFlags = GetValidPipelineResourceFlags(Res.ResourceType);
232232
233233 bool IsCompatibleWith(const PipelineResourceSignatureD3D12Impl& Other) const;
234234
235 bool IsIncompatibleWith(const PipelineResourceSignatureD3D12Impl& Other) const
236 {
237 return GetHash() != Other.GetHash();
238 }
239
240235 SRBMemoryAllocator& GetSRBMemoryAllocator()
241236 {
242237 return m_SRBMemAllocator;
100100 SHADER_TYPE Type = SHADER_TYPE_UNKNOWN;
101101 std::vector<ShaderD3D12Impl*> Shaders;
102102 std::vector<CComPtr<ID3DBlob>> ByteCodes;
103
104 friend SHADER_TYPE GetShaderStageType(const ShaderStageInfo& Stage) { return Stage.Type; }
103105 };
104106 using TShaderStages = std::vector<ShaderStageInfo>;
105107
6666 void Destruct();
6767
6868 ShaderResourceCacheD3D12 m_ShaderResourceCache;
69 ShaderVariableManagerD3D12* m_pShaderVarMgrs = nullptr;
69 ShaderVariableManagerD3D12* m_pShaderVarMgrs = nullptr; // [GetNumShaders()]
7070 };
7171
7272 } // namespace Diligent
166166 {}
167167
168168 // clang-format off
169 ShaderVariableD3D12Impl (const ShaderVariableD3D12Impl&) = delete;
170 ShaderVariableD3D12Impl (ShaderVariableD3D12Impl&&) = delete;
171 ShaderVariableD3D12Impl& operator= (const ShaderVariableD3D12Impl&) = delete;
172 ShaderVariableD3D12Impl& operator= (ShaderVariableD3D12Impl&&) = delete;
169 ShaderVariableD3D12Impl (const ShaderVariableD3D12Impl&) = delete;
170 ShaderVariableD3D12Impl ( ShaderVariableD3D12Impl&&) = delete;
171 ShaderVariableD3D12Impl& operator= (const ShaderVariableD3D12Impl&) = delete;
172 ShaderVariableD3D12Impl& operator= ( ShaderVariableD3D12Impl&&) = delete;
173173 // clang-format on
174174
175175 virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final
552552 }
553553 else
554554 {
555 Uint32 MaxSignatureBindingIndex = 0;
556 for (Uint32 i = 0; i < CreateInfo.ResourceSignaturesCount; ++i)
557 {
558 const auto* pSignature = ValidatedCast<const PipelineResourceSignatureD3D12Impl>(CreateInfo.ppResourceSignatures[i]);
559 VERIFY(pSignature != nullptr, "Pipeline resource signature at index ", i, " is null. This error should've been caught by ValidatePipelineResourceSignatures.");
560 MaxSignatureBindingIndex = std::max(MaxSignatureBindingIndex, Uint32{pSignature->GetDesc().BindingIndex});
561 }
562 SignatureCount = MaxSignatureBindingIndex + 1;
555 Uint32 MaxSignatureBindingIndex = PipelineResourceSignatureD3D12Impl::CalcMaxSignatureBindIndex(CreateInfo.ResourceSignaturesCount, CreateInfo.ppResourceSignatures);
556 SignatureCount = MaxSignatureBindingIndex + 1;
563557 m_ResourceSignatures.reset(new RefCntAutoPtr<PipelineResourceSignatureD3D12Impl>[SignatureCount]);
564558
565559 auto DbgMaxSignatureBindingIndex =
3434 #include "PipelineResourceSignatureBase.hpp"
3535 #include "ShaderResourceCacheGL.hpp"
3636 #include "ShaderResourcesGL.hpp"
37 #include "SRBMemoryAllocator.hpp"
3738
3839 namespace Diligent
3940 {
173174 return GetHash() != Other.GetHash() || m_BindingCount != Other.m_BindingCount;
174175 }
175176
176 void InitSRBResourceCache(ShaderResourceCacheGL& ResourceCache) const;
177 SRBMemoryAllocator& GetSRBMemoryAllocator()
178 {
179 return m_SRBMemAllocator;
180 }
181
182 void InitSRBResourceCache(ShaderResourceCacheGL& ResourceCache, IMemoryAllocator& CacheMemAllocator) const;
177183
178184 #ifdef DILIGENT_DEVELOPMENT
179185 /// Verifies committed resource attribs using the SPIRV resource attributes from the PSO.
214220
215221 using SamplerPtr = RefCntAutoPtr<ISampler>;
216222 SamplerPtr* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
223
224 SRBMemoryAllocator m_SRBMemAllocator;
217225 };
218226
219227 } // namespace Diligent
7676
7777 void CommitProgram(GLContextState& State);
7878
79 Uint32 GetSignatureCount() const { return m_SignatureCount; }
80
8179 PipelineResourceSignatureGLImpl* GetSignature(Uint32 index) const
8280 {
8381 VERIFY_EXPR(index < m_SignatureCount);
9088 #endif
9189
9290 private:
93 using ShaderStageInfo = ShaderGLImpl::ShaderStageInfo;
94 using TShaderStages = std::vector<ShaderStageInfo>;
91 using TShaderStages = std::vector<ShaderGLImpl*>;
9592
9693 GLObjectWrappers::GLPipelineObj& GetGLProgramPipeline(GLContext::NativeGLContextType Context);
9794
183180 #endif
184181 };
185182
183 __forceinline SHADER_TYPE GetShaderStageType(const ShaderGLImpl* pShader)
184 {
185 return pShader->GetDesc().ShaderType;
186 }
187
186188 } // namespace Diligent
9191 /// Implementation of IShader::GetResource() in OpenGL backend.
9292 virtual void DILIGENT_CALL_TYPE GetResourceDesc(Uint32 Index, ShaderResourceDesc& ResourceDesc) const override final;
9393
94 struct ShaderStageInfo
95 {
96 ShaderStageInfo(const ShaderGLImpl* _pShader);
97
98 SHADER_TYPE Type = SHADER_TYPE_UNKNOWN;
99 const ShaderGLImpl* pShader = nullptr;
100 };
101 static GLObjectWrappers::GLProgramObj LinkProgram(const ShaderStageInfo* pShaderStagess, Uint32 NumShaders, bool IsSeparableProgram);
94 static GLObjectWrappers::GLProgramObj LinkProgram(ShaderGLImpl* const* ppShaders, Uint32 NumShaders, bool IsSeparableProgram);
10295
10396 const std::shared_ptr<const ShaderResourcesGL>& GetShaderResources() const { return m_pShaderResources; }
10497
118118 RefCntAutoPtr<BufferViewGLImpl> pBufferView;
119119 };
120120
121
122 static size_t GetRequriedMemorySize(Uint32 UBCount, Uint32 TextureCount, Uint32 ImageCount, Uint32 SSBOCount);
123
124 void Initialize(Uint32 UBCount, Uint32 TextureCount, Uint32 ImageCount, Uint32 SSBOCount, IMemoryAllocator& MemAllocator);
125 void Destroy(IMemoryAllocator& MemAllocator);
121 using TResourceCount = std::array<Uint32, 4>; // same as PipelineResourceSignatureGLImpl::TBindings.
122 static size_t GetRequriedMemorySize(const TResourceCount& ResCount);
123
124 void Initialize(const TResourceCount& Count, IMemoryAllocator& MemAllocator);
126125
127126 void SetUniformBuffer(Uint32 CacheOffset, RefCntAutoPtr<BufferGLImpl>&& pBuff)
128127 {
274273 return const_cast<CachedSSBO&>(const_cast<const ShaderResourceCacheGL*>(this)->GetConstSSBO(CacheOffset));
275274 }
276275
276 private:
277277 static constexpr const Uint16 InvalidResourceOffset = 0xFFFF;
278278 static constexpr const Uint16 m_UBsOffset = 0;
279279
282282 Uint16 m_SSBOsOffset = InvalidResourceOffset;
283283 Uint16 m_MemoryEndOffset = InvalidResourceOffset;
284284
285 Uint8* m_pResourceData = nullptr;
285 Uint8* m_pResourceData = nullptr;
286 IMemoryAllocator* m_pAllocator = nullptr;
286287
287288 // Indicates what types of resources are stored in the cache
288289 const CacheContentType m_ContentType;
289290
290 #ifdef DILIGENT_DEBUG
291 IMemoryAllocator* m_pdbgMemoryAllocator = nullptr;
292 #endif
293291 #ifdef DILIGENT_DEVELOPMENT
294292 bool m_bStaticResourcesInitialized = false;
295293 #endif
8787
8888 ~ShaderVariableManagerGL();
8989
90 void DestroyVariables(IMemoryAllocator& Allocator);
91
9092 // No copies, only moves are allowed
9193 // clang-format off
9294 ShaderVariableManagerGL (const ShaderVariableManagerGL&) = delete;
9698 // clang-format on
9799
98100 void Initialize(const PipelineResourceSignatureGLImpl& Signature,
101 IMemoryAllocator& Allocator,
99102 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
100103 Uint32 NumAllowedTypes,
101104 SHADER_TYPE ShaderType);
121124
122125 struct GLVariableBase : public ShaderVariableBase<ShaderVariableManagerGL>
123126 {
127 public:
124128 using TBase = ShaderVariableBase<ShaderVariableManagerGL>;
125129 GLVariableBase(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
126130 TBase{ParentLayout},
148152 return m_ParentManager.GetVariableIndex(*this);
149153 }
150154
155 private:
151156 const Uint32 m_ResIndex;
152157 };
153158
184189 };
185190
186191
187 struct SamplerBindInfo final : GLVariableBase
188 {
189 SamplerBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
192 struct TextureBindInfo final : GLVariableBase
193 {
194 TextureBindInfo(ShaderVariableManagerGL& ParentLayout, Uint32 ResIndex) :
190195 GLVariableBase{ParentLayout, ResIndex}
191196 {}
192197
210215
211216 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
212217 {
213 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
214 return m_ParentManager.m_ResourceCache.IsTextureBound(GetAttribs().CacheOffset + ArrayIndex, GetDesc().ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV);
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);
215222 }
216223 };
217224
242249
243250 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
244251 {
245 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
246 return m_ParentManager.m_ResourceCache.IsImageBound(GetAttribs().CacheOffset + ArrayIndex, GetDesc().ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
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);
247256 }
248257 };
249258
297306
298307 // clang-format off
299308 Uint32 GetNumUBs() const { return (m_TextureOffset - m_UBOffset) / sizeof(UniformBuffBindInfo); }
300 Uint32 GetNumTextures() const { return (m_ImageOffset - m_TextureOffset) / sizeof(SamplerBindInfo); }
309 Uint32 GetNumTextures() const { return (m_ImageOffset - m_TextureOffset) / sizeof(TextureBindInfo); }
301310 Uint32 GetNumImages() const { return (m_StorageBufferOffset - m_ImageOffset) / sizeof(ImageBindInfo) ; }
302311 Uint32 GetNumStorageBuffers() const { return (m_VariableEndOffset - m_StorageBufferOffset) / sizeof(StorageBufferBindInfo); }
303312 // clang-format on
309318 {
310319 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>(), ")");
311320 auto Offset = GetResourceOffset<ResourceType>();
312 return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex];
321 return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
313322 }
314323
315324 Uint32 GetVariableIndex(const GLVariableBase& Var) const;
345354 {
346355 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>() - 1, ")");
347356 auto Offset = GetResourceOffset<ResourceType>();
348 return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex];
357 return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
349358 }
350359
351360 template <typename ResourceType>
352361 IShaderResourceVariable* GetResourceByName(const Char* Name) const;
353362
354363 template <typename THandleUB,
355 typename THandleSampler,
364 typename THandleTexture,
356365 typename THandleImage,
357366 typename THandleStorageBuffer>
358367 void HandleResources(THandleUB HandleUB,
359 THandleSampler HandleSampler,
368 THandleTexture HandleTexture,
360369 THandleImage HandleImage,
361370 THandleStorageBuffer HandleStorageBuffer)
362371 {
363372 for (Uint32 ub = 0; ub < GetNumResources<UniformBuffBindInfo>(); ++ub)
364373 HandleUB(GetResource<UniformBuffBindInfo>(ub));
365374
366 for (Uint32 s = 0; s < GetNumResources<SamplerBindInfo>(); ++s)
367 HandleSampler(GetResource<SamplerBindInfo>(s));
375 for (Uint32 s = 0; s < GetNumResources<TextureBindInfo>(); ++s)
376 HandleTexture(GetResource<TextureBindInfo>(s));
368377
369378 for (Uint32 i = 0; i < GetNumResources<ImageBindInfo>(); ++i)
370379 HandleImage(GetResource<ImageBindInfo>(i));
374383 }
375384
376385 template <typename THandleUB,
377 typename THandleSampler,
386 typename THandleTexture,
378387 typename THandleImage,
379388 typename THandleStorageBuffer>
380389 void HandleConstResources(THandleUB HandleUB,
381 THandleSampler HandleSampler,
390 THandleTexture HandleTexture,
382391 THandleImage HandleImage,
383392 THandleStorageBuffer HandleStorageBuffer) const
384393 {
385394 for (Uint32 ub = 0; ub < GetNumResources<UniformBuffBindInfo>(); ++ub)
386395 HandleUB(GetConstResource<UniformBuffBindInfo>(ub));
387396
388 for (Uint32 s = 0; s < GetNumResources<SamplerBindInfo>(); ++s)
389 HandleSampler(GetConstResource<SamplerBindInfo>(s));
397 for (Uint32 s = 0; s < GetNumResources<TextureBindInfo>(); ++s)
398 HandleTexture(GetConstResource<TextureBindInfo>(s));
390399
391400 for (Uint32 i = 0; i < GetNumResources<ImageBindInfo>(); ++i)
392401 HandleImage(GetConstResource<ImageBindInfo>(i));
404413 IObject& m_Owner;
405414 // No need to use shared pointer, as the resource cache is either part of the same
406415 // ShaderGLImpl object, or ShaderResourceBindingGLImpl object
407 ShaderResourceCacheGL& m_ResourceCache;
408 std::unique_ptr<void, STDDeleterRawMem<void>> m_ResourceBuffer;
416 ShaderResourceCacheGL& m_ResourceCache;
417 void* m_ResourceBuffer = nullptr;
409418
410419 static constexpr OffsetType m_UBOffset = 0;
411420 OffsetType m_TextureOffset = 0;
412421 OffsetType m_ImageOffset = 0;
413422 OffsetType m_StorageBufferOffset = 0;
414423 OffsetType m_VariableEndOffset = 0;
424
425 #ifdef DILIGENT_DEBUG
426 IMemoryAllocator* m_pDbgAllocator = nullptr;
427 #endif
415428 };
416429
417430
422435 }
423436
424437 template <>
425 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::SamplerBindInfo>() const
438 inline Uint32 ShaderVariableManagerGL::GetNumResources<ShaderVariableManagerGL::TextureBindInfo>() const
426439 {
427440 return GetNumTextures();
428441 }
450463
451464 template <>
452465 inline ShaderVariableManagerGL::OffsetType ShaderVariableManagerGL::
453 GetResourceOffset<ShaderVariableManagerGL::SamplerBindInfo>() const
466 GetResourceOffset<ShaderVariableManagerGL::TextureBindInfo>() const
454467 {
455468 return m_TextureOffset;
456469 }
155155 // the draw command.
156156 m_pPipelineState->CommitProgram(m_ContextState);
157157
158 const auto SignCount = m_pPipelineState->GetSignatureCount();
158 const auto SignCount = m_pPipelineState->GetResourceSignatureCount();
159159
160160 m_BindInfo.ActiveSRBMask = 0;
161161 for (Uint32 s = 0; s < SignCount; ++s)
707707 {
708708 Uint32 sign = PlatformMisc::GetLSB(ActiveSRBMask);
709709 Uint32 SigBit = (1u << sign);
710 VERIFY_EXPR(sign < m_pPipelineState->GetSignatureCount());
710 VERIFY_EXPR(sign < m_pPipelineState->GetResourceSignatureCount());
711711
712712 ActiveSRBMask &= ~SigBit;
713713
714714 const auto* pSRB = m_BindInfo.SRBs[sign];
715715 VERIFY_EXPR(pSRB);
716716
717 //if (m_BindInfo.StaleSRBMask & SigBit)
717 if (m_BindInfo.StaleSRBMask & SigBit)
718718 {
719719 BindProgramResources(m_CommitedResourcesTentativeBarriers, pSRB, Bindings);
720720
5252 PatchedPipelineResourceSignatureDesc(RenderDeviceGLImpl* pDeviceGL, const PipelineResourceSignatureDesc& Desc) :
5353 PipelineResourceSignatureDesc{Desc}
5454 {
55 if (NumImmutableSamplers > 0 && !pDeviceGL->GetDeviceCaps().Features.SeparablePrograms)
55 if (NumImmutableSamplers > 0 && ImmutableSamplers != nullptr && !pDeviceGL->GetDeviceCaps().Features.SeparablePrograms)
5656 {
5757 m_ImmutableSamplers.resize(NumImmutableSamplers);
5858
9696 switch (Desc.ResourceType)
9797 {
9898 // clang-format off
99 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return BINDING_RANGE_UNIFORM_BUFFER;
100 case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return BINDING_RANGE_TEXTURE;
101 case SHADER_RESOURCE_TYPE_BUFFER_SRV: return (Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? BINDING_RANGE_TEXTURE : BINDING_RANGE_STORAGE_BUFFER;
102 case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return BINDING_RANGE_IMAGE;
103 case SHADER_RESOURCE_TYPE_BUFFER_UAV: return (Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? BINDING_RANGE_IMAGE : BINDING_RANGE_STORAGE_BUFFER;
104 // clang-format on
99 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return BINDING_RANGE_UNIFORM_BUFFER;
100 case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return BINDING_RANGE_TEXTURE;
101 case SHADER_RESOURCE_TYPE_BUFFER_SRV: return (Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? BINDING_RANGE_TEXTURE : BINDING_RANGE_STORAGE_BUFFER;
102 case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return BINDING_RANGE_IMAGE;
103 case SHADER_RESOURCE_TYPE_BUFFER_UAV: return (Desc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? BINDING_RANGE_IMAGE : BINDING_RANGE_STORAGE_BUFFER;
104 case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT: return BINDING_RANGE_TEXTURE;
105 // clang-format on
105106 case SHADER_RESOURCE_TYPE_SAMPLER:
106 case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT:
107107 case SHADER_RESOURCE_TYPE_ACCEL_STRUCT:
108108 default:
109 UNEXPECTED("Unsupported resource type");
109110 return BINDING_RANGE_UNKNOWN;
110111 }
111112 }
123124 const PipelineResourceSignatureDesc& Desc,
124125 bool bIsDeviceInternal,
125126 int) :
126 TPipelineResourceSignatureBase{pRefCounters, pDeviceGL, Desc, bIsDeviceInternal}
127 TPipelineResourceSignatureBase{pRefCounters, pDeviceGL, Desc, bIsDeviceInternal},
128 m_SRBMemAllocator{GetRawAllocator()}
127129 {
128130 try
129131 {
144146
145147 MemPool.Reserve();
146148
149 static_assert(std::is_trivially_destructible<ResourceAttribs>::value,
150 "ResourceAttribs objects must be constructed to be properly destructed in case an excpetion is thrown");
147151 m_pResourceAttribs = MemPool.Allocate<ResourceAttribs>(std::max(1u, m_Desc.NumResources));
148152 m_ImmutableSamplers = MemPool.ConstructArray<SamplerPtr>(m_Desc.NumImmutableSamplers);
149153
172176 {
173177 VERIFY_EXPR(static_cast<Uint32>(Idx) < NumStaticResStages);
174178 const auto ShaderType = GetShaderTypeFromPipelineIndex(i, GetPipelineType());
175 m_StaticVarsMgrs[Idx].Initialize(*this, AllowedVarTypes, _countof(AllowedVarTypes), ShaderType);
176 }
177 }
179 m_StaticVarsMgrs[Idx].Initialize(*this, GetRawAllocator(), AllowedVarTypes, _countof(AllowedVarTypes), ShaderType);
180 }
181 }
182 }
183
184 if (m_Desc.SRBAllocationGranularity > 1)
185 {
186 std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderVariableDataSizes = {};
187 for (Uint32 s = 0; s < GetNumActiveShaderStages(); ++s)
188 {
189 constexpr SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC};
190
191 ShaderVariableDataSizes[s] = ShaderVariableManagerGL::GetRequiredMemorySize(*this, AllowedVarTypes, _countof(AllowedVarTypes), GetActiveShaderStageType(s));
192 }
193
194 const size_t CacheMemorySize = ShaderResourceCacheGL::GetRequriedMemorySize(m_BindingCount);
195 m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumActiveShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize);
178196 }
179197
180198 m_Hash = CalculateHash();
188206
189207 void PipelineResourceSignatureGLImpl::CreateLayouts()
190208 {
191 std::array<Uint32, BINDING_RANGE_COUNT> StaticCounter = {};
209 TBindings StaticCounter = {};
192210
193211 for (Uint32 s = 0; s < m_Desc.NumImmutableSamplers; ++s)
194212 GetDevice()->CreateSampler(m_Desc.ImmutableSamplers[s].Desc, &m_ImmutableSamplers[s]);
247265
248266 if (m_pStaticResCache)
249267 {
250 m_pStaticResCache->Initialize(StaticCounter[BINDING_RANGE_UNIFORM_BUFFER],
251 StaticCounter[BINDING_RANGE_TEXTURE],
252 StaticCounter[BINDING_RANGE_IMAGE],
253 StaticCounter[BINDING_RANGE_STORAGE_BUFFER],
254 GetRawAllocator());
268 m_pStaticResCache->Initialize(StaticCounter, GetRawAllocator());
255269 // Set immutable samplers for static resources.
256270 const auto ResIdxRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
257271
325339 for (auto Idx : m_StaticResStageIndex)
326340 {
327341 if (Idx >= 0)
342 {
343 m_StaticVarsMgrs[Idx].DestroyVariables(RawAllocator);
328344 m_StaticVarsMgrs[Idx].~ShaderVariableManagerGL();
345 }
329346 }
330347 m_StaticVarsMgrs = nullptr;
331348 }
332349
333350 if (m_pStaticResCache)
334351 {
335 m_pStaticResCache->Destroy(RawAllocator);
352 m_pStaticResCache->~ShaderResourceCacheGL();
336353 m_pStaticResCache = nullptr;
337354 }
338355
357374 {
358375 const auto& ResDesc = m_Desc.Resources[r];
359376 const auto& ResAttr = m_pResourceAttribs[r];
360 const auto Range = PipelineResourceToBindingRange(ResDesc);
361
362 if (Range == BINDING_RANGE_UNKNOWN)
377
378 if (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER)
363379 continue;
364380
365381 if ((ResDesc.ShaderStages & Stages) == 0)
366382 continue;
367383
384 const auto Range = PipelineResourceToBindingRange(ResDesc);
368385 const Uint32 BindingIndex = Bindings[Range] + ResAttr.CacheOffset;
369386
370387 static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range");
629646 #endif
630647 }
631648
632 void PipelineResourceSignatureGLImpl::InitSRBResourceCache(ShaderResourceCacheGL& ResourceCache) const
633 {
634 ResourceCache.Initialize(m_BindingCount[BINDING_RANGE_UNIFORM_BUFFER],
635 m_BindingCount[BINDING_RANGE_TEXTURE],
636 m_BindingCount[BINDING_RANGE_IMAGE],
637 m_BindingCount[BINDING_RANGE_STORAGE_BUFFER],
638 GetRawAllocator());
649 void PipelineResourceSignatureGLImpl::InitSRBResourceCache(ShaderResourceCacheGL& ResourceCache, IMemoryAllocator& CacheMemAllocator) const
650 {
651 ResourceCache.Initialize(m_BindingCount, CacheMemAllocator);
639652 }
640653
641654 bool PipelineResourceSignatureGLImpl::IsCompatibleWith(const PipelineResourceSignatureGLImpl& Other) const
714727 case BINDING_RANGE_TEXTURE:
715728 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
716729 {
717 if (!ResourceCache.IsTextureBound(ResAttr.CacheOffset + ArrInd, ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV))
730 const bool IsTexView = (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || ResDesc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
731 if (!ResourceCache.IsTextureBound(ResAttr.CacheOffset + ArrInd, IsTexView))
718732 {
719733 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(GLAttribs, ArrInd),
720734 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
732746 case BINDING_RANGE_IMAGE:
733747 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
734748 {
735 if (!ResourceCache.IsImageBound(ResAttr.CacheOffset + ArrInd, ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV))
749 const bool IsImgView = (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
750 if (!ResourceCache.IsImageBound(ResAttr.CacheOffset + ArrInd, IsImgView))
736751 {
737752 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(GLAttribs, ArrInd),
738753 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
132132 {
133133 for (size_t i = 0; i < ShaderStages.size(); ++i)
134134 {
135 auto* pShaderGL = ShaderStages[i].pShader;
135 auto* pShaderGL = ShaderStages[i];
136136 pShaderGL->GetShaderResources()->ProcessConstResources(HandleUB, HandleTexture, HandleImage, HandleSB);
137137 }
138138 }
233233 {
234234 for (size_t i = 0; i < ShaderStages.size(); ++i)
235235 {
236 auto* pShaderGL = ShaderStages[i].pShader;
236 auto* pShaderGL = ShaderStages[i];
237237 DvpValidateShaderResources(pShaderGL->GetShaderResources(), pShaderGL->GetDesc().Name, pShaderGL->GetDesc().ShaderType);
238238 }
239239 }
271271
272272 // Get active shader stages.
273273 SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN;
274 for (auto& Stage : ShaderStages)
275 {
276 const auto ShaderType = Stage.pShader->GetDesc().ShaderType;
274 for (auto* pShaderGL : ShaderStages)
275 {
276 const auto ShaderType = pShaderGL->GetDesc().ShaderType;
277277 VERIFY((ActiveStages & ShaderType) == 0, "Shader stage ", GetShaderTypeLiteralName(ShaderType), " is already active");
278278 ActiveStages |= ShaderType;
279279 }
281281 // Create programs.
282282 if (m_IsProgramPipelineSupported)
283283 {
284 VERIFY_EXPR(m_ShaderTypes.size() >= ShaderStages.size());
284285 m_GLPrograms = MemPool.ConstructArray<GLProgramObj>(ShaderStages.size(), false);
285286 for (size_t i = 0; i < ShaderStages.size(); ++i)
286287 {
287 auto* pShaderGL = ShaderStages[i].pShader;
288 auto* pShaderGL = ShaderStages[i];
288289 m_GLPrograms[i] = GLProgramObj{ShaderGLImpl::LinkProgram(&ShaderStages[i], 1, true)};
289290 m_ShaderTypes[i] = pShaderGL->GetDesc().ShaderType;
290291 }
416417 const auto& lhs = *this;
417418 const auto& rhs = *ValidatedCast<const PipelineStateGLImpl>(pPSO);
418419
419 if (lhs.GetSignatureCount() != rhs.GetSignatureCount())
420 if (lhs.GetResourceSignatureCount() != rhs.GetResourceSignatureCount())
420421 return false;
421422
422 for (Uint32 s = 0, SigCount = lhs.GetSignatureCount(); s < SigCount; ++s)
423 for (Uint32 s = 0, SigCount = lhs.GetResourceSignatureCount(); s < SigCount; ++s)
423424 {
424425 if (!lhs.GetSignature(s)->IsCompatibleWith(*rhs.GetSignature(s)))
425426 return false;
474475 #ifdef DILIGENT_DEVELOPMENT
475476 PipelineStateGLImpl::ResourceAttribution PipelineStateGLImpl::GetResourceAttribution(const char* Name, SHADER_TYPE Stage) const
476477 {
477 const auto SignCount = GetSignatureCount();
478 const auto SignCount = GetResourceSignatureCount();
478479 for (Uint32 sign = 0; sign < SignCount; ++sign)
479480 {
480481 const auto* const pSignature = GetSignature(sign);
499500 m_ShaderResources.emplace_back(pShaderResources);
500501 m_ShaderNames.emplace_back(ShaderName);
501502
502 const auto HandleResource = [&](const ShaderResourcesGL::GLResourceAttribs& Attribs, SHADER_RESOURCE_TYPE ReadOnlyResourceType, PIPELINE_RESOURCE_FLAGS Flags) //
503 const auto HandleResource = [&](const ShaderResourcesGL::GLResourceAttribs& Attribs, SHADER_RESOURCE_TYPE AltResourceType, PIPELINE_RESOURCE_FLAGS Flags) //
503504 {
504505 m_ResourceAttibutions.emplace_back();
505506 auto& ResAttribution = m_ResourceAttibutions.back();
520521 const auto& ResDesc = pSignature->GetResourceDesc(ResAttribution.ResourceIndex);
521522
522523 // Shader reflection does not contain read-only flag, so image and storage buffer can be UAV or SRV.
523 if (Attribs.ResourceType != ResDesc.ResourceType &&
524 ReadOnlyResourceType != ResDesc.ResourceType)
525 {
526 LOG_ERROR_AND_THROW("Shader '", ShaderName, "' contains resource with name '", Attribs.Name,
527 "' and type '", GetShaderResourceTypeLiteralName(Attribs.ResourceType), "' that is not compatible with type '",
528 GetShaderResourceTypeLiteralName(ResDesc.ResourceType), "' in pipeline resource signature '", pSignature->GetDesc().Name, "'.");
529 }
530
531 if ((Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER))
532 {
533 LOG_ERROR_AND_THROW("Shader '", ShaderName, "' contains resource '", Attribs.Name,
534 "' that is", ((Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? "" : " not"),
535 " labeled as formatted buffer, while the same resource specified by the pipeline resource signature '",
536 pSignature->GetDesc().Name, "' is", ((ResDesc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) ? "" : " not"),
537 " labeled as such.");
538 }
524 // Texture SRV is same as input attachment.
525 const auto Type = (AltResourceType == ResDesc.ResourceType ? AltResourceType : Attribs.ResourceType);
526
527 ValidatePipelineResourceCompatibility(ResDesc, Type, Flags, Attribs.ArraySize, ShaderName, pSignature->GetDesc().Name);
528 }
529 else
530 {
531 UNEXPECTED("Resource index should be valid");
539532 }
540533 };
541534
546539 const auto HandleTexture = [&](const ShaderResourcesGL::TextureInfo& Attribs) {
547540 const bool IsTexelBuffer = (Attribs.ResourceType != SHADER_RESOURCE_TYPE_TEXTURE_SRV);
548541 HandleResource(Attribs,
549 Attribs.ResourceType,
542 IsTexelBuffer ? Attribs.ResourceType : SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT,
550543 IsTexelBuffer ? PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER : PIPELINE_RESOURCE_FLAG_COMBINED_SAMPLER);
551544 };
552545
4040 namespace Diligent
4141 {
4242
43 ShaderGLImpl::ShaderStageInfo::ShaderStageInfo(const ShaderGLImpl* _pShader) :
44 Type{_pShader->GetDesc().ShaderType},
45 pShader{_pShader}
46 {}
47
4843 ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters,
4944 RenderDeviceGLImpl* pDeviceGL,
5045 const ShaderCreateInfo& ShaderCI,
162157
163158 if (deviceCaps.Features.SeparablePrograms)
164159 {
165 ShaderStageInfo ThisShader[] = {ShaderStageInfo{this}};
160 ShaderGLImpl* const ThisShader[] = {this};
166161 GLObjectWrappers::GLProgramObj Program = LinkProgram(ThisShader, 1, true);
167162 auto pImmediateCtx = m_pDevice->GetImmediateContext();
168163 VERIFY_EXPR(pImmediateCtx);
181176 IMPLEMENT_QUERY_INTERFACE(ShaderGLImpl, IID_ShaderGL, TShaderBase)
182177
183178
184 GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(const ShaderStageInfo* pShaderStagess, Uint32 NumShaders, bool IsSeparableProgram)
179 GLObjectWrappers::GLProgramObj ShaderGLImpl::LinkProgram(ShaderGLImpl* const* ppShaders, Uint32 NumShaders, bool IsSeparableProgram)
185180 {
186181 VERIFY(!IsSeparableProgram || NumShaders == 1, "Number of shaders must be 1 when separable program is created");
187182
193188
194189 for (Uint32 i = 0; i < NumShaders; ++i)
195190 {
196 auto* pCurrShader = pShaderStagess[i].pShader;
191 auto* pCurrShader = ppShaders[i];
197192 glAttachShader(GLProg, pCurrShader->m_GLShaderObj);
198193 CHECK_GL_ERROR("glAttachShader() failed");
199194 }
232227
233228 for (Uint32 i = 0; i < NumShaders; ++i)
234229 {
235 auto* pCurrShader = ValidatedCast<const ShaderGLImpl>(pShaderStagess[i].pShader);
230 auto* pCurrShader = ValidatedCast<const ShaderGLImpl>(ppShaders[i]);
236231 glDetachShader(GLProg, pCurrShader->m_GLShaderObj);
237232 CHECK_GL_ERROR("glDetachShader() failed");
238233 }
6161 // It is important to construct all objects before initializing them because if an exception is thrown,
6262 // destructors will be called for all objects
6363
64 pPRS->InitSRBResourceCache(m_ShaderResourceCache);
64 // This will only allocate memory and initialize descriptor sets in the resource cache
65 // Resources will be initialized by InitializeResourceMemoryInCache()
66 auto& SRBMemAllocator = pPRS->GetSRBMemoryAllocator();
67 auto& ResourceCacheDataAllocator = SRBMemAllocator.GetResourceCacheDataAllocator(0);
68 pPRS->InitSRBResourceCache(m_ShaderResourceCache, ResourceCacheDataAllocator);
6569
6670 for (Uint32 s = 0; s < NumShaders; ++s)
6771 {
7074 const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd];
7175 VERIFY_EXPR(MgrInd >= 0 && MgrInd < static_cast<int>(NumShaders));
7276
77 auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s);
78
7379 // Create shader variable manager in place
7480 // Initialize vars manager to reference mutable and dynamic variables
7581 // Note that the cache has space for all variable types
7682 const SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC};
77 m_pShaderVarMgrs[MgrInd].Initialize(*pPRS, VarTypes, _countof(VarTypes), ShaderType);
83 m_pShaderVarMgrs[MgrInd].Initialize(*pPRS, VarDataAllocator, VarTypes, _countof(VarTypes), ShaderType);
7884 }
7985 }
8086 catch (...)
9197
9298 void ShaderResourceBindingGLImpl::Destruct()
9399 {
94 auto& RawAllocator = GetRawAllocator();
95
96100 if (m_pShaderVarMgrs != nullptr)
97101 {
98 const auto NumShaders = GetNumShaders();
99 for (Uint32 s = 0; s < NumShaders; ++s)
102 auto& SRBMemAllocator = GetSignature()->GetSRBMemoryAllocator();
103 for (Uint32 s = 0; s < GetNumShaders(); ++s)
104 {
105 auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s);
106 m_pShaderVarMgrs[s].DestroyVariables(VarDataAllocator);
100107 m_pShaderVarMgrs[s].~ShaderVariableManagerGL();
108 }
101109
102 RawAllocator.Free(m_pShaderVarMgrs);
110 GetRawAllocator().Free(m_pShaderVarMgrs);
103111 m_pShaderVarMgrs = nullptr;
104112 }
105
106 m_ShaderResourceCache.Destroy(RawAllocator);
107113 }
108114
109115 IMPLEMENT_QUERY_INTERFACE(ShaderResourceBindingGLImpl, IID_ShaderResourceBindingGL, TBase)
2626
2727 #include "pch.h"
2828 #include "ShaderResourceCacheGL.hpp"
29 #include "PipelineResourceSignatureGLImpl.hpp"
2930
3031 namespace Diligent
3132 {
3233
33 size_t ShaderResourceCacheGL::GetRequriedMemorySize(Uint32 UBCount, Uint32 TextureCount, Uint32 ImageCount, Uint32 SSBOCount)
34 size_t ShaderResourceCacheGL::GetRequriedMemorySize(const TResourceCount& ResCount)
3435 {
36 static_assert(std::is_same<TResourceCount, PipelineResourceSignatureGLImpl::TBindings>::value,
37 "ShaderResourceCacheGL::TResourceCount must be the same type as PipelineResourceSignatureGLImpl::TBindings");
3538 // clang-format off
3639 auto MemSize =
37 sizeof(CachedUB) * UBCount +
38 sizeof(CachedResourceView) * TextureCount +
39 sizeof(CachedResourceView) * ImageCount +
40 sizeof(CachedSSBO) * SSBOCount;
40 sizeof(CachedUB) * ResCount[BINDING_RANGE_UNIFORM_BUFFER] +
41 sizeof(CachedResourceView) * ResCount[BINDING_RANGE_TEXTURE] +
42 sizeof(CachedResourceView) * ResCount[BINDING_RANGE_IMAGE] +
43 sizeof(CachedSSBO) * ResCount[BINDING_RANGE_STORAGE_BUFFER];
4144 // clang-format on
45 VERIFY(MemSize < InvalidResourceOffset, "Memory size exeed the maximum allowed size.");
4246 return MemSize;
4347 }
4448
45 void ShaderResourceCacheGL::Initialize(Uint32 UBCount, Uint32 TextureCount, Uint32 ImageCount, Uint32 SSBOCount, IMemoryAllocator& MemAllocator)
49 void ShaderResourceCacheGL::Initialize(const TResourceCount& ResCount, IMemoryAllocator& MemAllocator)
4650 {
51 VERIFY(m_pAllocator == nullptr && m_pResourceData == nullptr, "Cache already initialized");
52 m_pAllocator = &MemAllocator;
53
4754 // clang-format off
48 m_TexturesOffset = static_cast<Uint16>(m_UBsOffset + sizeof(CachedUB) * UBCount);
49 m_ImagesOffset = static_cast<Uint16>(m_TexturesOffset + sizeof(CachedResourceView) * TextureCount);
50 m_SSBOsOffset = static_cast<Uint16>(m_ImagesOffset + sizeof(CachedResourceView) * ImageCount);
51 m_MemoryEndOffset = static_cast<Uint16>(m_SSBOsOffset + sizeof(CachedSSBO) * SSBOCount);
55 m_TexturesOffset = static_cast<Uint16>(m_UBsOffset + sizeof(CachedUB) * ResCount[BINDING_RANGE_UNIFORM_BUFFER]);
56 m_ImagesOffset = static_cast<Uint16>(m_TexturesOffset + sizeof(CachedResourceView) * ResCount[BINDING_RANGE_TEXTURE]);
57 m_SSBOsOffset = static_cast<Uint16>(m_ImagesOffset + sizeof(CachedResourceView) * ResCount[BINDING_RANGE_IMAGE]);
58 m_MemoryEndOffset = static_cast<Uint16>(m_SSBOsOffset + sizeof(CachedSSBO) * ResCount[BINDING_RANGE_STORAGE_BUFFER]);
5259
53 VERIFY_EXPR(GetUBCount() == static_cast<Uint32>(UBCount));
54 VERIFY_EXPR(GetTextureCount() == static_cast<Uint32>(TextureCount));
55 VERIFY_EXPR(GetImageCount() == static_cast<Uint32>(ImageCount));
56 VERIFY_EXPR(GetSSBOCount() == static_cast<Uint32>(SSBOCount));
60 VERIFY_EXPR(GetUBCount() == static_cast<Uint32>(ResCount[BINDING_RANGE_UNIFORM_BUFFER]));
61 VERIFY_EXPR(GetTextureCount() == static_cast<Uint32>(ResCount[BINDING_RANGE_TEXTURE]));
62 VERIFY_EXPR(GetImageCount() == static_cast<Uint32>(ResCount[BINDING_RANGE_IMAGE]));
63 VERIFY_EXPR(GetSSBOCount() == static_cast<Uint32>(ResCount[BINDING_RANGE_STORAGE_BUFFER]));
5764 // clang-format on
5865
5966 VERIFY_EXPR(m_pResourceData == nullptr);
6067 size_t BufferSize = m_MemoryEndOffset;
6168
62 VERIFY_EXPR(BufferSize == GetRequriedMemorySize(UBCount, TextureCount, ImageCount, SSBOCount));
69 VERIFY_EXPR(BufferSize == GetRequriedMemorySize(ResCount));
6370
64 #ifdef DILIGENT_DEBUG
65 m_pdbgMemoryAllocator = &MemAllocator;
66 #endif
6771 if (BufferSize > 0)
6872 {
6973 m_pResourceData = ALLOCATE(MemAllocator, "Shader resource cache data buffer", Uint8, BufferSize);
7175 }
7276
7377 // Explicitly construct all objects
74 for (Uint32 cb = 0; cb < UBCount; ++cb)
78 for (Uint32 cb = 0; cb < GetUBCount(); ++cb)
7579 new (&GetUB(cb)) CachedUB;
7680
77 for (Uint32 s = 0; s < TextureCount; ++s)
81 for (Uint32 s = 0; s < GetTextureCount(); ++s)
7882 new (&GetTexture(s)) CachedResourceView;
7983
80 for (Uint32 i = 0; i < ImageCount; ++i)
84 for (Uint32 i = 0; i < GetImageCount(); ++i)
8185 new (&GetImage(i)) CachedResourceView;
8286
83 for (Uint32 s = 0; s < SSBOCount; ++s)
87 for (Uint32 s = 0; s < GetSSBOCount(); ++s)
8488 new (&GetSSBO(s)) CachedSSBO;
8589 }
8690
8791 ShaderResourceCacheGL::~ShaderResourceCacheGL()
8892 {
89 VERIFY(!IsInitialized(), "Shader resource cache memory must be released with ShaderResourceCacheGL::Destroy()");
90 }
93 if (IsInitialized())
94 {
95 for (Uint32 cb = 0; cb < GetUBCount(); ++cb)
96 GetUB(cb).~CachedUB();
9197
92 void ShaderResourceCacheGL::Destroy(IMemoryAllocator& MemAllocator)
93 {
94 if (!IsInitialized())
95 return;
98 for (Uint32 s = 0; s < GetTextureCount(); ++s)
99 GetTexture(s).~CachedResourceView();
96100
97 VERIFY(m_pdbgMemoryAllocator == &MemAllocator, "The allocator does not match the one used to create resources");
101 for (Uint32 i = 0; i < GetImageCount(); ++i)
102 GetImage(i).~CachedResourceView();
98103
99 for (Uint32 cb = 0; cb < GetUBCount(); ++cb)
100 GetUB(cb).~CachedUB();
104 for (Uint32 s = 0; s < GetSSBOCount(); ++s)
105 GetSSBO(s).~CachedSSBO();
101106
102 for (Uint32 s = 0; s < GetTextureCount(); ++s)
103 GetTexture(s).~CachedResourceView();
107 if (m_pResourceData != nullptr)
108 m_pAllocator->Free(m_pResourceData);
104109
105 for (Uint32 i = 0; i < GetImageCount(); ++i)
106 GetImage(i).~CachedResourceView();
107
108 for (Uint32 s = 0; s < GetSSBOCount(); ++s)
109 GetSSBO(s).~CachedSSBO();
110
111 if (m_pResourceData != nullptr)
112 MemAllocator.Free(m_pResourceData);
113
114 m_pResourceData = nullptr;
115 m_TexturesOffset = InvalidResourceOffset;
116 m_ImagesOffset = InvalidResourceOffset;
117 m_SSBOsOffset = InvalidResourceOffset;
118 m_MemoryEndOffset = InvalidResourceOffset;
110 m_pResourceData = nullptr;
111 m_TexturesOffset = InvalidResourceOffset;
112 m_ImagesOffset = InvalidResourceOffset;
113 m_SSBOsOffset = InvalidResourceOffset;
114 m_MemoryEndOffset = InvalidResourceOffset;
115 }
119116 }
120117
121118 } // namespace Diligent
4343 {
4444 ProcessSignatureResources(
4545 Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
46 [&](Uint32 Index) {
46 [&](Uint32 Index) //
47 {
4748 const auto& ResDesc = Signature.GetResourceDesc(Index);
4849 static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range");
4950 switch (PipelineResourceToBindingRange(ResDesc))
102103
103104 // clang-format off
104105 size_t RequiredSize = Counters.NumUBs * sizeof(UniformBuffBindInfo) +
105 Counters.NumTextures * sizeof(SamplerBindInfo) +
106 Counters.NumTextures * sizeof(TextureBindInfo) +
106107 Counters.NumImages * sizeof(ImageBindInfo) +
107108 Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo);
108109 // clang-format on
110111 }
111112
112113 void ShaderVariableManagerGL::Initialize(const PipelineResourceSignatureGLImpl& Signature,
114 IMemoryAllocator& Allocator,
113115 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
114116 Uint32 NumAllowedTypes,
115117 SHADER_TYPE ShaderType)
116118 {
119 #ifdef DILIGENT_DEBUG
120 m_pDbgAllocator = &Allocator;
121 #endif
122
117123 ResourceCounters Counters;
118124 CountResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, Counters);
119125
134140
135141 // clang-format off
136142 auto UBOffset = AdvanceOffset(Counters.NumUBs * sizeof(UniformBuffBindInfo) ); (void)UBOffset; // To suppress warning
137 m_TextureOffset = AdvanceOffset(Counters.NumTextures * sizeof(SamplerBindInfo) );
143 m_TextureOffset = AdvanceOffset(Counters.NumTextures * sizeof(TextureBindInfo) );
138144 m_ImageOffset = AdvanceOffset(Counters.NumImages * sizeof(ImageBindInfo) );
139145 m_StorageBufferOffset = AdvanceOffset(Counters.NumStorageBlocks * sizeof(StorageBufferBindInfo));
140146 m_VariableEndOffset = AdvanceOffset(0);
142148 auto TotalMemorySize = m_VariableEndOffset;
143149 VERIFY_EXPR(TotalMemorySize == GetRequiredMemorySize(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType));
144150
145 auto& ResLayoutDataAllocator = GetRawAllocator();
146151 if (TotalMemorySize)
147152 {
148 auto* pRawMem = ALLOCATE_RAW(ResLayoutDataAllocator, "Raw memory buffer for shader resource layout resources", TotalMemorySize);
149 m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void> >(pRawMem, ResLayoutDataAllocator);
153 m_ResourceBuffer = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", TotalMemorySize);
150154 }
151155
152156 // clang-format off
161165
162166 ProcessSignatureResources(
163167 Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
164 [&](Uint32 Index) {
168 [&](Uint32 Index) //
169 {
165170 const auto& ResDesc = Signature.GetResourceDesc(Index);
166171 static_assert(BINDING_RANGE_COUNT == 4, "Please update the switch below to handle the new shader resource range");
167172 switch (PipelineResourceToBindingRange(ResDesc))
170175 new (&GetResource<UniformBuffBindInfo>(VarCounters.NumUBs++)) UniformBuffBindInfo{*this, Index};
171176 break;
172177 case BINDING_RANGE_TEXTURE:
173 new (&GetResource<SamplerBindInfo>(VarCounters.NumTextures++)) SamplerBindInfo{*this, Index};
178 new (&GetResource<TextureBindInfo>(VarCounters.NumTextures++)) TextureBindInfo{*this, Index};
174179 break;
175180 case BINDING_RANGE_IMAGE:
176181 new (&GetResource<ImageBindInfo>(VarCounters.NumImages++)) ImageBindInfo{*this, Index};
185190
186191 // clang-format off
187192 VERIFY(VarCounters.NumUBs == GetNumUBs(), "Not all UBs are initialized which will cause a crash when dtor is called");
188 VERIFY(VarCounters.NumTextures == GetNumTextures(), "Not all Samplers 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");
189194 VERIFY(VarCounters.NumImages == GetNumImages(), "Not all Images are initialized which will cause a crash when dtor is called");
190195 VERIFY(VarCounters.NumStorageBlocks == GetNumStorageBuffers(), "Not all SSBOs are initialized which will cause a crash when dtor is called");
191196 // clang-format on
193198
194199 ShaderVariableManagerGL::~ShaderVariableManagerGL()
195200 {
196 // clang-format off
201 VERIFY(m_ResourceBuffer == nullptr, "DestroyVariables() has not been called");
202 }
203
204 void ShaderVariableManagerGL::DestroyVariables(IMemoryAllocator& Allocator)
205 {
206 if (m_ResourceBuffer == nullptr)
207 return;
208
209 VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor");
210
197211 HandleResources(
198 [&](UniformBuffBindInfo& ub)
199 {
212 [&](UniformBuffBindInfo& ub) {
200213 ub.~UniformBuffBindInfo();
201214 },
202
203 [&](SamplerBindInfo& sam)
204 {
205 sam.~SamplerBindInfo();
206 },
207
208 [&](ImageBindInfo& img)
209 {
215 [&](TextureBindInfo& tex) {
216 tex.~TextureBindInfo();
217 },
218 [&](ImageBindInfo& img) {
210219 img.~ImageBindInfo();
211220 },
212
213 [&](StorageBufferBindInfo& ssbo)
214 {
221 [&](StorageBufferBindInfo& ssbo) {
215222 ssbo.~StorageBufferBindInfo();
216 }
217 );
218 // clang-format on
223 });
224
225 m_ResourceBuffer = nullptr;
219226 }
220227
221228 void ShaderVariableManagerGL::UniformBuffBindInfo::BindResource(IDeviceObject* pBuffer,
244251
245252
246253
247 void ShaderVariableManagerGL::SamplerBindInfo::BindResource(IDeviceObject* pView,
248 Uint32 ArrayIndex)
254 void ShaderVariableManagerGL::TextureBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
249255 {
250256 const auto& Desc = GetDesc();
251257 const auto& Attr = GetAttribs();
253259 DEV_CHECK_ERR(ArrayIndex < Desc.ArraySize, "Array index (", ArrayIndex, ") is out of range for variable '", Desc.Name, "'. Max allowed index: ", Desc.ArraySize - 1);
254260 auto& ResourceCache = m_ParentManager.m_ResourceCache;
255261
256 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV ||
257 Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV);
258
259 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV)
262 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV ||
263 Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT)
260264 {
261265 // We cannot use ValidatedCast<> here as the resource retrieved from the
262266 // resource mapping can be of wrong type
269273 RESOURCE_DIM_UNDEFINED, false, CachedTexSampler.pView.RawPtr());
270274 if (Attr.IsImmutableSamplerAssigned() && ResourceCache.StaticResourcesInitialized())
271275 {
272 VERIFY(CachedTexSampler.pSampler != nullptr, "Immutable samplers must be initialized by PipelineStateGLImpl::InitializeSRBResourceCache!");
276 VERIFY(CachedTexSampler.pSampler != nullptr, "Immutable samplers must be initialized by PipelineResourceSignatureGLImpl::InitializeSRBResourceCache!");
277 }
278 if (Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT)
279 {
280 DEV_CHECK_ERR(!Attr.IsSamplerAssigned(), "Input attachment must not have assigned sampler.");
273281 }
274282 }
275283 #endif
308316 }
309317
310318
311 void ShaderVariableManagerGL::ImageBindInfo::BindResource(IDeviceObject* pView,
312 Uint32 ArrayIndex)
319 void ShaderVariableManagerGL::ImageBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
313320 {
314321 const auto& Desc = GetDesc();
315322 const auto& Attr = GetAttribs();
366373
367374
368375
369 void ShaderVariableManagerGL::StorageBufferBindInfo::BindResource(IDeviceObject* pView,
370 Uint32 ArrayIndex)
376 void ShaderVariableManagerGL::StorageBufferBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
371377 {
372378 const auto& Desc = GetDesc();
373379 const auto& Attr = GetAttribs();
403409 ResourceCache.SetSSBO(Attr.CacheOffset + ArrayIndex, std::move(pViewGL));
404410 }
405411
406
407
408 // Helper template class that facilitates binding CBs, SRVs, and UAVs
409 class BindResourceHelper
410 {
411 public:
412 BindResourceHelper(IResourceMapping& RM, Uint32 Fl) :
413 // clang-format off
414 ResourceMapping {RM},
415 Flags {Fl}
416 // clang-format on
417 {
418 }
419
420 template <typename ResourceType>
421 void Bind(ResourceType& Res)
422 {
423 if ((Flags & (1 << Res.GetType())) == 0)
424 return;
425
426 const auto& ResDesc = Res.GetDesc();
427
428 for (Uint16 elem = 0; elem < ResDesc.ArraySize; ++elem)
429 {
430 if ((Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(elem))
431 continue;
432
433 const auto* VarName = ResDesc.Name;
434 RefCntAutoPtr<IDeviceObject> pRes;
435 ResourceMapping.GetResource(VarName, &pRes, elem);
436 if (pRes)
437 {
438 // Call non-virtual function
439 Res.BindResource(pRes, elem);
440 }
441 else
442 {
443 if ((Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(elem))
444 LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", VarName, "': resource is not found in the resource mapping");
445 }
446 }
447 }
448
449 private:
450 IResourceMapping& ResourceMapping;
451 const Uint32 Flags;
452 };
453
454
455412 void ShaderVariableManagerGL::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags)
456413 {
457414 if (pResourceMapping == nullptr)
463420 if ((Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0)
464421 Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL;
465422
466 BindResourceHelper BindResHelper(*pResourceMapping, Flags);
467
468 // clang-format off
469423 HandleResources(
470 [&](UniformBuffBindInfo& ub)
471 {
472 BindResHelper.Bind(ub);
473 },
474
475 [&](SamplerBindInfo& sam)
476 {
477 BindResHelper.Bind(sam);
478 },
479
480 [&](ImageBindInfo& img)
481 {
482 BindResHelper.Bind(img);
483 },
484
485 [&](StorageBufferBindInfo& ssbo)
486 {
487 BindResHelper.Bind(ssbo);
488 }
489 );
490 // clang-format on
424 [&](UniformBuffBindInfo& ub) {
425 ub.BindResources<UniformBuffBindInfo>(pResourceMapping, Flags);
426 },
427 [&](TextureBindInfo& tex) {
428 tex.BindResources<TextureBindInfo>(pResourceMapping, Flags);
429 },
430 [&](ImageBindInfo& img) {
431 img.BindResources<ImageBindInfo>(pResourceMapping, Flags);
432 },
433 [&](StorageBufferBindInfo& ssbo) {
434 ssbo.BindResources<StorageBufferBindInfo>(pResourceMapping, Flags);
435 });
491436 }
492437
493438
512457 if (auto* pUB = GetResourceByName<UniformBuffBindInfo>(Name))
513458 return pUB;
514459
515 if (auto* pSampler = GetResourceByName<SamplerBindInfo>(Name))
516 return pSampler;
460 if (auto* pTexture = GetResourceByName<TextureBindInfo>(Name))
461 return pTexture;
517462
518463 if (auto* pImage = GetResourceByName<ImageBindInfo>(Name))
519464 return pImage;
566511 if (auto* pUB = VarLocator.TryResource<UniformBuffBindInfo>(GetNumUBs()))
567512 return pUB;
568513
569 if (auto* pSampler = VarLocator.TryResource<SamplerBindInfo>(GetNumTextures()))
570 return pSampler;
514 if (auto* pTexture = VarLocator.TryResource<TextureBindInfo>(GetNumTextures()))
515 return pTexture;
571516
572517 if (auto* pImage = VarLocator.TryResource<ImageBindInfo>(GetNumImages()))
573518 return pImage;
587532 ShaderVariableIndexLocator(const ShaderVariableManagerGL& _Layout, const ShaderVariableManagerGL::GLVariableBase& Variable) :
588533 // clang-format off
589534 Layout {_Layout},
590 VarOffset(reinterpret_cast<const Uint8*>(&Variable) - reinterpret_cast<const Uint8*>(_Layout.m_ResourceBuffer.get()))
535 VarOffset(reinterpret_cast<const Uint8*>(&Variable) - reinterpret_cast<const Uint8*>(_Layout.m_ResourceBuffer))
591536 // clang-format on
592537 {}
593538
634579 if (IdxLocator.TryResource<UniformBuffBindInfo>(m_TextureOffset, GetNumUBs()))
635580 return IdxLocator.GetIndex();
636581
637 if (IdxLocator.TryResource<SamplerBindInfo>(m_ImageOffset, GetNumTextures()))
582 if (IdxLocator.TryResource<TextureBindInfo>(m_ImageOffset, GetNumTextures()))
638583 return IdxLocator.GetIndex();
639584
640585 if (IdxLocator.TryResource<ImageBindInfo>(m_StorageBufferOffset, GetNumImages()))
656601 HandleConstResources(
657602 [&](const UniformBuffBindInfo& ub) //
658603 {
659 const auto& Desc = GetResourceDesc(ub.m_ResIndex);
660 const auto& Attr = GetAttribs(ub.m_ResIndex);
604 const auto& Desc = ub.GetDesc();
605 const auto& Attr = ub.GetAttribs();
606 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER);
661607 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
662608 {
663609 if (!ResourceCache.IsUBBound(Attr.CacheOffset + ArrInd))
668614 }
669615 },
670616
671 [&](const SamplerBindInfo& sam) //
672 {
673 const auto& Desc = GetResourceDesc(sam.m_ResIndex);
674 const auto& Attr = GetAttribs(sam.m_ResIndex);
617 [&](const TextureBindInfo& tex) //
618 {
619 const auto& Desc = tex.GetDesc();
620 const auto& Attr = tex.GetAttribs();
621 const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
622 VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
675623 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
676624 {
677 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV ||
678 Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
679 if (!ResourceCache.IsTextureBound(Attr.CacheOffset + ArrInd, Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV))
625 if (!ResourceCache.IsTextureBound(Attr.CacheOffset + ArrInd, IsTexView))
680626 {
681 LOG_MISSING_BINDING("texture", sam, ArrInd);
627 LOG_MISSING_BINDING("texture", tex, ArrInd);
682628 BindingsOK = false;
683629 }
684630 else
685631 {
686 const auto& CachedSampler = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrInd);
687 if (Attr.IsImmutableSamplerAssigned() && CachedSampler.pSampler == nullptr)
632 const auto& CachedTex = ResourceCache.GetConstTexture(Attr.CacheOffset + ArrInd);
633 if (Attr.IsImmutableSamplerAssigned() && CachedTex.pSampler == nullptr)
688634 {
689635 LOG_ERROR_MESSAGE("Immutable sampler is not initialized for texture '", Desc.Name, "'");
690636 BindingsOK = false;
695641
696642 [&](const ImageBindInfo& img) //
697643 {
698 const auto& Desc = GetResourceDesc(img.m_ResIndex);
699 const auto& Attr = GetAttribs(img.m_ResIndex);
644 const auto& Desc = img.GetDesc();
645 const auto& Attr = img.GetAttribs();
646 const bool IsTexView = (Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
647 VERIFY_EXPR(IsTexView || Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV);
700648 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
701649 {
702 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV ||
703 Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV);
704 if (!ResourceCache.IsImageBound(Attr.CacheOffset + ArrInd, Desc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV))
650 if (!ResourceCache.IsImageBound(Attr.CacheOffset + ArrInd, IsTexView))
705651 {
706652 LOG_MISSING_BINDING("texture UAV", img, ArrInd);
707653 BindingsOK = false;
711657
712658 [&](const StorageBufferBindInfo& ssbo) //
713659 {
714 const auto& Desc = GetResourceDesc(ssbo.m_ResIndex);
715 const auto& Attr = GetAttribs(ssbo.m_ResIndex);
660 const auto& Desc = ssbo.GetDesc();
661 const auto& Attr = ssbo.GetAttribs();
662 VERIFY_EXPR(Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV ||
663 Desc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV);
716664 for (Uint32 ArrInd = 0; ArrInd < Desc.ArraySize; ++ArrInd)
717665 {
718666 if (!ResourceCache.IsSSBOBound(Attr.CacheOffset + ArrInd))
105105
106106 std::vector<const ShaderVkImpl*> Shaders;
107107 std::vector<std::vector<uint32_t>> SPIRVs;
108
109 friend SHADER_TYPE GetShaderStageType(const ShaderStageInfo& Stage) { return Stage.Type; }
108110 };
109111 using TShaderStages = std::vector<ShaderStageInfo>;
110112
237237 {SHADER_TYPE_PIXEL, "g_InputAttachment", 1, SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY}};
238238 PRSDesc.Resources = Resources;
239239 PRSDesc.NumResources = _countof(Resources);
240 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (RUNTIME_ARRAY). Only the following flags are valid for a input attachment: UNKNOWN");
240 const char* ExpectedErrorSubstring;
241 if (TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().Features.ShaderResourceRuntimeArray)
242 ExpectedErrorSubstring = "Incorrect Desc.Resources[1].Flags (RUNTIME_ARRAY). Only the following flags are valid for a input attachment: UNKNOWN";
243 else
244 ExpectedErrorSubstring = "Incorrect Desc.Resources[1].Flags (RUNTIME_ARRAY) can only be used if ShaderResourceRuntimeArray device feature is enabled";
245
246 TestCreatePRSFailure(PRSDesc, ExpectedErrorSubstring);
241247 }
242248
243249 TEST(PRSCreationFailureTest, InvalidAccelStructFlag)
249255 {SHADER_TYPE_PIXEL, "g_AS", 1, SHADER_RESOURCE_TYPE_ACCEL_STRUCT, SHADER_RESOURCE_VARIABLE_TYPE_STATIC, PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS}};
250256 PRSDesc.Resources = Resources;
251257 PRSDesc.NumResources = _countof(Resources);
252 TestCreatePRSFailure(PRSDesc, "Incorrect Desc.Resources[1].Flags (NO_DYNAMIC_BUFFERS). Only the following flags are valid for a acceleration structure: RUNTIME_ARRAY");
258 const char* ExpectedErrorSubstring;
259 if (TestingEnvironment::GetInstance()->GetDevice()->GetDeviceCaps().Features.RayTracing)
260 ExpectedErrorSubstring = "Incorrect Desc.Resources[1].Flags (NO_DYNAMIC_BUFFERS). Only the following flags are valid for a acceleration structure: RUNTIME_ARRAY";
261 else
262 ExpectedErrorSubstring = "Incorrect Desc.Resources[1].ResourceType (ACCEL_STRUCT): acceleration structure is not supported by device";
263
264 TestCreatePRSFailure(PRSDesc, ExpectedErrorSubstring);
253265 }
254266
255267 TEST(PRSCreationFailureTest, InvalidAssignedSamplerResourceType)