From d81817038a73aac29846928ebd1fcd8d8ace0f60 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 1 Dec 2020 18:13:42 -0800 Subject: Refcactored GLTFResourceManager: made allocations ref-counted objects --- AssetLoader/src/GLTFResourceManager.cpp | 185 +++++++++++++++++++------------- 1 file changed, 113 insertions(+), 72 deletions(-) (limited to 'AssetLoader/src/GLTFResourceManager.cpp') diff --git a/AssetLoader/src/GLTFResourceManager.cpp b/AssetLoader/src/GLTFResourceManager.cpp index c6f627c..05dfa28 100644 --- a/AssetLoader/src/GLTFResourceManager.cpp +++ b/AssetLoader/src/GLTFResourceManager.cpp @@ -32,112 +32,153 @@ namespace Diligent { -GLTFResourceManager::BufferCache::BufferCache(IRenderDevice* pDevice, const BufferDesc& BuffDesc) : - Mgr{BuffDesc.uiSizeInBytes, DefaultRawMemoryAllocator::GetAllocator()} +GLTFResourceManager::BufferCache::BufferCache(GLTFResourceManager& Owner, + IRenderDevice* pDevice, + const BufferDesc& BuffDesc) : + m_Owner{Owner}, + m_Mgr{BuffDesc.uiSizeInBytes, DefaultRawMemoryAllocator::GetAllocator()} { - pDevice->CreateBuffer(BuffDesc, nullptr, &pBuffer); + pDevice->CreateBuffer(BuffDesc, nullptr, &m_pBuffer); } -GLTFResourceManager::TextureCache::TextureCache(IRenderDevice* pDevice, const TextureCacheAttribs& CacheCI) : - Mgr{CacheCI.Desc.Width / CacheCI.Granularity, CacheCI.Desc.Height / CacheCI.Granularity}, - Granularity{CacheCI.Granularity} +IBuffer* GLTFResourceManager::BufferCache::GetBuffer(IRenderDevice* pDevice, IDeviceContext* pContext) { - DEV_CHECK_ERR(IsPowerOfTwo(CacheCI.Granularity), "Granularity (", CacheCI.Granularity, ") must be a power of two"); - DEV_CHECK_ERR((CacheCI.Desc.Width % CacheCI.Granularity) == 0, "Atlas width (", CacheCI.Desc.Width, ") is not multiple of granularity (", CacheCI.Granularity, ")"); - DEV_CHECK_ERR((CacheCI.Desc.Height % CacheCI.Granularity) == 0, "Atlas height (", CacheCI.Desc.Height, ") is not multiple of granularity (", CacheCI.Granularity, ")"); + std::lock_guard Lock{m_Mtx}; - pDevice->CreateTexture(CacheCI.Desc, nullptr, &pTexture); -} + const auto& BuffDesc = m_pBuffer->GetDesc(); + const auto MgrSize = m_Mgr.GetMaxSize(); + if (BuffDesc.uiSizeInBytes < MgrSize) + { + // Extend the buffer + auto NewBuffDesc = BuffDesc; -RefCntAutoPtr GLTFResourceManager::Create(IRenderDevice* pDevice, - const CreateInfo& CI) -{ - return RefCntAutoPtr{MakeNewRCObj()(pDevice, CI)}; -} + NewBuffDesc.uiSizeInBytes = static_cast(MgrSize); -GLTFResourceManager::GLTFResourceManager(IReferenceCounters* pRefCounters, - IRenderDevice* pDevice, - const CreateInfo& CI) : - TBase{pRefCounters} -{ - m_Buffers.reserve(CI.NumBuffers); - for (Uint32 i = 0; i < CI.NumBuffers; ++i) - { - m_Buffers.emplace_back(pDevice, CI.Buffers[i]); - } + RefCntAutoPtr pNewBuffer; + pDevice->CreateBuffer(NewBuffDesc, nullptr, &pNewBuffer); + pContext->CopyBuffer(m_pBuffer, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, + pNewBuffer, 0, BuffDesc.uiSizeInBytes, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - m_Textures.reserve(CI.NumTextures); - for (Uint32 i = 0; i < CI.NumTextures; ++i) - { - m_Textures.emplace_back(pDevice, CI.Textures[i]); + m_pBuffer = std::move(pNewBuffer); } + + return m_pBuffer.RawPtr(); } -GLTFResourceManager::BufferAllocation GLTFResourceManager::AllocateBufferSpace(Uint32 BufferIndex, Uint32 Size, Uint32 Alignment) +RefCntAutoPtr GLTFResourceManager::BufferCache::Allocate(Uint32 Size, Uint32 Alignment) { - auto& BuffCache = m_Buffers[BufferIndex]; + std::lock_guard Lock{m_Mtx}; - std::lock_guard Lock{BuffCache.Mtx}; + auto Region = m_Mgr.Allocate(Size, Alignment); + while (!Region.IsValid()) + { + m_Mgr.Extend(m_Mgr.GetMaxSize()); + Region = m_Mgr.Allocate(Size, Alignment); + } - BufferAllocation Allocation; - Allocation.Region = BuffCache.Mgr.Allocate(Size, Alignment); - if (Allocation.Region.IsValid()) - Allocation.BufferIndex = BufferIndex; - return Allocation; + return RefCntAutoPtr{ + MakeNewRCObj()( + RefCntAutoPtr{&m_Owner}, + *this, + std::move(Region) // + ) // + }; } -void GLTFResourceManager::FreeBufferSpace(BufferAllocation&& Allocation) +GLTFResourceManager::TextureCache::TextureCache(GLTFResourceManager& Owner, + IRenderDevice* pDevice, + const TextureCacheAttribs& CacheCI) : + m_Owner{Owner}, + m_TexDesc{CacheCI.Desc}, + m_Mgr{CacheCI.Desc.Width / CacheCI.Granularity, CacheCI.Desc.Height / CacheCI.Granularity}, + m_Granularity{CacheCI.Granularity} { - VERIFY_EXPR(Allocation.IsValid()); + m_TexDesc.Name = m_TexName.c_str(); - auto& BuffCache = m_Buffers[Allocation.BufferIndex]; + DEV_CHECK_ERR(IsPowerOfTwo(CacheCI.Granularity), "Granularity (", CacheCI.Granularity, ") must be a power of two"); + DEV_CHECK_ERR((CacheCI.Desc.Width % CacheCI.Granularity) == 0, "Atlas width (", CacheCI.Desc.Width, ") is not multiple of granularity (", CacheCI.Granularity, ")"); + DEV_CHECK_ERR((CacheCI.Desc.Height % CacheCI.Granularity) == 0, "Atlas height (", CacheCI.Desc.Height, ") is not multiple of granularity (", CacheCI.Granularity, ")"); - std::lock_guard Lock{BuffCache.Mtx}; - BuffCache.Mgr.Free(std::move(Allocation.Region)); + pDevice->CreateTexture(CacheCI.Desc, nullptr, &m_pTexture); } -GLTFResourceManager::TextureAllocation GLTFResourceManager::AllocateTextureSpace(Uint32 TextureIndex, Uint32 Width, Uint32 Height) + +ITexture* GLTFResourceManager::TextureCache::GetTexture(IRenderDevice* pDevice, IDeviceContext* pContext) { - auto& TexCache = m_Textures[TextureIndex]; + // TODO: handle resizes + return m_pTexture; +} - Width = (Width + TexCache.Granularity - 1) / TexCache.Granularity; - Height = (Height + TexCache.Granularity - 1) / TexCache.Granularity; +RefCntAutoPtr GLTFResourceManager::TextureCache::Allocate(Uint32 Width, Uint32 Height) +{ + Width = (Width + m_Granularity - 1) / m_Granularity; + Height = (Height + m_Granularity - 1) / m_Granularity; - std::lock_guard Lock{TexCache.Mtx}; + std::lock_guard Lock{m_Mtx}; - TextureAllocation Allocation; - Allocation.Region = TexCache.Mgr.Allocate(Width, Height); - if (!Allocation.Region.IsEmpty()) + auto Region = m_Mgr.Allocate(Width, Height); + if (!Region.IsEmpty()) { - Allocation.TextureIndex = TextureIndex; - - Allocation.Region.x *= TexCache.Granularity; - Allocation.Region.y *= TexCache.Granularity; - Allocation.Region.width *= TexCache.Granularity; - Allocation.Region.height *= TexCache.Granularity; + Region.x *= m_Granularity; + Region.y *= m_Granularity; + Region.width *= m_Granularity; + Region.height *= m_Granularity; + + return RefCntAutoPtr{ + MakeNewRCObj()( + RefCntAutoPtr{&m_Owner}, + *this, + std::move(Region) // + ) // + }; + } + else + { + // TODO: handle resize + return RefCntAutoPtr{}; } - return Allocation; } -void GLTFResourceManager::FreeTextureSpace(TextureAllocation&& Allocation) +void GLTFResourceManager::TextureCache::FreeAllocation(DynamicAtlasManager::Region&& Allocation) { - VERIFY_EXPR(Allocation.IsValid()); + VERIFY((Allocation.x % m_Granularity) == 0, "Allocation x (", Allocation.x, ") is not multiple of granularity (", m_Granularity, ")"); + VERIFY((Allocation.y % m_Granularity) == 0, "Allocation y (", Allocation.y, ") is not multiple of granularity (", m_Granularity, ")"); + VERIFY((Allocation.width % m_Granularity) == 0, "Allocation width (", Allocation.width, ") is not multiple of granularity (", m_Granularity, ")"); + VERIFY((Allocation.height % m_Granularity) == 0, "Allocation height (", Allocation.height, ") is not multiple of granularity (", m_Granularity, ")"); + + Allocation.x /= m_Granularity; + Allocation.y /= m_Granularity; + Allocation.width /= m_Granularity; + Allocation.height /= m_Granularity; + + std::lock_guard Lock{m_Mtx}; + m_Mgr.Free(std::move(Allocation)); +} - auto& TexCache = m_Textures[Allocation.TextureIndex]; - auto& Region = Allocation.Region; - DEV_CHECK_ERR((Region.x % TexCache.Granularity) == 0, "Allocation x (", Region.x, ") is not multiple of granularity (", TexCache.Granularity, ")"); - DEV_CHECK_ERR((Region.y % TexCache.Granularity) == 0, "Allocation y (", Region.y, ") is not multiple of granularity (", TexCache.Granularity, ")"); - DEV_CHECK_ERR((Region.width % TexCache.Granularity) == 0, "Allocation width (", Region.width, ") is not multiple of granularity (", TexCache.Granularity, ")"); - DEV_CHECK_ERR((Region.height % TexCache.Granularity) == 0, "Allocation height (", Region.height, ") is not multiple of granularity (", TexCache.Granularity, ")"); - Region.x /= TexCache.Granularity; - Region.y /= TexCache.Granularity; - Region.width /= TexCache.Granularity; - Region.height /= TexCache.Granularity; +RefCntAutoPtr GLTFResourceManager::Create(IRenderDevice* pDevice, + const CreateInfo& CI) +{ + return RefCntAutoPtr{MakeNewRCObj()(pDevice, CI)}; +} - std::lock_guard Lock{TexCache.Mtx}; - TexCache.Mgr.Free(std::move(Region)); +GLTFResourceManager::GLTFResourceManager(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + const CreateInfo& CI) : + TBase{pRefCounters} +{ + m_Buffers.reserve(CI.NumBuffers); + for (Uint32 i = 0; i < CI.NumBuffers; ++i) + { + m_Buffers.emplace_back(*this, pDevice, CI.Buffers[i]); + } + + m_Textures.reserve(CI.NumTextures); + for (Uint32 i = 0; i < CI.NumTextures; ++i) + { + m_Textures.emplace_back(*this, pDevice, CI.Textures[i]); + } } } // namespace Diligent -- cgit v1.2.3