summaryrefslogtreecommitdiffstats
path: root/AssetLoader
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-12-05 17:19:28 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-12-05 17:19:28 +0000
commite3bad5a7fcedc170a10aed3ee644310ec8c982fe (patch)
tree1ebedbfb4a1a415bc9615ded4f46fa1e8e694fc6 /AssetLoader
parentGLTF Loader: fixed names of Material::ALPHA_MODE enum members (diff)
downloadDiligentTools-e3bad5a7fcedc170a10aed3ee644310ec8c982fe.tar.gz
DiligentTools-e3bad5a7fcedc170a10aed3ee644310ec8c982fe.zip
GLTF Resource manager: implemented texture array resizing
Diffstat (limited to 'AssetLoader')
-rw-r--r--AssetLoader/interface/GLTFLoader.hpp12
-rw-r--r--AssetLoader/interface/GLTFResourceManager.hpp96
-rw-r--r--AssetLoader/src/GLTFLoader.cpp23
-rw-r--r--AssetLoader/src/GLTFResourceManager.cpp188
4 files changed, 244 insertions, 75 deletions
diff --git a/AssetLoader/interface/GLTFLoader.hpp b/AssetLoader/interface/GLTFLoader.hpp
index ddf5625..68747c5 100644
--- a/AssetLoader/interface/GLTFLoader.hpp
+++ b/AssetLoader/interface/GLTFLoader.hpp
@@ -61,6 +61,12 @@ struct GLTFCacheInfo
Uint8 IndexBufferIdx = 0;
Uint8 VertexBuffer0Idx = 0;
Uint8 VertexBuffer1Idx = 0;
+
+ TEXTURE_FORMAT BaseColorFormat = TEX_FORMAT_RGBA8_UNORM;
+ TEXTURE_FORMAT PhysicalDescFormat = TEX_FORMAT_RGBA8_UNORM;
+ TEXTURE_FORMAT NormalFormat = TEX_FORMAT_RGBA8_UNORM;
+ TEXTURE_FORMAT OcclusionFormat = TEX_FORMAT_RGBA8_UNORM;
+ TEXTURE_FORMAT EmissiveFormat = TEX_FORMAT_RGBA8_UNORM;
};
struct Material
@@ -388,6 +394,11 @@ struct Model
return Textures[Index].UVScaleBias;
}
+ float GetSlice(Uint32 Index)
+ {
+ return Textures[Index].Slice;
+ }
+
private:
void LoadFromFile(IRenderDevice* pDevice,
IDeviceContext* pContext,
@@ -433,6 +444,7 @@ private:
{
RefCntAutoPtr<ITexture> pTexture;
float4 UVScaleBias{1, 1, 0, 0};
+ float Slice = 0;
RefCntAutoPtr<GLTFResourceManager::TextureAllocation> pCacheAllocation;
diff --git a/AssetLoader/interface/GLTFResourceManager.hpp b/AssetLoader/interface/GLTFResourceManager.hpp
index e0b007d..a6c2a82 100644
--- a/AssetLoader/interface/GLTFResourceManager.hpp
+++ b/AssetLoader/interface/GLTFResourceManager.hpp
@@ -30,6 +30,7 @@
#include <mutex>
#include <vector>
#include <unordered_map>
+#include <atomic>
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
@@ -97,6 +98,7 @@ public:
TextureCache& ParentCache,
Uint32 Width,
Uint32 Height,
+ Uint32 Slice,
DynamicAtlasManager::Region&& Region) :
// clang-format off
ObjectBase<IObject>{pRefCounters},
@@ -104,6 +106,7 @@ public:
m_ParentCache {ParentCache},
m_Width {Width},
m_Height {Height},
+ m_Slice {Slice},
m_Region {std::move(Region)}
// clang-format on
{
@@ -112,7 +115,7 @@ public:
~TextureAllocation()
{
- m_ParentCache.FreeAllocation(std::move(m_Region));
+ m_ParentCache.FreeAllocation(m_Slice, std::move(m_Region));
}
ITexture* GetTexture(IRenderDevice* pDevice, IDeviceContext* pContext) const
@@ -132,19 +135,24 @@ public:
Uint32 GetWidth() const { return m_Width; }
Uint32 GetHeight() const { return m_Height; }
+ Uint32 GetSlice() const { return m_Slice; }
private:
RefCntAutoPtr<GLTFResourceManager> 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 Granularity = 128;
+ Uint32 ExtraSliceCount = 2;
+ Uint32 MaxSlices = 2048;
};
struct CreateInfo
{
@@ -153,6 +161,10 @@ public:
const TextureCacheAttribs* Textures = nullptr; // [NumTextures]
Uint32 NumTextures = 0;
+
+ TextureDesc DefaultTexDesc;
+
+ Uint32 DefaultExtraSliceCount = 1;
};
static RefCntAutoPtr<GLTFResourceManager> Create(IRenderDevice* pDevice,
@@ -163,10 +175,32 @@ public:
return m_Buffers[BufferIndex].Allocate(Size, Alignment);
}
- RefCntAutoPtr<TextureAllocation> AllocateTextureSpace(Uint32 TextureIndex, Uint32 Width, Uint32 Height, const char* CacheId = nullptr);
+ RefCntAutoPtr<TextureAllocation> AllocateTextureSpace(TEXTURE_FORMAT Fmt, Uint32 Width, Uint32 Height, const char* CacheId = nullptr);
RefCntAutoPtr<TextureAllocation> FindAllocation(const char* CacheId);
+ Uint32 GetResourceVersion() const
+ {
+ return m_ResourceVersion.load();
+ }
+
+ IBuffer* GetBuffer(Uint32 Index, IRenderDevice* pDevice, IDeviceContext* pContext)
+ {
+ return m_Buffers[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
+ {
+ std::lock_guard<std::mutex> Lock{m_TexturesMtx};
+ cache_it = m_Textures.find(Fmt);
+ if (cache_it == m_Textures.end())
+ return nullptr;
+ }
+
+ return cache_it->second.GetTexture(pDevice, pContext);
+ }
+
private:
template <typename AllocatorType, typename ObjectType>
friend class MakeNewRCObj;
@@ -227,44 +261,72 @@ private:
TextureCache(TextureCache&& Cache) noexcept :
// clang-format off
- m_Owner {Cache.m_Owner},
- m_TexDesc {m_TexDesc},
- m_TexName {std::move(m_TexName)},
- m_Granularity{Cache.m_Granularity},
- m_Mgr {std::move(Cache.m_Mgr)},
- m_pTexture {std::move(Cache.m_pTexture)}
+ 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_TexDesc.Name = m_TexName.c_str();
+ m_Attribs.Desc.Name = m_TexName.c_str();
}
ITexture* GetTexture(IRenderDevice* pDevice, IDeviceContext* pContext);
const TextureDesc& GetTexDesc() const
{
- return m_TexDesc;
+ return m_Attribs.Desc;
}
RefCntAutoPtr<TextureAllocation> Allocate(Uint32 Width, Uint32 Height);
- void FreeAllocation(DynamicAtlasManager::Region&& Allocation);
+ void FreeAllocation(Uint32 Slice, DynamicAtlasManager::Region&& Allocation);
private:
GLTFResourceManager& m_Owner;
- TextureDesc m_TexDesc;
+ TextureCacheAttribs m_Attribs;
+
std::string m_TexName;
- const Uint32 m_Granularity;
+ struct SliceManager
+ {
+ SliceManager(Uint32 Width, Uint32 Height) :
+ Mgr{Width, Height}
+ {}
+
+ DynamicAtlasManager::Region Allocate(Uint32 Width, Uint32 Height)
+ {
+ std::lock_guard<std::mutex> Lock{Mtx};
+ return Mgr.Allocate(Width, Height);
+ }
+ void Free(DynamicAtlasManager::Region&& Region)
+ {
+ std::lock_guard<std::mutex> Lock{Mtx};
+ Mgr.Free(std::move(Region));
+ }
+
+ private:
+ std::mutex Mtx;
+ DynamicAtlasManager Mgr;
+ };
+ std::mutex m_SlicesMtx;
+ std::vector<std::unique_ptr<SliceManager>> m_Slices;
- std::mutex m_Mtx;
- DynamicAtlasManager m_Mgr;
RefCntAutoPtr<ITexture> m_pTexture;
};
- std::vector<TextureCache> m_Textures;
+
+ TextureDesc m_DefaultTexDesc;
+ const Uint32 m_DefaultExtraSliceCount;
+
+
+ std::mutex m_TexturesMtx;
+ std::unordered_map<TEXTURE_FORMAT, TextureCache> m_Textures;
std::mutex m_AllocationsMtx;
std::unordered_map<std::string, RefCntWeakPtr<TextureAllocation>> m_Allocations;
+
+ std::atomic_uint32_t m_ResourceVersion = {};
};
} // namespace Diligent
diff --git a/AssetLoader/src/GLTFLoader.cpp b/AssetLoader/src/GLTFLoader.cpp
index addf01e..40b6f7d 100644
--- a/AssetLoader/src/GLTFLoader.cpp
+++ b/AssetLoader/src/GLTFLoader.cpp
@@ -699,6 +699,8 @@ void Model::LoadTextures(IRenderDevice* pDevice,
TexInfo.UVScaleBias.y = static_cast<float>(gltf_image.height) / static_cast<float>(TexDesc.Height);
TexInfo.UVScaleBias.z = static_cast<float>(Region.x) / static_cast<float>(TexDesc.Width);
TexInfo.UVScaleBias.w = static_cast<float>(Region.y) / static_cast<float>(TexDesc.Height);
+
+ TexInfo.Slice = static_cast<float>(TexInfo.pCacheAllocation->GetSlice());
}
}
else if (pTextureCache != nullptr)
@@ -749,7 +751,7 @@ void Model::LoadTextures(IRenderDevice* pDevice,
{
if (CacheInfo.pResourceMgr != nullptr)
{
- TexInfo.pCacheAllocation = CacheInfo.pResourceMgr->AllocateTextureSpace(0, gltf_image.width, gltf_image.height);
+ TexInfo.pCacheAllocation = CacheInfo.pResourceMgr->AllocateTextureSpace(TEX_FORMAT_RGBA8_UNORM, gltf_image.width, gltf_image.height);
if (TexInfo.pCacheAllocation)
{
const auto& TexDesc = TexInfo.pCacheAllocation->GetTexDesc();
@@ -761,6 +763,8 @@ void Model::LoadTextures(IRenderDevice* pDevice,
TexInfo.UVScaleBias.y = static_cast<float>(gltf_image.height) / static_cast<float>(TexDesc.Height);
TexInfo.UVScaleBias.z = static_cast<float>(Region.x) / static_cast<float>(TexDesc.Width);
TexInfo.UVScaleBias.w = static_cast<float>(Region.y) / static_cast<float>(TexDesc.Height);
+
+ TexInfo.Slice = static_cast<float>(TexInfo.pCacheAllocation->GetSlice());
}
}
else
@@ -779,6 +783,7 @@ 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);
}
@@ -860,7 +865,7 @@ void Model::PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx)
const auto& Level = Levels[mip];
TextureSubResData SubresData{Level.Data.data(), Level.Stride};
- pCtx->UpdateTexture(pTexture, mip, 0, Level.UpdateBox, SubresData, RESOURCE_STATE_TRANSITION_MODE_NONE, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+ pCtx->UpdateTexture(pTexture, mip, static_cast<Uint32>(Textures[i].Slice), Level.UpdateBox, SubresData, RESOURCE_STATE_TRANSITION_MODE_NONE, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
}
if (Levels.size() == 1 && pTexture->GetDesc().MipLevels > 1)
@@ -993,17 +998,18 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model)
const Material::TEXTURE_ID TextureId;
float& UVSelector;
float4& UVScaleBias;
+ float& Slice;
const char* const TextureName;
const tinygltf::ParameterMap& Params;
};
// clang-format off
std::array<TextureParameterInfo, 5> TextureParams =
{
- TextureParameterInfo{Material::TEXTURE_ID_BASE_COLOR, Mat.Attribs.BaseColorUVSelector, Mat.Attribs.BaseColorUVScaleBias, "baseColorTexture", gltf_mat.values},
- TextureParameterInfo{Material::TEXTURE_ID_PHYSICAL_DESC, Mat.Attribs.PhysicalDescriptorUVSelector, Mat.Attribs.PhysicalDescriptorUVScaleBias, "metallicRoughnessTexture", gltf_mat.values},
- TextureParameterInfo{Material::TEXTURE_ID_NORMAL_MAP, Mat.Attribs.NormalUVSelector, Mat.Attribs.NormalUVScaleBias, "normalTexture", gltf_mat.additionalValues},
- TextureParameterInfo{Material::TEXTURE_ID_OCCLUSION, Mat.Attribs.OcclusionUVSelector, Mat.Attribs.OcclusionUVScaleBias, "occlusionTexture", gltf_mat.additionalValues},
- TextureParameterInfo{Material::TEXTURE_ID_EMISSIVE, Mat.Attribs.EmissiveUVSelector, Mat.Attribs.EmissiveUVScaleBias, "emissiveTexture", gltf_mat.additionalValues}
+ TextureParameterInfo{Material::TEXTURE_ID_BASE_COLOR, Mat.Attribs.BaseColorUVSelector, Mat.Attribs.BaseColorUVScaleBias, Mat.Attribs.BaseColorSlice, "baseColorTexture", gltf_mat.values},
+ TextureParameterInfo{Material::TEXTURE_ID_PHYSICAL_DESC, Mat.Attribs.PhysicalDescriptorUVSelector, Mat.Attribs.PhysicalDescriptorUVScaleBias, Mat.Attribs.PhysicalDescriptorSlice, "metallicRoughnessTexture", gltf_mat.values},
+ TextureParameterInfo{Material::TEXTURE_ID_NORMAL_MAP, Mat.Attribs.NormalUVSelector, Mat.Attribs.NormalUVScaleBias, Mat.Attribs.NormalSlice, "normalTexture", gltf_mat.additionalValues},
+ TextureParameterInfo{Material::TEXTURE_ID_OCCLUSION, Mat.Attribs.OcclusionUVSelector, Mat.Attribs.OcclusionUVScaleBias, Mat.Attribs.OcclusionSlice, "occlusionTexture", gltf_mat.additionalValues},
+ TextureParameterInfo{Material::TEXTURE_ID_EMISSIVE, Mat.Attribs.EmissiveUVSelector, Mat.Attribs.EmissiveUVScaleBias, Mat.Attribs.EmissiveSlice, "emissiveTexture", gltf_mat.additionalValues}
};
// clang-format on
@@ -1125,7 +1131,10 @@ 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);
+ }
}
Materials.push_back(Mat);
diff --git a/AssetLoader/src/GLTFResourceManager.cpp b/AssetLoader/src/GLTFResourceManager.cpp
index dc4febf..fa1008b 100644
--- a/AssetLoader/src/GLTFResourceManager.cpp
+++ b/AssetLoader/src/GLTFResourceManager.cpp
@@ -91,71 +91,139 @@ 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}
+ m_Attribs{CacheCI}
{
- m_TexDesc.Name = m_TexName.c_str();
+ m_Attribs.Desc.Name = m_TexName.c_str();
- 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, ")");
+ 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, ")");
- pDevice->CreateTexture(CacheCI.Desc, nullptr, &m_pTexture);
+ if (pDevice != nullptr)
+ {
+ pDevice->CreateTexture(Desc, nullptr, &m_pTexture);
+ }
}
ITexture* GLTFResourceManager::TextureCache::GetTexture(IRenderDevice* pDevice, IDeviceContext* pContext)
{
- // TODO: handle resizes
+ RefCntAutoPtr<ITexture> pNewTexture;
+ {
+ std::lock_guard<std::mutex> Lock{m_SlicesMtx};
+ if (!m_pTexture || m_pTexture->GetDesc().ArraySize < m_Slices.size())
+ {
+ m_Attribs.Desc.ArraySize = static_cast<Uint32>(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::TextureAllocation> GLTFResourceManager::TextureCache::Allocate(Uint32 Width, Uint32 Height)
{
VERIFY_EXPR(Width > 0 && Height > 0);
-
- std::lock_guard<std::mutex> Lock{m_Mtx};
-
- auto Region = m_Mgr.Allocate((Width + m_Granularity - 1) / m_Granularity, (Height + m_Granularity - 1) / m_Granularity);
- if (!Region.IsEmpty())
+ const auto& TexDesc = m_Attribs.Desc;
+ if (Width > TexDesc.Width || Height > TexDesc.Height)
{
- 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,
- Width,
- Height,
- std::move(Region) //
- ) //
- };
+ LOG_ERROR_MESSAGE("Requested size ", Width, " x ", Height, " exceeds the texture size ", TexDesc.Width, " x ", TexDesc.Height);
+ return {};
}
- else
+
+ const auto Granularity = m_Attribs.Granularity;
+ for (Uint32 Slice = 0; Slice < m_Attribs.MaxSlices; ++Slice)
{
- // TODO: handle resize
- return RefCntAutoPtr<TextureAllocation>{};
+ SliceManager* pSliceMgr = nullptr;
+ {
+ std::lock_guard<std::mutex> 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<TextureAllocation>{
+ MakeNewRCObj<TextureAllocation>()(
+ RefCntAutoPtr<GLTFResourceManager>{&m_Owner},
+ *this,
+ Width,
+ Height,
+ Slice,
+ std::move(Region) //
+ ) //
+ };
+ }
}
+
+ return RefCntAutoPtr<TextureAllocation>{};
}
-void GLTFResourceManager::TextureCache::FreeAllocation(DynamicAtlasManager::Region&& Allocation)
+void GLTFResourceManager::TextureCache::FreeAllocation(Uint32 Slice, DynamicAtlasManager::Region&& Allocation)
{
- 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));
+ 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<std::mutex> Lock{m_SlicesMtx};
+ pSliceMgr = m_Slices[Slice].get();
+ }
+ pSliceMgr->Free(std::move(Allocation));
}
@@ -169,7 +237,9 @@ RefCntAutoPtr<GLTFResourceManager> GLTFResourceManager::Create(IRenderDevice*
GLTFResourceManager::GLTFResourceManager(IReferenceCounters* pRefCounters,
IRenderDevice* pDevice,
const CreateInfo& CI) :
- TBase{pRefCounters}
+ TBase{pRefCounters},
+ m_DefaultTexDesc{CI.DefaultTexDesc},
+ m_DefaultExtraSliceCount{CI.DefaultExtraSliceCount}
{
m_Buffers.reserve(CI.NumBuffers);
for (Uint32 i = 0; i < CI.NumBuffers; ++i)
@@ -180,7 +250,7 @@ GLTFResourceManager::GLTFResourceManager(IReferenceCounters* pRefCounters,
m_Textures.reserve(CI.NumTextures);
for (Uint32 i = 0; i < CI.NumTextures; ++i)
{
- m_Textures.emplace_back(*this, pDevice, CI.Textures[i]);
+ m_Textures.emplace(CI.Textures[i].Desc.Format, TextureCache{*this, pDevice, CI.Textures[i]});
}
}
@@ -202,10 +272,10 @@ RefCntAutoPtr<GLTFResourceManager::TextureAllocation> GLTFResourceManager::FindA
}
RefCntAutoPtr<GLTFResourceManager::TextureAllocation> GLTFResourceManager::AllocateTextureSpace(
- Uint32 TextureIndex,
- Uint32 Width,
- Uint32 Height,
- const char* CacheId)
+ TEXTURE_FORMAT Fmt,
+ Uint32 Width,
+ Uint32 Height,
+ const char* CacheId)
{
RefCntAutoPtr<TextureAllocation> pAllocation;
if (CacheId != nullptr && *CacheId != 0)
@@ -215,7 +285,23 @@ RefCntAutoPtr<GLTFResourceManager::TextureAllocation> GLTFResourceManager::Alloc
if (!pAllocation)
{
- pAllocation = m_Textures[TextureIndex].Allocate(Width, Height);
+ decltype(m_Textures)::iterator cache_it; // NB: can't initialize it without locking the mutex
+ {
+ std::lock_guard<std::mutex> Lock{m_TexturesMtx};
+ cache_it = m_Textures.find(Fmt);
+ if (cache_it == m_Textures.end())
+ {
+ TextureCacheAttribs NewCacheAttribs;
+ NewCacheAttribs.Desc = m_DefaultTexDesc;
+
+ NewCacheAttribs.Desc.Name = "GLTF Texture cache";
+ NewCacheAttribs.Desc.Format = Fmt;
+
+ cache_it = m_Textures.emplace(Fmt, TextureCache{*this, nullptr, NewCacheAttribs}).first;
+ }
+ }
+ // Allocate outside of mutex
+ pAllocation = cache_it->second.Allocate(Width, Height);
}
if (CacheId != nullptr && *CacheId != 0)