4545#include " GLTFBuilder.hpp"
4646#include " GLTF_PBR_Renderer.hpp"
4747#include " DataBlobImpl.hpp"
48+ #include " VariableSizeAllocationsManager.hpp"
49+ #include " DefaultRawMemoryAllocator.hpp"
4850
4951#include " pxr/imaging/hd/sceneDelegate.h"
5052
@@ -101,10 +103,6 @@ HnMaterial::HnMaterial(HnRenderDelegate& RenderDelegate) :
101103 AllocateTextures ({}, RenderDelegate);
102104}
103105
104- HnMaterial::~HnMaterial ()
105- {
106- }
107-
108106void HnMaterial::Sync (pxr::HdSceneDelegate* SceneDelegate,
109107 pxr::HdRenderParam* RenderParam,
110108 pxr::HdDirtyBits* DirtyBits)
@@ -617,6 +615,13 @@ class HnMaterialSRBCache : public ObjectBase<IObject>
617615 HnMaterialSRBCache (IReferenceCounters* pRefCounters) :
618616 ObjectBase<IObject>{pRefCounters},
619617 m_Cache{/* NumRequestsToPurge = */ 128 },
618+ m_BufferRegionMgr{
619+ VariableSizeAllocationsManager::CreateInfo{
620+ DefaultRawMemoryAllocator::GetAllocator (),
621+ 2048 ,
622+ true , // DisableDebugValidation,
623+ },
624+ },
620625 m_MaterialAttribsBuffer{
621626 nullptr ,
622627 DynamicBufferCreateInfo{
@@ -630,6 +635,11 @@ class HnMaterialSRBCache : public ObjectBase<IObject>
630635 }
631636 {}
632637
638+ ~HnMaterialSRBCache ()
639+ {
640+ VERIFY (m_BufferRegionMgr.GetUsedSize () == 0 , " Not all buffer regions have been released" );
641+ }
642+
633643 static RefCntAutoPtr<IObject> Create ()
634644 {
635645 return RefCntAutoPtr<IObject>{MakeNewRCObj<HnMaterialSRBCache>()()};
@@ -703,17 +713,41 @@ class HnMaterialSRBCache : public ObjectBase<IObject>
703713 return it->second ;
704714 }
705715
706- Uint32 AllocateBufferOffset (Uint32 Size)
716+ void AllocateBufferOffset (Uint32& Offset, Uint32& Size, Uint32 RequiredSize )
707717 {
708- std::lock_guard<std::mutex> Lock{m_CurrBufferOffsetMtx };
718+ std::lock_guard<std::mutex> Lock{m_BufferRegionMgrMtx };
709719
710720 VERIFY (m_ConstantBufferOffsetAlignment != 0 && m_MaxAttribsDataSize != 0 , " The cache is not initialized" );
721+ // Release the previously allocated region
722+ if (Offset != ~0u )
723+ {
724+ VERIFY_EXPR (Size != 0 );
725+ VERIFY_EXPR (AlignUp (Offset, m_ConstantBufferOffsetAlignment) == Offset);
726+ m_BufferRegionMgr.Free (Offset, AlignUp (Size, m_ConstantBufferOffsetAlignment));
727+ }
728+
729+ Size = RequiredSize;
730+ if (RequiredSize != 0 )
731+ {
732+ RequiredSize = AlignUp (RequiredSize, m_ConstantBufferOffsetAlignment);
733+
734+ VariableSizeAllocationsManager::Allocation Allocation = m_BufferRegionMgr.Allocate (RequiredSize, 1 );
735+ if (!Allocation.IsValid ())
736+ {
737+ VERIFY_EXPR (RequiredSize <= m_BufferRegionMgr.GetMaxSize ());
738+ m_BufferRegionMgr.Extend (m_BufferRegionMgr.GetMaxSize ());
739+ Allocation = m_BufferRegionMgr.Allocate (RequiredSize, 1 );
740+ VERIFY_EXPR (Allocation.IsValid ());
741+ }
711742
712- const Uint32 Offset = AlignUp (m_CurrBufferOffset, m_ConstantBufferOffsetAlignment);
713- m_CurrBufferOffset = Offset + Size;
714- // Reserve enough space for the maximum possible attribs data size.
715- m_RequiredBufferSize = AlignUp (Offset + m_MaxAttribsDataSize, m_ConstantBufferOffsetAlignment);
716- return Offset;
743+ Offset = Allocation.UnalignedOffset ;
744+ // Reserve enough space for the maximum possible attribs data size.
745+ m_RequiredBufferSize = std::max (m_RequiredBufferSize, AlignUp (Offset + m_MaxAttribsDataSize, m_ConstantBufferOffsetAlignment));
746+ }
747+ else
748+ {
749+ Offset = ~0u ;
750+ }
717751 }
718752
719753 IBuffer* PrepareMaterialAttribsBuffer (IRenderDevice* pDevice, IDeviceContext* pContext)
@@ -731,7 +765,7 @@ class HnMaterialSRBCache : public ObjectBase<IObject>
731765
732766 IBuffer* GetMaterialAttribsBuffer () const
733767 {
734- VERIFY_EXPR (m_RequiredBufferSize == m_MaterialAttribsBuffer.GetDesc ().Size , " The buffer needs to be resized." );
768+ VERIFY (m_RequiredBufferSize == m_MaterialAttribsBuffer.GetDesc ().Size , " The buffer needs to be resized." );
735769 return m_MaterialAttribsBuffer.GetBuffer ();
736770 }
737771
@@ -751,7 +785,7 @@ class HnMaterialSRBCache : public ObjectBase<IObject>
751785
752786 IBuffer* CommitUpdates (IRenderDevice* pDevice, IDeviceContext* pContext)
753787 {
754- VERIFY_EXPR (m_RequiredBufferSize == m_MaterialAttribsBuffer.GetDesc ().Size , " The buffer needs to be resized." );
788+ VERIFY (m_RequiredBufferSize == m_MaterialAttribsBuffer.GetDesc ().Size , " The buffer needs to be resized." );
755789 IBuffer* pBuffer = m_MaterialAttribsBuffer.GetBuffer ();
756790 if (m_DirtyRangeStart < m_DirtyRangeEnd)
757791 {
@@ -800,9 +834,9 @@ class HnMaterialSRBCache : public ObjectBase<IObject>
800834 Uint32 m_ConstantBufferOffsetAlignment = 0 ;
801835 Uint32 m_MaxAttribsDataSize = 0 ;
802836
803- std::mutex m_CurrBufferOffsetMtx ;
804- Uint32 m_CurrBufferOffset = 0 ;
805- Uint32 m_RequiredBufferSize = 0 ;
837+ std::mutex m_BufferRegionMgrMtx ;
838+ VariableSizeAllocationsManager m_BufferRegionMgr ;
839+ Uint32 m_RequiredBufferSize = 0 ;
806840
807841 // Material attribs data resides in a single buffer shared by all SRBs.
808842 DynamicBuffer m_MaterialAttribsBuffer;
@@ -815,18 +849,20 @@ void HnMaterial::AllocateBufferSpace(HnRenderDelegate& RenderDelegate)
815849{
816850 const USD_Renderer& UsdRenderer = *RenderDelegate.GetUSDRenderer ();
817851
818- m_PSOFlags = HnRenderPass::GetMaterialPSOFlags (*this );
819- Uint32 LastPBRMaterialAttribsSize = m_PBRMaterialAttribsSize;
820- m_PBRMaterialAttribsSize = UsdRenderer.GetPBRMaterialAttribsSize (m_PSOFlags);
821-
822- // Note that in case material attribs size increases, previously allocated space will not be reused.
823- // This, however, is unlikely to happen in practice.
824- if (m_PBRMaterialAttribsBufferOffset == ~0u || m_PBRMaterialAttribsSize > LastPBRMaterialAttribsSize)
852+ m_PSOFlags = HnRenderPass::GetMaterialPSOFlags (*this );
853+ Uint32 AttribsSize = UsdRenderer.GetPBRMaterialAttribsSize (m_PSOFlags);
854+ if (m_PBRMaterialAttribsBufferOffset == ~0u || AttribsSize > m_PBRMaterialAttribsSize)
825855 {
826- RefCntAutoPtr<HnMaterialSRBCache> SRBCache{RenderDelegate.GetMaterialSRBCache (), IID_HnMaterialSRBCache};
827- VERIFY_EXPR (SRBCache);
828-
829- m_PBRMaterialAttribsBufferOffset = SRBCache->AllocateBufferOffset (m_PBRMaterialAttribsSize);
856+ if (!m_SRBCache)
857+ {
858+ m_SRBCache = RefCntAutoPtr<HnMaterialSRBCache>{RenderDelegate.GetMaterialSRBCache (), IID_HnMaterialSRBCache};
859+ VERIFY_EXPR (m_SRBCache);
860+ }
861+ else
862+ {
863+ VERIFY_EXPR (m_SRBCache == RenderDelegate.GetMaterialSRBCache ());
864+ }
865+ m_SRBCache->AllocateBufferOffset (m_PBRMaterialAttribsBufferOffset, m_PBRMaterialAttribsSize, AttribsSize);
830866 }
831867}
832868
@@ -1325,6 +1361,11 @@ void HnMaterial::EndResourceUpdate(HnRenderDelegate& RenderDelegate)
13251361 }
13261362}
13271363
1364+ HnMaterial::~HnMaterial ()
1365+ {
1366+ m_SRBCache->AllocateBufferOffset (m_PBRMaterialAttribsBufferOffset, m_PBRMaterialAttribsSize, 0 );
1367+ }
1368+
13281369} // namespace USD
13291370
13301371} // namespace Diligent
0 commit comments