diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-03-10 07:03:41 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:38:19 +0000 |
| commit | 4bb5004e4067a245b8bb199427310aaf656a422f (patch) | |
| tree | 018ff2549eb06ea1786a53c8c27ac22dd2e0865d /Graphics/GraphicsEngine | |
| parent | Updated PSOCompatibility.IsCompatibleWith: texture and texture array are now ... (diff) | |
| download | DiligentCore-4bb5004e4067a245b8bb199427310aaf656a422f.tar.gz DiligentCore-4bb5004e4067a245b8bb199427310aaf656a422f.zip | |
Fixed issue with destruction of ShaderResourceBindingBase
Diffstat (limited to 'Graphics/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp | 106 |
1 files changed, 60 insertions, 46 deletions
diff --git a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp index e6dddb0c..f3106afc 100644 --- a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp +++ b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp @@ -75,69 +75,67 @@ public: m_pPRS{pPRS}, m_ShaderResourceCache{ResourceCacheContentType::SRB} { - m_ActiveShaderStageIndex.fill(-1); - - const auto NumShaders = GetNumShaders(); - const auto PipelineType = GetPipelineType(); - for (Uint32 s = 0; s < NumShaders; ++s) + try { - const auto ShaderType = pPRS->GetActiveShaderStageType(s); - const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); + m_ActiveShaderStageIndex.fill(-1); - m_ActiveShaderStageIndex[ShaderInd] = static_cast<Int8>(s); - } + const auto NumShaders = GetNumShaders(); + const auto PipelineType = GetPipelineType(); + for (Uint32 s = 0; s < NumShaders; ++s) + { + const auto ShaderType = pPRS->GetActiveShaderStageType(s); + const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); + + m_ActiveShaderStageIndex[ShaderInd] = static_cast<Int8>(s); + } - FixedLinearAllocator MemPool{GetRawAllocator()}; - MemPool.AddSpace<ShaderVariableManagerImplType>(NumShaders); - MemPool.Reserve(); - static_assert(std::is_nothrow_constructible<ShaderVariableManagerImplType, decltype(*this), ShaderResourceCacheImplType&>::value, - "Constructor of ShaderVariableManagerImplType must be noexcept, so we can safely construct all managers"); - m_pShaderVarMgrs = MemPool.ConstructArray<ShaderVariableManagerImplType>(NumShaders, std::ref(*this), std::ref(m_ShaderResourceCache)); + FixedLinearAllocator MemPool{GetRawAllocator()}; + MemPool.AddSpace<ShaderVariableManagerImplType>(NumShaders); + MemPool.Reserve(); + static_assert(std::is_nothrow_constructible<ShaderVariableManagerImplType, decltype(*this), ShaderResourceCacheImplType&>::value, + "Constructor of ShaderVariableManagerImplType must be noexcept, so we can safely construct all managers"); + m_pShaderVarMgrs = MemPool.ConstructArray<ShaderVariableManagerImplType>(NumShaders, std::ref(*this), std::ref(m_ShaderResourceCache)); - // The memory is now owned by ShaderResourceBindingBase and will be freed by destructor. - auto* Ptr = MemPool.ReleaseOwnership(); - VERIFY_EXPR(Ptr == m_pShaderVarMgrs); - (void)Ptr; + // The memory is now owned by ShaderResourceBindingBase and will be freed by Destruct(). + auto* Ptr = MemPool.ReleaseOwnership(); + VERIFY_EXPR(Ptr == m_pShaderVarMgrs); + (void)Ptr; - // It is important to construct all objects before initializing them because if an exception is thrown, - // destructors will be called for all objects + // It is important to construct all objects before initializing them because if an exception is thrown, + // Destruct() will call destructors for all non-null objects. - pPRS->InitSRBResourceCache(m_ShaderResourceCache); + pPRS->InitSRBResourceCache(m_ShaderResourceCache); - auto& SRBMemAllocator = pPRS->GetSRBMemoryAllocator(); - for (Uint32 s = 0; s < NumShaders; ++s) - { - const auto ShaderType = pPRS->GetActiveShaderStageType(s); - const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPRS->GetPipelineType()); - const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd]; - VERIFY_EXPR(MgrInd >= 0 && MgrInd < static_cast<int>(NumShaders)); + auto& SRBMemAllocator = pPRS->GetSRBMemoryAllocator(); + for (Uint32 s = 0; s < NumShaders; ++s) + { + const auto ShaderType = pPRS->GetActiveShaderStageType(s); + const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPRS->GetPipelineType()); + const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd]; + VERIFY_EXPR(MgrInd >= 0 && MgrInd < static_cast<int>(NumShaders)); - auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s); + auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s); - // Initialize vars manager to reference mutable and dynamic variables - // Note that the cache has space for all variable types - const SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; - m_pShaderVarMgrs[MgrInd].Initialize(*pPRS, VarDataAllocator, VarTypes, _countof(VarTypes), ShaderType); + // Initialize vars manager to reference mutable and dynamic variables + // Note that the cache has space for all variable types + const SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + m_pShaderVarMgrs[MgrInd].Initialize(*pPRS, VarDataAllocator, VarTypes, _countof(VarTypes), ShaderType); + } + } + catch (...) + { + // We must release objects manually as destructor will not be called. + Destruct(); + throw; } } ~ShaderResourceBindingBase() { - if (m_pShaderVarMgrs != nullptr) - { - auto& SRBMemAllocator = GetSignature()->GetSRBMemoryAllocator(); - for (Uint32 s = 0; s < GetNumShaders(); ++s) - { - auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s); - m_pShaderVarMgrs[s].Destroy(VarDataAllocator); - m_pShaderVarMgrs[s].~ShaderVariableManagerImplType(); - } - GetRawAllocator().Free(m_pShaderVarMgrs); - } + Destruct(); } - IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderResourceBinding, TObjectBase) Uint32 GetBindingIndex() const @@ -261,6 +259,22 @@ public: ShaderResourceCacheImplType& GetResourceCache() { return m_ShaderResourceCache; } const ShaderResourceCacheImplType& GetResourceCache() const { return m_ShaderResourceCache; } +private: + void Destruct() + { + if (m_pShaderVarMgrs != nullptr) + { + auto& SRBMemAllocator = GetSignature()->GetSRBMemoryAllocator(); + for (Uint32 s = 0; s < GetNumShaders(); ++s) + { + auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s); + m_pShaderVarMgrs[s].Destroy(VarDataAllocator); + m_pShaderVarMgrs[s].~ShaderVariableManagerImplType(); + } + GetRawAllocator().Free(m_pShaderVarMgrs); + } + } + protected: /// Strong reference to pipeline resource signature. We must use strong reference, because /// shader resource binding uses pipeline resource signature's memory allocator to allocate |
