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/src/GLTFLoader.cpp | 115 ++++++++------ AssetLoader/src/GLTFResourceManager.cpp | 274 ++++++-------------------------- 2 files changed, 110 insertions(+), 279 deletions(-) (limited to 'AssetLoader/src') diff --git a/AssetLoader/src/GLTFLoader.cpp b/AssetLoader/src/GLTFLoader.cpp index 9b18bd1..c138eed 100644 --- a/AssetLoader/src/GLTFLoader.cpp +++ b/AssetLoader/src/GLTFLoader.cpp @@ -682,25 +682,18 @@ void Model::LoadTextures(IRenderDevice* pDevice, const tinygltf::Image& gltf_image = gltf_model.images[gltf_tex.source]; // TODO: simplify path - const auto CacheId = BaseDir + gltf_image.uri; + const auto CacheId = !gltf_image.uri.empty() ? BaseDir + gltf_image.uri : ""; TextureInfo TexInfo; if (CacheInfo.pResourceMgr != nullptr) { - TexInfo.pCacheAllocation = CacheInfo.pResourceMgr->FindAllocation(CacheId.c_str()); - if (TexInfo.pCacheAllocation) + TexInfo.pAtlasSuballocation = CacheInfo.pResourceMgr->FindAllocation(CacheId.c_str()); + if (TexInfo.pAtlasSuballocation) { - const auto& TexDesc = TexInfo.pCacheAllocation->GetTexDesc(); - const auto& Region = TexInfo.pCacheAllocation->GetRegion(); - VERIFY_EXPR(gltf_image.width == static_cast(TexInfo.pCacheAllocation->GetWidth())); - VERIFY_EXPR(gltf_image.height == static_cast(TexInfo.pCacheAllocation->GetHeight())); - - TexInfo.UVScaleBias.x = static_cast(gltf_image.width) / static_cast(TexDesc.Width); - TexInfo.UVScaleBias.y = static_cast(gltf_image.height) / static_cast(TexDesc.Height); - TexInfo.UVScaleBias.z = static_cast(Region.x) / static_cast(TexDesc.Width); - TexInfo.UVScaleBias.w = static_cast(Region.y) / static_cast(TexDesc.Height); - - TexInfo.Slice = static_cast(TexInfo.pCacheAllocation->GetSlice()); + // Note that the texture may appear in the cache after the call to LoadImageData because + // it can be loaded by another thread + VERIFY_EXPR(gltf_image.width == -1 || gltf_image.width == static_cast(TexInfo.pAtlasSuballocation->GetSize().x)); + VERIFY_EXPR(gltf_image.height == -1 || gltf_image.height == static_cast(TexInfo.pAtlasSuballocation->GetSize().y)); } } else if (pTextureCache != nullptr) @@ -751,7 +744,8 @@ void Model::LoadTextures(IRenderDevice* pDevice, { if (CacheInfo.pResourceMgr != nullptr) { - TexInfo.pCacheAllocation = CacheInfo.pResourceMgr->AllocateTextureSpace(TEX_FORMAT_RGBA8_UNORM, gltf_image.width, gltf_image.height); + TexInfo.pAtlasSuballocation = + CacheInfo.pResourceMgr->AllocateTextureSpace(TEX_FORMAT_RGBA8_UNORM, gltf_image.width, gltf_image.height, CacheId.c_str()); } else { @@ -768,8 +762,6 @@ void Model::LoadTextures(IRenderDevice* pDevice, pDevice->CreateTexture(TexDesc, nullptr, &TexInfo.pTexture); TexInfo.pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)->SetSampler(pSampler); - TexInfo.UVScaleBias = float4{1, 1, 0, 0}; - TexInfo.Slice = 0; TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, 0, 0, 1); } @@ -782,6 +774,7 @@ void Model::LoadTextures(IRenderDevice* pDevice, TextureLoadInfo LoadInfo; if (CacheInfo.pResourceMgr != nullptr) { + LoadInfo.Name = "Staging upload texture for compressed"; LoadInfo.Usage = USAGE_STAGING; LoadInfo.BindFlags = BIND_NONE; LoadInfo.CPUAccessFlags = CPU_ACCESS_WRITE; @@ -801,27 +794,20 @@ void Model::LoadTextures(IRenderDevice* pDevice, } if (CacheInfo.pResourceMgr != nullptr && TexInitData.pStagingTex) { - const auto& TexDesc = TexInitData.pStagingTex->GetDesc(); - TexInfo.pCacheAllocation = CacheInfo.pResourceMgr->AllocateTextureSpace(TexDesc.Format, TexDesc.Width, TexDesc.Height); + const auto& TexDesc = TexInitData.pStagingTex->GetDesc(); + TexInfo.pAtlasSuballocation = CacheInfo.pResourceMgr->AllocateTextureSpace(TexDesc.Format, TexDesc.Width, TexDesc.Height, CacheId.c_str()); } } - if (TexInfo.pCacheAllocation) + if (TexInfo.pAtlasSuballocation) { - const auto& AtlasDesc = TexInfo.pCacheAllocation->GetTexDesc(); + const auto& AtlasDesc = TexInfo.pAtlasSuballocation->GetAtlas()->GetAtlasDesc(); + const auto& Origin = TexInfo.pAtlasSuballocation->GetOrigin(); - const auto& Region = TexInfo.pCacheAllocation->GetRegion(); if (!TexInitData.pStagingTex) { - TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, Region.x, Region.y, AtlasDesc.MipLevels); + TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, Origin.x, Origin.y, AtlasDesc.MipLevels); } - - TexInfo.UVScaleBias.x = static_cast(gltf_image.width) / static_cast(AtlasDesc.Width); - TexInfo.UVScaleBias.y = static_cast(gltf_image.height) / static_cast(AtlasDesc.Height); - TexInfo.UVScaleBias.z = static_cast(Region.x) / static_cast(AtlasDesc.Width); - TexInfo.UVScaleBias.w = static_cast(Region.y) / static_cast(AtlasDesc.Height); - - TexInfo.Slice = static_cast(TexInfo.pCacheAllocation->GetSlice()); } if (!InitData) @@ -866,14 +852,17 @@ void Model::PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx) VERIFY_EXPR(InitData->Textures.size() == Textures.size()); for (Uint32 i = 0; i < Textures.size(); ++i) { - auto* pTexture = GetTexture(i, pDevice, pCtx); + auto& TexInfo = Textures[i]; + ITexture* pTexture = TexInfo.pAtlasSuballocation ? + TexInfo.pAtlasSuballocation->GetAtlas()->GetTexture(pDevice, pCtx) : + TexInfo.pTexture; if (!pTexture) continue; auto& TexData = InitData->Textures[i]; const auto& Levels = TexData.Levels; - const auto DstSlice = static_cast(Textures[i].Slice); + const auto DstSlice = TexInfo.pAtlasSuballocation ? TexInfo.pAtlasSuballocation->GetSlice() : 0; if (!Levels.empty()) { VERIFY_EXPR(Levels.size() == 1 || Levels.size() == pTexture->GetDesc().MipLevels); @@ -903,15 +892,24 @@ void Model::PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx) CopyAttribs.pDstTexture = pTexture; CopyAttribs.SrcTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION; CopyAttribs.DstTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION; + CopyAttribs.SrcSlice = 0; + CopyAttribs.DstSlice = DstSlice; - const auto& DstTexDesc = pTexture->GetDesc(); - for (Uint32 mip = 0; mip < DstTexDesc.MipLevels; ++mip) + if (Textures[i].pAtlasSuballocation) + { + const auto& Origin = Textures[i].pAtlasSuballocation->GetOrigin(); + CopyAttribs.DstX = Origin.x; + CopyAttribs.DstY = Origin.y; + } + const auto& DstTexDesc = pTexture->GetDesc(); + auto NumMipLevels = std::min(DstTexDesc.MipLevels, TexData.pStagingTex->GetDesc().MipLevels); + for (Uint32 mip = 0; mip < NumMipLevels; ++mip) { - CopyAttribs.SrcSlice = 0; - CopyAttribs.DstSlice = DstSlice; CopyAttribs.SrcMipLevel = mip; CopyAttribs.DstMipLevel = mip; pCtx->CopyTexture(CopyAttribs); + CopyAttribs.DstX /= 2; + CopyAttribs.DstY /= 2; } } else @@ -923,10 +921,20 @@ void Model::PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx) auto UpdateBuffer = [&](BUFFER_ID BuffId, const void* pData, size_t Size) // { - auto* pBuffer = GetBuffer(BuffId, pDevice, pCtx); - VERIFY_EXPR(pBuffer != nullptr); - auto Offset = Buffers[BuffId].pCacheAllocation ? Buffers[BuffId].pCacheAllocation->GetRegion().UnalignedOffset : 0; - pCtx->UpdateBuffer(pBuffer, static_cast(Offset), static_cast(Size), pData, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + auto& BuffInfo = Buffers[BuffId]; + IBuffer* pBuffer = nullptr; + Uint32 Offset = 0; + if (BuffInfo.pSuballocation) + { + pBuffer = BuffInfo.pSuballocation->GetAllocator()->GetBuffer(pDevice, pCtx); + Offset = BuffInfo.pSuballocation->GetOffset(); + } + else + { + pBuffer = BuffInfo.pBuffer; + } + + pCtx->UpdateBuffer(pBuffer, Offset, static_cast(Size), pData, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); if (Buffers[BuffId].pBuffer != nullptr) { VERIFY_EXPR(Buffers[BuffId].pBuffer == pBuffer); @@ -1163,8 +1171,12 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) auto TexIndex = Mat.TextureIds[Param.TextureId]; if (TexIndex >= 0) { - Param.UVScaleBias = GetUVScaleBias(TexIndex); - Param.Slice = GetSlice(TexIndex); + const auto& TexInfo = Textures[TexIndex]; + if (TexInfo.pAtlasSuballocation) + { + Param.UVScaleBias = TexInfo.pAtlasSuballocation->GetUVScaleBias(); + Param.Slice = static_cast(TexInfo.pAtlasSuballocation->GetSlice()); + } } } @@ -1321,12 +1333,12 @@ namespace struct ImageLoaderData { - using TexAllocationsVector = std::vector>; + using TexAllocationsVector = std::vector>; using TexturesVector = std::vector>; Model::TextureCacheType* const pTextureCache; TexturesVector* const pTextureHold; - GLTFResourceManager* const pResourceMgr; + ResourceManager* const pResourceMgr; TexAllocationsVector* const pTextureAllocationsHold; std::string BaseDir; @@ -1349,17 +1361,18 @@ bool LoadImageData(tinygltf::Image* gltf_image, if (pLoaderData != nullptr) { // TODO: simplify path - auto CacheId = pLoaderData->BaseDir + gltf_image->uri; + auto CacheId = !gltf_image->uri.empty() ? pLoaderData->BaseDir + gltf_image->uri : ""; if (pLoaderData->pResourceMgr != nullptr) { if (auto pAllocation = pLoaderData->pResourceMgr->FindAllocation(CacheId.c_str())) { - const auto& TexDesc = pAllocation->GetTexDesc(); + const auto& TexDesc = pAllocation->GetAtlas()->GetAtlasDesc(); const auto& FmtAttribs = GetTextureFormatAttribs(TexDesc.Format); + const auto Size = pAllocation->GetSize(); - gltf_image->width = pAllocation->GetWidth(); - gltf_image->height = pAllocation->GetHeight(); + gltf_image->width = Size.x; + gltf_image->height = Size.y; gltf_image->component = FmtAttribs.NumComponents; gltf_image->bits = FmtAttribs.ComponentSize * 8; gltf_image->pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE; @@ -1660,7 +1673,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice, auto BufferSize = static_cast(VertexData0.size() * sizeof(VertexData0[0])); if (CacheInfo.pResourceMgr != nullptr) { - Buffers[BUFFER_ID_VERTEX0].pCacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.VertexBuffer0Idx, BufferSize, 1); + Buffers[BUFFER_ID_VERTEX0].pSuballocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.VertexBuffer0Idx, BufferSize, 1); } else { @@ -1684,7 +1697,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice, auto BufferSize = static_cast(VertexData1.size() * sizeof(VertexData1[0])); if (CacheInfo.pResourceMgr != nullptr) { - Buffers[BUFFER_ID_VERTEX1].pCacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.VertexBuffer1Idx, BufferSize, 1); + Buffers[BUFFER_ID_VERTEX1].pSuballocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.VertexBuffer1Idx, BufferSize, 1); } else { @@ -1709,7 +1722,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice, auto BufferSize = static_cast(IndexBuffer.size() * sizeof(IndexBuffer[0])); if (CacheInfo.pResourceMgr != nullptr) { - Buffers[BUFFER_ID_INDEX].pCacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.IndexBufferIdx, BufferSize, 1); + Buffers[BUFFER_ID_INDEX].pSuballocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.IndexBufferIdx, BufferSize, 1); } else { diff --git a/AssetLoader/src/GLTFResourceManager.cpp b/AssetLoader/src/GLTFResourceManager.cpp index e9b37a3..a30e265 100644 --- a/AssetLoader/src/GLTFResourceManager.cpp +++ b/AssetLoader/src/GLTFResourceManager.cpp @@ -28,256 +28,67 @@ #include "GLTFResourceManager.hpp" #include "DefaultRawMemoryAllocator.hpp" #include "Align.hpp" +#include "GraphicsAccessories.hpp" namespace Diligent { -GLTFResourceManager::BufferCache::BufferCache(GLTFResourceManager& Owner, - IRenderDevice* pDevice, - const BufferDesc& BuffDesc) : - m_Owner{Owner}, - m_Mgr{BuffDesc.uiSizeInBytes, DefaultRawMemoryAllocator::GetAllocator()} +namespace GLTF { - pDevice->CreateBuffer(BuffDesc, nullptr, &m_pBuffer); -} - -IBuffer* GLTFResourceManager::BufferCache::GetBuffer(IRenderDevice* pDevice, IDeviceContext* pContext) -{ - std::lock_guard Lock{m_Mtx}; - - const auto& BuffDesc = m_pBuffer->GetDesc(); - const auto MgrSize = m_Mgr.GetMaxSize(); - if (BuffDesc.uiSizeInBytes < MgrSize) - { - // Extend the buffer - auto NewBuffDesc = BuffDesc; - - NewBuffDesc.uiSizeInBytes = static_cast(MgrSize); - - 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_pBuffer = std::move(pNewBuffer); - } - - return m_pBuffer.RawPtr(); -} - -RefCntAutoPtr GLTFResourceManager::BufferCache::Allocate(Uint32 Size, Uint32 Alignment) -{ - VERIFY_EXPR(Size > 0 && IsPowerOfTwo(Alignment)); - - std::lock_guard Lock{m_Mtx}; - - auto Region = m_Mgr.Allocate(Size, Alignment); - while (!Region.IsValid()) - { - m_Mgr.Extend(m_Mgr.GetMaxSize()); - Region = m_Mgr.Allocate(Size, Alignment); - } - - return RefCntAutoPtr{ - MakeNewRCObj()( - RefCntAutoPtr{&m_Owner}, - *this, - std::move(Region) // - ) // - }; -} - -GLTFResourceManager::TextureCache::TextureCache(GLTFResourceManager& Owner, - IRenderDevice* pDevice, - const TextureCacheAttribs& CacheCI) : - m_Owner{Owner}, - m_Attribs{CacheCI} -{ - m_Attribs.Desc.Name = m_TexName.c_str(); - - const auto& Desc = m_Attribs.Desc; - for (Uint32 slice = 0; slice < Desc.ArraySize; ++slice) - { - m_Slices.emplace_back(new SliceManager{Desc.Width / m_Attribs.Granularity, Desc.Height / m_Attribs.Granularity}); - } - - DEV_CHECK_ERR(IsPowerOfTwo(m_Attribs.Granularity), "Granularity (", m_Attribs.Granularity, ") must be a power of two"); - DEV_CHECK_ERR((Desc.Width % m_Attribs.Granularity) == 0, "Atlas width (", Desc.Width, ") is not multiple of granularity (", m_Attribs.Granularity, ")"); - DEV_CHECK_ERR((Desc.Height % m_Attribs.Granularity) == 0, "Atlas height (", Desc.Height, ") is not multiple of granularity (", m_Attribs.Granularity, ")"); - - if (pDevice != nullptr) - { - pDevice->CreateTexture(Desc, nullptr, &m_pTexture); - } -} - - -ITexture* GLTFResourceManager::TextureCache::GetTexture(IRenderDevice* pDevice, IDeviceContext* pContext) -{ - RefCntAutoPtr pNewTexture; - { - std::lock_guard Lock{m_SlicesMtx}; - if (!m_pTexture || m_pTexture->GetDesc().ArraySize < m_Slices.size()) - { - m_Attribs.Desc.ArraySize = static_cast(m_Slices.size()); - VERIFY_EXPR(pDevice != nullptr); - pDevice->CreateTexture(m_Attribs.Desc, nullptr, &pNewTexture); - } - if (pNewTexture) - { - if (m_pTexture) - { - const auto& OldDesc = m_pTexture->GetDesc(); - - CopyTextureAttribs CopyAttribs; - CopyAttribs.pSrcTexture = m_pTexture; - CopyAttribs.pDstTexture = pNewTexture; - CopyAttribs.SrcTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION; - CopyAttribs.DstTextureTransitionMode = RESOURCE_STATE_TRANSITION_MODE_TRANSITION; - - for (Uint32 slice = 0; slice < OldDesc.ArraySize; ++slice) - { - for (Uint32 mip = 0; mip < OldDesc.MipLevels; ++mip) - { - CopyAttribs.SrcSlice = slice; - CopyAttribs.DstSlice = slice; - CopyAttribs.SrcMipLevel = mip; - CopyAttribs.DstMipLevel = mip; - pContext->CopyTexture(CopyAttribs); - } - } - } - m_pTexture = std::move(pNewTexture); - m_Owner.m_ResourceVersion.fetch_add(1); - } - } - - return m_pTexture; -} - -RefCntAutoPtr GLTFResourceManager::TextureCache::Allocate(Uint32 Width, Uint32 Height) -{ - VERIFY_EXPR(Width > 0 && Height > 0); - const auto& TexDesc = m_Attribs.Desc; - if (Width > TexDesc.Width || Height > TexDesc.Height) - { - LOG_ERROR_MESSAGE("Requested size ", Width, " x ", Height, " exceeds the texture size ", TexDesc.Width, " x ", TexDesc.Height); - return {}; - } - - const auto Granularity = m_Attribs.Granularity; - for (Uint32 Slice = 0; Slice < m_Attribs.MaxSlices; ++Slice) - { - SliceManager* pSliceMgr = nullptr; - { - std::lock_guard Lock{m_SlicesMtx}; - if (Slice == m_Slices.size()) - { - for (Uint32 ExtraSlice = 0; ExtraSlice < m_Attribs.ExtraSliceCount && Slice + ExtraSlice < m_Attribs.MaxSlices; ++ExtraSlice) - { - m_Slices.emplace_back(new SliceManager{TexDesc.Width / Granularity, TexDesc.Height / Granularity}); - } - } - pSliceMgr = m_Slices[Slice].get(); - } - auto Region = pSliceMgr->Allocate((Width + Granularity - 1) / Granularity, (Height + Granularity - 1) / Granularity); - if (!Region.IsEmpty()) - { - Region.x *= Granularity; - Region.y *= Granularity; - Region.width *= Granularity; - Region.height *= Granularity; - - return RefCntAutoPtr{ - MakeNewRCObj()( - RefCntAutoPtr{&m_Owner}, - *this, - Width, - Height, - Slice, - std::move(Region) // - ) // - }; - } - } - - return RefCntAutoPtr{}; -} - -void GLTFResourceManager::TextureCache::FreeAllocation(Uint32 Slice, DynamicAtlasManager::Region&& Allocation) -{ - const auto Granularity = m_Attribs.Granularity; - VERIFY((Allocation.x % Granularity) == 0, "Allocation x (", Allocation.x, ") is not multiple of granularity (", Granularity, ")"); - VERIFY((Allocation.y % Granularity) == 0, "Allocation y (", Allocation.y, ") is not multiple of granularity (", Granularity, ")"); - VERIFY((Allocation.width % Granularity) == 0, "Allocation width (", Allocation.width, ") is not multiple of granularity (", Granularity, ")"); - VERIFY((Allocation.height % Granularity) == 0, "Allocation height (", Allocation.height, ") is not multiple of granularity (", Granularity, ")"); - - Allocation.x /= Granularity; - Allocation.y /= Granularity; - Allocation.width /= Granularity; - Allocation.height /= Granularity; - - SliceManager* pSliceMgr = nullptr; - { - std::lock_guard Lock{m_SlicesMtx}; - pSliceMgr = m_Slices[Slice].get(); - } - pSliceMgr->Free(std::move(Allocation)); -} - - - -RefCntAutoPtr GLTFResourceManager::Create(IRenderDevice* pDevice, - const CreateInfo& CI) +RefCntAutoPtr ResourceManager::Create(IRenderDevice* pDevice, + const CreateInfo& CI) { - return RefCntAutoPtr{MakeNewRCObj()(pDevice, CI)}; + return RefCntAutoPtr{MakeNewRCObj()(pDevice, CI)}; } -GLTFResourceManager::GLTFResourceManager(IReferenceCounters* pRefCounters, - IRenderDevice* pDevice, - const CreateInfo& CI) : +ResourceManager::ResourceManager(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + const CreateInfo& CI) : TBase{pRefCounters}, - m_DefaultTexDesc{CI.DefaultTexDesc}, - m_DefaultExtraSliceCount{CI.DefaultExtraSliceCount} + m_DefaultAtlasDesc{CI.DefaultAtlasDesc}, + m_DefaultAtlasName{CI.DefaultAtlasDesc.Desc.Name != nullptr ? CI.DefaultAtlasDesc.Desc.Name : "GLTF texture atlas"} { - m_Buffers.reserve(CI.NumBuffers); - for (Uint32 i = 0; i < CI.NumBuffers; ++i) + m_DefaultAtlasDesc.Desc.Name = m_DefaultAtlasName.c_str(); + m_BufferSuballocators.resize(CI.NumBuffSuballocators); + for (Uint32 i = 0; i < CI.NumBuffSuballocators; ++i) { - m_Buffers.emplace_back(*this, pDevice, CI.Buffers[i]); + CreateBufferSuballocator(pDevice, CI.BuffSuballocators[i], &m_BufferSuballocators[i]); } - m_Textures.reserve(CI.NumTextures); - for (Uint32 i = 0; i < CI.NumTextures; ++i) + m_Atlases.reserve(CI.NumTexAtlases); + for (Uint32 i = 0; i < CI.NumTexAtlases; ++i) { - m_Textures.emplace(CI.Textures[i].Desc.Format, TextureCache{*this, pDevice, CI.Textures[i]}); + RefCntAutoPtr pAtlas; + CreateDynamicTextureAtlas(pDevice, CI.TexAtlases[i], &pAtlas); + m_Atlases.emplace(CI.TexAtlases[i].Desc.Format, std::move(pAtlas)); } } -RefCntAutoPtr GLTFResourceManager::FindAllocation(const char* CacheId) +RefCntAutoPtr ResourceManager::FindAllocation(const char* CacheId) { - RefCntAutoPtr pAllocation; + RefCntAutoPtr pAllocation; - std::lock_guard Lock{m_AllocationsMtx}; + std::lock_guard Lock{m_TexAllocationsMtx}; - auto it = m_Allocations.find(CacheId); - if (it != m_Allocations.end()) + auto it = m_TexAllocations.find(CacheId); + if (it != m_TexAllocations.end()) { pAllocation = it->second.Lock(); if (!pAllocation) - m_Allocations.erase(it); + m_TexAllocations.erase(it); } return pAllocation; } -RefCntAutoPtr GLTFResourceManager::AllocateTextureSpace( +RefCntAutoPtr ResourceManager::AllocateTextureSpace( TEXTURE_FORMAT Fmt, Uint32 Width, Uint32 Height, const char* CacheId) { - RefCntAutoPtr pAllocation; + RefCntAutoPtr pAllocation; if (CacheId != nullptr && *CacheId != 0) { pAllocation = FindAllocation(CacheId); @@ -285,33 +96,40 @@ RefCntAutoPtr GLTFResourceManager::Alloc if (!pAllocation) { - 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()) { - DEV_CHECK_ERR(m_DefaultTexDesc.Width > 0 && m_DefaultTexDesc.Height > 0, "Default texture description is not initialized"); - TextureCacheAttribs NewCacheAttribs; - NewCacheAttribs.Desc = m_DefaultTexDesc; + DEV_CHECK_ERR(m_DefaultAtlasDesc.Desc.Width > 0 && + m_DefaultAtlasDesc.Desc.Height > 0 && + m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_UNDEFINED, + "Default texture description is not initialized"); - NewCacheAttribs.Desc.Name = "GLTF Texture cache"; - NewCacheAttribs.Desc.Format = Fmt; + auto AtalsCreateInfo = m_DefaultAtlasDesc; + AtalsCreateInfo.Desc.Format = Fmt; - cache_it = m_Textures.emplace(Fmt, TextureCache{*this, nullptr, NewCacheAttribs}).first; + RefCntAutoPtr pAtlas; + CreateDynamicTextureAtlas(nullptr, AtalsCreateInfo, &pAtlas); + DEV_CHECK_ERR(pAtlas, "Failed to create new texture atlas"); + + cache_it = m_Atlases.emplace(Fmt, std::move(pAtlas)).first; } } // Allocate outside of mutex - pAllocation = cache_it->second.Allocate(Width, Height); + cache_it->second->Allocate(Width, Height, &pAllocation); } if (CacheId != nullptr && *CacheId != 0) { - auto inserted = m_Allocations.emplace(CacheId, pAllocation).second; + auto inserted = m_TexAllocations.emplace(CacheId, pAllocation).second; VERIFY_EXPR(inserted); } return pAllocation; } +} // namespace GLTF + } // namespace Diligent -- cgit v1.2.3