From 60ce41d5b736dbb7c5799897bdadfc2a34d6c16a Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 8 Dec 2020 18:48:28 -0800 Subject: Reworked GLTF resource manager to use BufferSuballocator and DynamicTextureAtlas --- AssetLoader/interface/GLTFLoader.hpp | 65 ++---- AssetLoader/interface/GLTFResourceManager.hpp | 296 +++++--------------------- 2 files changed, 70 insertions(+), 291 deletions(-) (limited to 'AssetLoader/interface') diff --git a/AssetLoader/interface/GLTFLoader.hpp b/AssetLoader/interface/GLTFLoader.hpp index 68747c5..cbfd3b0 100644 --- a/AssetLoader/interface/GLTFLoader.hpp +++ b/AssetLoader/interface/GLTFLoader.hpp @@ -56,7 +56,7 @@ namespace GLTF struct GLTFCacheInfo { - GLTFResourceManager* pResourceMgr = nullptr; + ResourceManager* pResourceMgr = nullptr; Uint8 IndexBufferIdx = 0; Uint8 VertexBuffer0Idx = 0; @@ -346,59 +346,36 @@ struct Model void PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx); - IBuffer* GetBuffer(BUFFER_ID BuffId, IRenderDevice* pDevice, IDeviceContext* pCtx) + IBuffer* GetBuffer(BUFFER_ID BuffId) { - VERIFY_EXPR(BuffId < BUFFER_ID_NUM_BUFFERS); - auto& Buff = Buffers[BuffId]; - if (Buff.pBuffer) - return Buff.pBuffer; - else if (Buff.pCacheAllocation) - return Buff.pCacheAllocation->GetBuffer(pDevice, pCtx); - else - return nullptr; + return Buffers[BuffId].pBuffer; + } + + ITexture* GetTexture(Uint32 Index) + { + return Textures[Index].pTexture; } Uint32 GetFirstIndexLocation() const { auto& IndBuff = Buffers[BUFFER_ID_INDEX]; - VERIFY(!IndBuff.pCacheAllocation || IndBuff.pCacheAllocation->GetRegion().UnalignedOffset % sizeof(Uint32) == 0, + VERIFY(!IndBuff.pSuballocation || IndBuff.pSuballocation->GetOffset() % sizeof(Uint32) == 0, "Allocation offset is not multiple of sizeof(Uint32)"); - return IndBuff.pCacheAllocation ? - static_cast(IndBuff.pCacheAllocation->GetRegion().UnalignedOffset / sizeof(Uint32)) : + return IndBuff.pSuballocation ? + static_cast(IndBuff.pSuballocation->GetOffset() / sizeof(Uint32)) : 0; } Uint32 GetBaseVertex() const { auto& VertBuff = Buffers[BUFFER_ID_VERTEX0]; - VERIFY(!VertBuff.pCacheAllocation || VertBuff.pCacheAllocation->GetRegion().UnalignedOffset % sizeof(VertexAttribs0) == 0, + VERIFY(!VertBuff.pSuballocation || VertBuff.pSuballocation->GetOffset() % sizeof(VertexAttribs0) == 0, "Allocation offset is not multiple of sizeof(VertexAttribs0)"); - return VertBuff.pCacheAllocation ? - static_cast(VertBuff.pCacheAllocation->GetRegion().UnalignedOffset / sizeof(VertexAttribs0)) : + return VertBuff.pSuballocation ? + static_cast(VertBuff.pSuballocation->GetOffset() / sizeof(VertexAttribs0)) : 0; } - ITexture* GetTexture(Uint32 Index, IRenderDevice* pDevice, IDeviceContext* pCtx) - { - auto& TexInfo = Textures[Index]; - if (TexInfo.pTexture) - return TexInfo.pTexture; - else if (TexInfo.pCacheAllocation) - return TexInfo.pCacheAllocation->GetTexture(pDevice, pCtx); - else - return nullptr; - } - - const float4& GetUVScaleBias(Uint32 Index) - { - return Textures[Index].UVScaleBias; - } - - float GetSlice(Uint32 Index) - { - return Textures[Index].Slice; - } - private: void LoadFromFile(IRenderDevice* pDevice, IDeviceContext* pContext, @@ -434,23 +411,19 @@ private: struct BufferInfo { - RefCntAutoPtr pBuffer; - - RefCntAutoPtr pCacheAllocation; + RefCntAutoPtr pBuffer; + RefCntAutoPtr pSuballocation; }; std::array Buffers; struct TextureInfo { - RefCntAutoPtr pTexture; - float4 UVScaleBias{1, 1, 0, 0}; - float Slice = 0; - - RefCntAutoPtr pCacheAllocation; + RefCntAutoPtr pTexture; + RefCntAutoPtr pAtlasSuballocation; bool IsValid() const { - return pTexture || pCacheAllocation; + return pTexture || pAtlasSuballocation; } }; std::vector Textures; diff --git a/AssetLoader/interface/GLTFResourceManager.hpp b/AssetLoader/interface/GLTFResourceManager.hpp index a6c2a82..db386f1 100644 --- a/AssetLoader/interface/GLTFResourceManager.hpp +++ b/AssetLoader/interface/GLTFResourceManager.hpp @@ -36,297 +36,103 @@ #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h" #include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp" #include "../../../DiligentCore/Common/interface/ObjectBase.hpp" -#include "../../../DiligentCore/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.hpp" -#include "../../../DiligentCore/Graphics/GraphicsAccessories/interface/DynamicAtlasManager.hpp" +#include "../../../DiligentCore/Graphics/GraphicsTools/interface/BufferSuballocator.h" +#include "../../../DiligentCore/Graphics/GraphicsTools/interface/DynamicTextureAtlas.h" namespace Diligent { -/// GLTF resource manager -class GLTFResourceManager final : public ObjectBase +namespace GLTF { - class BufferCache; - class TextureCache; +/// GLTF resource manager +class ResourceManager final : public ObjectBase +{ public: using TBase = ObjectBase; - class BufferAllocation final : public ObjectBase - { - public: - BufferAllocation(IReferenceCounters* pRefCounters, - RefCntAutoPtr pResourceMg, - BufferCache& ParentCache, - VariableSizeAllocationsManager::Allocation&& Region) : - // clang-format off - ObjectBase{pRefCounters}, - m_pResMgr {std::move(pResourceMg)}, - m_ParentCache {ParentCache}, - m_Region {std::move(Region)} - // clang-format on - { - VERIFY_EXPR(m_Region.IsValid()); - } - - ~BufferAllocation() - { - m_ParentCache.FreeAllocation(std::move(m_Region)); - } - - IBuffer* GetBuffer(IRenderDevice* pDevice, IDeviceContext* pContext) const - { - return m_ParentCache.GetBuffer(pDevice, pContext); - } - - const VariableSizeAllocationsManager::Allocation& GetRegion() const - { - return m_Region; - } - - private: - RefCntAutoPtr m_pResMgr; - BufferCache& m_ParentCache; - VariableSizeAllocationsManager::Allocation m_Region; - }; - - class TextureAllocation final : public ObjectBase - { - public: - TextureAllocation(IReferenceCounters* pRefCounters, - RefCntAutoPtr pResourceMg, - TextureCache& ParentCache, - Uint32 Width, - Uint32 Height, - Uint32 Slice, - DynamicAtlasManager::Region&& Region) : - // clang-format off - ObjectBase{pRefCounters}, - m_pResMgr {std::move(pResourceMg)}, - m_ParentCache {ParentCache}, - m_Width {Width}, - m_Height {Height}, - m_Slice {Slice}, - m_Region {std::move(Region)} - // clang-format on - { - VERIFY_EXPR(!m_Region.IsEmpty()); - } - - ~TextureAllocation() - { - m_ParentCache.FreeAllocation(m_Slice, std::move(m_Region)); - } - - ITexture* GetTexture(IRenderDevice* pDevice, IDeviceContext* pContext) const - { - return m_ParentCache.GetTexture(pDevice, pContext); - } - - const TextureDesc& GetTexDesc() const - { - return m_ParentCache.GetTexDesc(); - } - - const DynamicAtlasManager::Region& GetRegion() - { - return m_Region; - } - - Uint32 GetWidth() const { return m_Width; } - Uint32 GetHeight() const { return m_Height; } - Uint32 GetSlice() const { return m_Slice; } - - private: - RefCntAutoPtr m_pResMgr; - TextureCache& m_ParentCache; - const Uint32 m_Width; - const Uint32 m_Height; - const Uint32 m_Slice; - DynamicAtlasManager::Region m_Region; - }; - - struct TextureCacheAttribs - { - TextureDesc Desc; - - Uint32 Granularity = 128; - Uint32 ExtraSliceCount = 2; - Uint32 MaxSlices = 2048; - }; struct CreateInfo { - const BufferDesc* Buffers = nullptr; // [NumBuffers] - Uint32 NumBuffers = 0; + const BufferSuballocatorCreateInfo* BuffSuballocators = nullptr; // [NumBuffSuballocators] + const DynamicTextureAtlasCreateInfo* TexAtlases = nullptr; // [NumTexAtlases] - const TextureCacheAttribs* Textures = nullptr; // [NumTextures] - Uint32 NumTextures = 0; + Uint32 NumBuffSuballocators = 0; + Uint32 NumTexAtlases = 0; - TextureDesc DefaultTexDesc; - - Uint32 DefaultExtraSliceCount = 1; + DynamicTextureAtlasCreateInfo DefaultAtlasDesc; }; - static RefCntAutoPtr Create(IRenderDevice* pDevice, - const CreateInfo& CI); + static RefCntAutoPtr Create(IRenderDevice* pDevice, + const CreateInfo& CI); - RefCntAutoPtr AllocateBufferSpace(Uint32 BufferIndex, Uint32 Size, Uint32 Alignment) + RefCntAutoPtr AllocateBufferSpace(Uint32 BufferIndex, + Uint32 Size, + Uint32 Alignment) { - return m_Buffers[BufferIndex].Allocate(Size, Alignment); + RefCntAutoPtr pSuballoc; + m_BufferSuballocators[BufferIndex]->Allocate(Size, Alignment, &pSuballoc); + return pSuballoc; } - RefCntAutoPtr AllocateTextureSpace(TEXTURE_FORMAT Fmt, Uint32 Width, Uint32 Height, const char* CacheId = nullptr); + RefCntAutoPtr AllocateTextureSpace(TEXTURE_FORMAT Fmt, + Uint32 Width, + Uint32 Height, + const char* CacheId = nullptr); - RefCntAutoPtr FindAllocation(const char* CacheId); + RefCntAutoPtr FindAllocation(const char* CacheId); - Uint32 GetResourceVersion() const + Uint32 GetResourceVersion() { - return m_ResourceVersion.load(); + Uint32 Version = 0; + + std::lock_guard Lock{m_AtlasesMtx}; + for (auto atlas_it : m_Atlases) + Version += atlas_it.second->GetVersion(); + + return Version; } IBuffer* GetBuffer(Uint32 Index, IRenderDevice* pDevice, IDeviceContext* pContext) { - return m_Buffers[Index].GetBuffer(pDevice, pContext); + return m_BufferSuballocators[Index]->GetBuffer(pDevice, pContext); } + ITexture* GetTexture(TEXTURE_FORMAT Fmt, IRenderDevice* pDevice, IDeviceContext* pContext) { - decltype(m_Textures)::iterator cache_it; // NB: can't initialize it without locking the mutex + decltype(m_Atlases)::iterator cache_it; // NB: can't initialize it without locking the mutex { - std::lock_guard Lock{m_TexturesMtx}; - cache_it = m_Textures.find(Fmt); - if (cache_it == m_Textures.end()) + std::lock_guard Lock{m_AtlasesMtx}; + cache_it = m_Atlases.find(Fmt); + if (cache_it == m_Atlases.end()) return nullptr; } - return cache_it->second.GetTexture(pDevice, pContext); + return cache_it->second->GetTexture(pDevice, pContext); } private: template friend class MakeNewRCObj; - GLTFResourceManager(IReferenceCounters* pRefCounters, - IRenderDevice* pDevice, - const CreateInfo& CI); - - class BufferCache - { - public: - BufferCache(GLTFResourceManager& Owner, IRenderDevice* pDevice, const BufferDesc& BuffDesc); - - // clang-format off - BufferCache (const BufferCache&) = delete; - BufferCache& operator=(const BufferCache&) = delete; - BufferCache& operator=(BufferCache&&) = delete; - // clang-format on - - BufferCache(BufferCache&& Cache) noexcept : - // clang-format off - m_Owner {Cache.m_Owner}, - m_Mgr {std::move(Cache.m_Mgr)}, - m_pBuffer{std::move(Cache.m_pBuffer)} - // clang-format on - {} - - IBuffer* GetBuffer(IRenderDevice* pDevice, IDeviceContext* pContext); - - RefCntAutoPtr Allocate(Uint32 Size, Uint32 Alignment); + ResourceManager(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + const CreateInfo& CI); - void FreeAllocation(VariableSizeAllocationsManager::Allocation&& Allocation) - { - std::lock_guard Lock{m_Mtx}; - m_Mgr.Free(std::move(Allocation)); - } - - private: - GLTFResourceManager& m_Owner; - - std::mutex m_Mtx; - VariableSizeAllocationsManager m_Mgr; - RefCntAutoPtr m_pBuffer; - }; - std::vector m_Buffers; + std::vector> m_BufferSuballocators; + DynamicTextureAtlasCreateInfo m_DefaultAtlasDesc; + const std::string m_DefaultAtlasName; - class TextureCache - { - public: - TextureCache(GLTFResourceManager& Owner, IRenderDevice* pDevice, const TextureCacheAttribs& CacheCI); - - // clang-format off - TextureCache (const TextureCache&) = delete; - TextureCache& operator=(const TextureCache&) = delete; - TextureCache& operator=(TextureCache&&) = delete; - // clang-format on - - TextureCache(TextureCache&& Cache) noexcept : - // clang-format off - m_Owner {Cache.m_Owner}, - m_Attribs {Cache.m_Attribs}, - m_TexName {std::move(m_TexName)}, - m_Slices {std::move(Cache.m_Slices)}, - m_pTexture{std::move(Cache.m_pTexture)} - // clang-format on - { - m_Attribs.Desc.Name = m_TexName.c_str(); - } + std::mutex m_AtlasesMtx; + std::unordered_map> m_Atlases; - ITexture* GetTexture(IRenderDevice* pDevice, IDeviceContext* pContext); - - const TextureDesc& GetTexDesc() const - { - return m_Attribs.Desc; - } - - RefCntAutoPtr Allocate(Uint32 Width, Uint32 Height); - - void FreeAllocation(Uint32 Slice, DynamicAtlasManager::Region&& Allocation); - - private: - GLTFResourceManager& m_Owner; - - TextureCacheAttribs m_Attribs; - - std::string m_TexName; - - struct SliceManager - { - SliceManager(Uint32 Width, Uint32 Height) : - Mgr{Width, Height} - {} - - DynamicAtlasManager::Region Allocate(Uint32 Width, Uint32 Height) - { - std::lock_guard Lock{Mtx}; - return Mgr.Allocate(Width, Height); - } - void Free(DynamicAtlasManager::Region&& Region) - { - std::lock_guard Lock{Mtx}; - Mgr.Free(std::move(Region)); - } - - private: - std::mutex Mtx; - DynamicAtlasManager Mgr; - }; - std::mutex m_SlicesMtx; - std::vector> m_Slices; - - RefCntAutoPtr m_pTexture; - }; - - TextureDesc m_DefaultTexDesc; - const Uint32 m_DefaultExtraSliceCount; - - - std::mutex m_TexturesMtx; - std::unordered_map m_Textures; - - std::mutex m_AllocationsMtx; - std::unordered_map> m_Allocations; + std::mutex m_TexAllocationsMtx; + std::unordered_map> m_TexAllocations; std::atomic_uint32_t m_ResourceVersion = {}; }; +} // namespace GLTF + } // namespace Diligent -- cgit v1.2.3