Skip to content

Commit b0fc9e3

Browse files
GLTF Resource Manager: enabled support of multiple index buffers
1 parent 0d6f88e commit b0fc9e3

File tree

2 files changed

+129
-32
lines changed

2 files changed

+129
-32
lines changed

AssetLoader/interface/GLTFResourceManager.hpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -203,22 +203,31 @@ class ResourceManager final : public ObjectBase<IObject>
203203

204204
/// Returns the combined texture atlas version, i.e. the sum of the texture versions of all
205205
/// atlases.
206-
Uint32 GetTextureVersion();
206+
Uint32 GetTextureVersion() const;
207207

208208
/// Returns the index buffer version.
209209
Uint32 GetIndexBufferVersion() const;
210210

211211
/// Returns the combined vertex pool version, i.e. the sum all vertex pool versions.
212-
Uint32 GetVertexPoolsVersion();
212+
Uint32 GetVertexPoolsVersion() const;
213213

214214
/// Updates the index buffer, if necessary.
215-
IBuffer* UpdateIndexBuffer(IRenderDevice* pDevice, IDeviceContext* pContext);
215+
IBuffer* UpdateIndexBuffer(IRenderDevice* pDevice, IDeviceContext* pContext, Uint32 Index = 0);
216+
217+
/// Updates all index buffers.
218+
void UpdateIndexBuffers(IRenderDevice* pDevice, IDeviceContext* pContext);
219+
220+
/// Returns the number of index buffers.
221+
size_t GetIndexBufferCount() const;
222+
223+
/// Returns the index allocator index.
224+
Uint32 GetIndexAllocatorIndex(IBufferSuballocator* pAllocator) const;
216225

217226
/// Updates the vertex buffers, if necessary.
218227
void UpdateVertexBuffers(IRenderDevice* pDevice, IDeviceContext* pContext);
219228

220229
/// Returns a pointer to the index buffer.
221-
IBuffer* GetIndexBuffer() const;
230+
IBuffer* GetIndexBuffer(Uint32 Index = 0) const;
222231

223232
/// Returns a pointer to the vertex pool for the given key and index.
224233
/// If the pool does not exist, null is returned.
@@ -229,14 +238,14 @@ class ResourceManager final : public ObjectBase<IObject>
229238
IVertexPool* GetVertexPool(const VertexLayoutKey& Key, Uint32 Index = 0);
230239

231240
/// Returns the number of vertex pools for the given key.
232-
size_t GetVertexPoolCount(const VertexLayoutKey& Key);
241+
size_t GetVertexPoolCount(const VertexLayoutKey& Key) const;
233242

234243
/// Returns all vertex pools for the given key.
235-
std::vector<IVertexPool*> GetVertexPools(const VertexLayoutKey& Key);
244+
std::vector<IVertexPool*> GetVertexPools(const VertexLayoutKey& Key) const;
236245

237246
/// Returns index of the vertex pool with the give key.
238247
/// If the pool does not exist, InvalidIndex (0xFFFFFFFF) is returned.
239-
Uint32 GetVertexPoolIndex(const VertexLayoutKey& Key, IVertexPool* pPool);
248+
Uint32 GetVertexPoolIndex(const VertexLayoutKey& Key, IVertexPool* pPool) const;
240249

241250
/// Updates the atlas texture for the given format.
242251
/// If the atlas does not exist, null is returned.
@@ -345,7 +354,8 @@ class ResourceManager final : public ObjectBase<IObject>
345354
IRenderDevice* pDevice,
346355
const CreateInfo& CI);
347356

348-
RefCntAutoPtr<IVertexPool> CreateVertexPoolForLayout(const VertexLayoutKey& Key) const;
357+
RefCntAutoPtr<IVertexPool> CreateVertexPoolForLayout(const VertexLayoutKey& Key) const;
358+
RefCntAutoPtr<IBufferSuballocator> CreateIndexBufferAllocator(IRenderDevice* pDevice) const;
349359

350360
private:
351361
const RENDER_DEVICE_TYPE m_DeviceType;
@@ -356,12 +366,15 @@ class ResourceManager final : public ObjectBase<IObject>
356366
const std::string m_DefaultAtlasName;
357367
DynamicTextureAtlasCreateInfo m_DefaultAtlasDesc;
358368

359-
RefCntAutoPtr<IBufferSuballocator> m_pIndexBufferAllocator;
369+
const BufferSuballocatorCreateInfo m_IndexAllocatorCI;
370+
371+
mutable std::mutex m_IndexAllocatorsMtx;
372+
std::vector<RefCntAutoPtr<IBufferSuballocator>> m_IndexAllocators;
360373

361374
std::unordered_map<VertexLayoutKey, VertexPoolCreateInfoX, VertexLayoutKey::Hasher> m_VertexPoolCIs;
362375

363376
using VertexPoolsHashMapType = std::unordered_map<VertexLayoutKey, std::vector<RefCntAutoPtr<IVertexPool>>, VertexLayoutKey::Hasher>;
364-
std::mutex m_VertexPoolsMtx;
377+
mutable std::mutex m_VertexPoolsMtx;
365378
VertexPoolsHashMapType m_VertexPools;
366379

367380
using AtlasesHashMapType = std::unordered_map<TEXTURE_FORMAT, RefCntAutoPtr<IDynamicTextureAtlas>, std::hash<Uint32>>;

AssetLoader/src/GLTFResourceManager.cpp

Lines changed: 106 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ ResourceManager::ResourceManager(IReferenceCounters* pRefCounters,
6161
m_DefaultVertPoolName{CI.DefaultPoolDesc.Name != nullptr ? CI.DefaultPoolDesc.Name : "GLTF vertex pool"},
6262
m_DefaultVertPoolDesc{CI.DefaultPoolDesc},
6363
m_DefaultAtlasName{CI.DefaultAtlasDesc.Desc.Name != nullptr ? CI.DefaultAtlasDesc.Desc.Name : "GLTF texture atlas"},
64-
m_DefaultAtlasDesc{CI.DefaultAtlasDesc}
64+
m_DefaultAtlasDesc{CI.DefaultAtlasDesc},
65+
m_IndexAllocatorCI{CI.IndexAllocatorCI}
6566
{
6667
m_DefaultVertPoolDesc.Name = m_DefaultVertPoolName.c_str();
6768
m_DefaultAtlasDesc.Desc.Name = m_DefaultAtlasName.c_str();
6869

69-
CreateBufferSuballocator(pDevice, CI.IndexAllocatorCI, &m_pIndexBufferAllocator);
70-
VERIFY_EXPR(m_pIndexBufferAllocator);
70+
m_IndexAllocators.emplace_back(CreateIndexBufferAllocator(pDevice));
7171

7272
if (m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_TEX_2D &&
7373
m_DefaultAtlasDesc.Desc.Type != RESOURCE_DIM_TEX_2D_ARRAY &&
@@ -203,16 +203,36 @@ RefCntAutoPtr<ITextureAtlasSuballocation> ResourceManager::AllocateTextureSpace(
203203
return pAllocation;
204204
}
205205

206+
RefCntAutoPtr<IBufferSuballocator> ResourceManager::CreateIndexBufferAllocator(IRenderDevice* pDevice) const
207+
{
208+
RefCntAutoPtr<IBufferSuballocator> pIndexBufferAllocator;
209+
CreateBufferSuballocator(pDevice, m_IndexAllocatorCI, &pIndexBufferAllocator);
210+
VERIFY_EXPR(pIndexBufferAllocator);
211+
212+
return pIndexBufferAllocator;
213+
}
206214

207215
RefCntAutoPtr<IBufferSuballocation> ResourceManager::AllocateIndices(Uint32 Size, Uint32 Alignment)
208216
{
209217
RefCntAutoPtr<IBufferSuballocation> pIndices;
210-
if (!m_pIndexBufferAllocator)
218+
for (Uint32 AllocatorIdx = 0; !pIndices; ++AllocatorIdx)
211219
{
212-
UNEXPECTED("Index buffer allocator is not initialized");
213-
return pIndices;
220+
IBufferSuballocator* pAllocator = nullptr;
221+
{
222+
std::lock_guard<std::mutex> Guard{m_IndexAllocatorsMtx};
223+
if (AllocatorIdx == m_IndexAllocators.size())
224+
{
225+
m_IndexAllocators.emplace_back(CreateIndexBufferAllocator(nullptr));
226+
}
227+
pAllocator = m_IndexAllocators[AllocatorIdx];
228+
}
229+
230+
if (pAllocator == nullptr)
231+
break;
232+
233+
pAllocator->Allocate(Size, Alignment, &pIndices);
214234
}
215-
m_pIndexBufferAllocator->Allocate(Size, Alignment, &pIndices);
235+
216236
return pIndices;
217237
}
218238

@@ -304,7 +324,7 @@ RefCntAutoPtr<IVertexPoolAllocation> ResourceManager::AllocateVertices(const Ver
304324
}
305325

306326

307-
Uint32 ResourceManager::GetTextureVersion()
327+
Uint32 ResourceManager::GetTextureVersion() const
308328
{
309329
Uint32 Version = 0;
310330

@@ -318,10 +338,16 @@ Uint32 ResourceManager::GetTextureVersion()
318338

319339
Uint32 ResourceManager::GetIndexBufferVersion() const
320340
{
321-
return m_pIndexBufferAllocator ? m_pIndexBufferAllocator->GetVersion() : 0;
341+
Uint32 Version = 0;
342+
343+
std::lock_guard<std::mutex> Guard{m_IndexAllocatorsMtx};
344+
for (const auto& pAllocator : m_IndexAllocators)
345+
Version += pAllocator ? pAllocator->GetVersion() : 0;
346+
347+
return Version;
322348
}
323349

324-
Uint32 ResourceManager::GetVertexPoolsVersion()
350+
Uint32 ResourceManager::GetVertexPoolsVersion() const
325351
{
326352
Uint32 Version = 0;
327353

@@ -334,18 +360,67 @@ Uint32 ResourceManager::GetVertexPoolsVersion()
334360
return Version;
335361
}
336362

337-
IBuffer* ResourceManager::UpdateIndexBuffer(IRenderDevice* pDevice, IDeviceContext* pContext)
363+
IBuffer* ResourceManager::UpdateIndexBuffer(IRenderDevice* pDevice, IDeviceContext* pContext, Uint32 Index)
338364
{
339-
return m_pIndexBufferAllocator ?
340-
m_pIndexBufferAllocator->Update(pDevice, pContext) :
365+
IBufferSuballocator* pIndexBufferAllocator = nullptr;
366+
{
367+
std::lock_guard<std::mutex> Guard{m_IndexAllocatorsMtx};
368+
pIndexBufferAllocator = Index < m_IndexAllocators.size() ? m_IndexAllocators[Index].RawPtr() : nullptr;
369+
}
370+
371+
return pIndexBufferAllocator != nullptr ?
372+
pIndexBufferAllocator->Update(pDevice, pContext) :
341373
nullptr;
342374
}
343375

344-
IBuffer* ResourceManager::GetIndexBuffer() const
376+
void ResourceManager::UpdateIndexBuffers(IRenderDevice* pDevice, IDeviceContext* pContext)
345377
{
346-
return m_pIndexBufferAllocator ?
347-
m_pIndexBufferAllocator->GetBuffer() :
348-
nullptr;
378+
Uint32 Index = 0;
379+
for (;; ++Index)
380+
{
381+
IBufferSuballocator* pIndexBufferAllocator = nullptr;
382+
{
383+
std::lock_guard<std::mutex> Guard{m_IndexAllocatorsMtx};
384+
if (Index >= m_IndexAllocators.size())
385+
break;
386+
pIndexBufferAllocator = m_IndexAllocators[Index];
387+
}
388+
389+
if (pIndexBufferAllocator != nullptr)
390+
{
391+
pIndexBufferAllocator->Update(pDevice, pContext);
392+
}
393+
}
394+
}
395+
396+
IBuffer* ResourceManager::GetIndexBuffer(Uint32 Index) const
397+
{
398+
std::lock_guard<std::mutex> Guard{m_IndexAllocatorsMtx};
399+
400+
if (Index >= m_IndexAllocators.size())
401+
return nullptr;
402+
403+
if (const auto& pAllocator = m_IndexAllocators[Index])
404+
return pAllocator->GetBuffer();
405+
else
406+
return nullptr;
407+
}
408+
409+
size_t ResourceManager::GetIndexBufferCount() const
410+
{
411+
std::lock_guard<std::mutex> Guard{m_IndexAllocatorsMtx};
412+
return m_IndexAllocators.size();
413+
}
414+
415+
Uint32 ResourceManager::GetIndexAllocatorIndex(IBufferSuballocator* pAllocator) const
416+
{
417+
std::lock_guard<std::mutex> Guard{m_IndexAllocatorsMtx};
418+
for (Uint32 i = 0; i < m_IndexAllocators.size(); ++i)
419+
{
420+
if (pAllocator == m_IndexAllocators[i])
421+
return i;
422+
}
423+
return ~0u;
349424
}
350425

351426
void ResourceManager::UpdateVertexBuffers(IRenderDevice* pDevice, IDeviceContext* pContext)
@@ -369,15 +444,15 @@ IVertexPool* ResourceManager::GetVertexPool(const VertexLayoutKey& Key, Uint32 I
369444
return nullptr;
370445
}
371446

372-
size_t ResourceManager::GetVertexPoolCount(const VertexLayoutKey& Key)
447+
size_t ResourceManager::GetVertexPoolCount(const VertexLayoutKey& Key) const
373448
{
374449
std::lock_guard<std::mutex> Guard{m_VertexPoolsMtx};
375450

376451
const auto pools_it = m_VertexPools.find(Key);
377452
return pools_it != m_VertexPools.end() ? pools_it->second.size() : 0;
378453
}
379454

380-
std::vector<IVertexPool*> ResourceManager::GetVertexPools(const VertexLayoutKey& Key)
455+
std::vector<IVertexPool*> ResourceManager::GetVertexPools(const VertexLayoutKey& Key) const
381456
{
382457
std::vector<IVertexPool*> Pools;
383458
{
@@ -394,7 +469,7 @@ std::vector<IVertexPool*> ResourceManager::GetVertexPools(const VertexLayoutKey&
394469
return Pools;
395470
}
396471

397-
Uint32 ResourceManager::GetVertexPoolIndex(const VertexLayoutKey& Key, IVertexPool* pPool)
472+
Uint32 ResourceManager::GetVertexPoolIndex(const VertexLayoutKey& Key, IVertexPool* pPool) const
398473
{
399474
std::lock_guard<std::mutex> Guard{m_VertexPoolsMtx};
400475

@@ -487,8 +562,17 @@ Uint32 ResourceManager::GetAllocationAlignment(TEXTURE_FORMAT Fmt, Uint32 Width,
487562
BufferSuballocatorUsageStats ResourceManager::GetIndexBufferUsageStats()
488563
{
489564
BufferSuballocatorUsageStats Stats;
490-
if (m_pIndexBufferAllocator)
491-
m_pIndexBufferAllocator->GetUsageStats(Stats);
565+
566+
std::lock_guard<std::mutex> Guard{m_IndexAllocatorsMtx};
567+
for (const auto& pAllocator : m_IndexAllocators)
568+
{
569+
if (pAllocator)
570+
{
571+
BufferSuballocatorUsageStats AllocatorStats;
572+
pAllocator->GetUsageStats(AllocatorStats);
573+
Stats += AllocatorStats;
574+
}
575+
}
492576
return Stats;
493577
}
494578

0 commit comments

Comments
 (0)