summaryrefslogtreecommitdiffstats
path: root/AssetLoader/src
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-12-02 02:13:42 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-12-02 02:13:42 +0000
commitd81817038a73aac29846928ebd1fcd8d8ace0f60 (patch)
treed9fa236af4332c1cc4191c9e480bed6928761799 /AssetLoader/src
parentGLTF Loader: added GetFirstIndexLocation and GetBaseVertex methods (diff)
downloadDiligentTools-d81817038a73aac29846928ebd1fcd8d8ace0f60.tar.gz
DiligentTools-d81817038a73aac29846928ebd1fcd8d8ace0f60.zip
Refcactored GLTFResourceManager: made allocations ref-counted objects
Diffstat (limited to 'AssetLoader/src')
-rw-r--r--AssetLoader/src/GLTFLoader.cpp36
-rw-r--r--AssetLoader/src/GLTFResourceManager.cpp185
2 files changed, 125 insertions, 96 deletions
diff --git a/AssetLoader/src/GLTFLoader.cpp b/AssetLoader/src/GLTFLoader.cpp
index 9fe0cd2..9b690a0 100644
--- a/AssetLoader/src/GLTFLoader.cpp
+++ b/AssetLoader/src/GLTFLoader.cpp
@@ -270,18 +270,6 @@ Model::~Model()
{
if (CacheInfo.pResourceMgr != nullptr)
{
- for (auto& Buff : Buffers)
- {
- if (Buff.CacheAllocation.Region.IsValid())
- CacheInfo.pResourceMgr->FreeBufferSpace(std::move(Buff.CacheAllocation));
- }
-
- for (auto& Tex : Textures)
- {
- if (Tex.CacheAllocation.IsValid())
- CacheInfo.pResourceMgr->FreeTextureSpace(std::move(Tex.CacheAllocation));
- }
-
CacheInfo.pResourceMgr->Release();
}
}
@@ -758,12 +746,12 @@ void Model::LoadTextures(IRenderDevice* pDevice,
{
if (CacheInfo.pResourceMgr != nullptr)
{
- TexInfo.CacheAllocation = CacheInfo.pResourceMgr->AllocateTextureSpace(0, gltf_image.width, gltf_image.height);
- if (TexInfo.CacheAllocation.IsValid())
+ TexInfo.pCacheAllocation = CacheInfo.pResourceMgr->AllocateTextureSpace(0, gltf_image.width, gltf_image.height);
+ if (TexInfo.pCacheAllocation)
{
- const auto& TexDesc = CacheInfo.pResourceMgr->GetTexture(TexInfo.CacheAllocation)->GetDesc();
+ const auto& TexDesc = TexInfo.pCacheAllocation->GetTexDesc();
- const auto& Region = TexInfo.CacheAllocation.Region;
+ const auto& Region = TexInfo.pCacheAllocation->GetRegion();
TexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, Region.x, Region.y, TexDesc.MipLevels);
TexInfo.UVScaleBias.x = static_cast<float>(gltf_image.width) / static_cast<float>(TexDesc.Width);
@@ -844,7 +832,7 @@ void Model::LoadTextures(IRenderDevice* pDevice,
}
}
-void Model::PrepareGPUResources(IDeviceContext* pCtx)
+void Model::PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx)
{
if (!InitData)
return;
@@ -854,7 +842,7 @@ void Model::PrepareGPUResources(IDeviceContext* pCtx)
VERIFY_EXPR(InitData->Textures.size() == Textures.size());
for (Uint32 i = 0; i < Textures.size(); ++i)
{
- auto* pTexture = GetTexture(i);
+ auto* pTexture = GetTexture(i, pDevice, pCtx);
if (!pTexture)
continue;
@@ -895,9 +883,9 @@ void Model::PrepareGPUResources(IDeviceContext* pCtx)
auto UpdateBuffer = [&](BUFFER_ID BuffId, const void* pData, size_t Size) //
{
- auto* pBuffer = GetBuffer(BuffId);
+ auto* pBuffer = GetBuffer(BuffId, pDevice, pCtx);
VERIFY_EXPR(pBuffer != nullptr);
- auto Offset = Buffers[BuffId].CacheAllocation.IsValid() ? Buffers[BuffId].CacheAllocation.Region.UnalignedOffset : 0;
+ auto Offset = Buffers[BuffId].pCacheAllocation ? Buffers[BuffId].pCacheAllocation->GetRegion().UnalignedOffset : 0;
pCtx->UpdateBuffer(pBuffer, static_cast<Uint32>(Offset), static_cast<Uint32>(Size), pData, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
if (Buffers[BuffId].pBuffer != nullptr)
{
@@ -1581,7 +1569,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice,
auto BufferSize = static_cast<Uint32>(VertexData0.size() * sizeof(VertexData0[0]));
if (CacheInfo.pResourceMgr != nullptr)
{
- Buffers[BUFFER_ID_VERTEX0].CacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.VertexBuffer0Idx, BufferSize, 1);
+ Buffers[BUFFER_ID_VERTEX0].pCacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.VertexBuffer0Idx, BufferSize, 1);
}
else
{
@@ -1605,7 +1593,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice,
auto BufferSize = static_cast<Uint32>(VertexData1.size() * sizeof(VertexData1[0]));
if (CacheInfo.pResourceMgr != nullptr)
{
- Buffers[BUFFER_ID_VERTEX1].CacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.VertexBuffer1Idx, BufferSize, 1);
+ Buffers[BUFFER_ID_VERTEX1].pCacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.VertexBuffer1Idx, BufferSize, 1);
}
else
{
@@ -1630,7 +1618,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice,
auto BufferSize = static_cast<Uint32>(IndexBuffer.size() * sizeof(IndexBuffer[0]));
if (CacheInfo.pResourceMgr != nullptr)
{
- Buffers[BUFFER_ID_INDEX].CacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.IndexBufferIdx, BufferSize, 1);
+ Buffers[BUFFER_ID_INDEX].pCacheAllocation = CacheInfo.pResourceMgr->AllocateBufferSpace(CacheInfo.IndexBufferIdx, BufferSize, 1);
}
else
{
@@ -1649,7 +1637,7 @@ void Model::LoadFromFile(IRenderDevice* pDevice,
if (pContext != nullptr)
{
- PrepareGPUResources(pContext);
+ PrepareGPUResources(pDevice, pContext);
}
GetSceneDimensions();
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<std::mutex> 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> GLTFResourceManager::Create(IRenderDevice* pDevice,
- const CreateInfo& CI)
-{
- return RefCntAutoPtr<GLTFResourceManager>{MakeNewRCObj<GLTFResourceManager>()(pDevice, CI)};
-}
+ NewBuffDesc.uiSizeInBytes = static_cast<Uint32>(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<IBuffer> 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::BufferAllocation> GLTFResourceManager::BufferCache::Allocate(Uint32 Size, Uint32 Alignment)
{
- auto& BuffCache = m_Buffers[BufferIndex];
+ std::lock_guard<std::mutex> Lock{m_Mtx};
- std::lock_guard<std::mutex> 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<BufferAllocation>{
+ MakeNewRCObj<BufferAllocation>()(
+ RefCntAutoPtr<GLTFResourceManager>{&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<std::mutex> 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::TextureAllocation> GLTFResourceManager::TextureCache::Allocate(Uint32 Width, Uint32 Height)
+{
+ Width = (Width + m_Granularity - 1) / m_Granularity;
+ Height = (Height + m_Granularity - 1) / m_Granularity;
- std::lock_guard<std::mutex> Lock{TexCache.Mtx};
+ std::lock_guard<std::mutex> 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<TextureAllocation>{
+ MakeNewRCObj<TextureAllocation>()(
+ RefCntAutoPtr<GLTFResourceManager>{&m_Owner},
+ *this,
+ std::move(Region) //
+ ) //
+ };
+ }
+ else
+ {
+ // TODO: handle resize
+ return RefCntAutoPtr<TextureAllocation>{};
}
- 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<std::mutex> 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> GLTFResourceManager::Create(IRenderDevice* pDevice,
+ const CreateInfo& CI)
+{
+ return RefCntAutoPtr<GLTFResourceManager>{MakeNewRCObj<GLTFResourceManager>()(pDevice, CI)};
+}
- std::lock_guard<std::mutex> 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