summaryrefslogtreecommitdiffstats
path: root/AssetLoader/src/GLTFResourceManager.cpp
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-11-30 19:21:07 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-11-30 19:21:07 +0000
commit70129fda4c75f7b8e6812190631e35a56eb2b9d2 (patch)
tree68e903d3a6bd869277174e727c1d321107aa9327 /AssetLoader/src/GLTFResourceManager.cpp
parentGLTF Loader: added texture coordinate scale and bias for use in texture atlas (diff)
downloadDiligentTools-70129fda4c75f7b8e6812190631e35a56eb2b9d2.tar.gz
DiligentTools-70129fda4c75f7b8e6812190631e35a56eb2b9d2.zip
GLTF loader: initial implementation of GLTF resource cache
Diffstat (limited to 'AssetLoader/src/GLTFResourceManager.cpp')
-rw-r--r--AssetLoader/src/GLTFResourceManager.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/AssetLoader/src/GLTFResourceManager.cpp b/AssetLoader/src/GLTFResourceManager.cpp
new file mode 100644
index 0000000..54724ea
--- /dev/null
+++ b/AssetLoader/src/GLTFResourceManager.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2019-2020 Diligent Graphics LLC
+ * Copyright 2015-2019 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#include "GLTFResourceManager.hpp"
+#include "DefaultRawMemoryAllocator.hpp"
+#include "Align.hpp"
+
+namespace Diligent
+{
+
+GLTFResourceManager::BufferCache::BufferCache(IRenderDevice* pDevice, const BufferDesc& BuffDesc) :
+ Mgr{BuffDesc.uiSizeInBytes, DefaultRawMemoryAllocator::GetAllocator()}
+{
+ pDevice->CreateBuffer(BuffDesc, nullptr, &pBuffer);
+}
+
+GLTFResourceManager::TextureCache::TextureCache(IRenderDevice* pDevice, const TextureCacheAttribs& CacheCI) :
+ Mgr{CacheCI.Desc.Width / CacheCI.Granularity, CacheCI.Desc.Height / CacheCI.Granularity},
+ Granularity{CacheCI.Granularity}
+{
+ 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, ")");
+
+ pDevice->CreateTexture(CacheCI.Desc, nullptr, &pTexture);
+}
+
+RefCntAutoPtr<GLTFResourceManager> GLTFResourceManager::Create(IRenderDevice* pDevice,
+ const CreateInfo& CI)
+{
+ return RefCntAutoPtr<GLTFResourceManager>{MakeNewRCObj<GLTFResourceManager>()(pDevice, CI)};
+}
+
+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]);
+ }
+
+ m_Textures.reserve(CI.NumTextures);
+ for (Uint32 i = 0; i < CI.NumTextures; ++i)
+ {
+ m_Textures.emplace_back(pDevice, CI.Textures[i]);
+ }
+}
+
+GLTFResourceManager::BufferAllocation GLTFResourceManager::AllocateBufferSpace(Uint32 BufferIndex, Uint32 Size, Uint32 Alignment)
+{
+ auto& BuffCache = m_Buffers[BufferIndex];
+
+ std::lock_guard<std::mutex> Lock{BuffCache.Mtx};
+
+ BufferAllocation Allocation;
+ Allocation.BufferIndex = BufferIndex;
+ Allocation.Region = BuffCache.Mgr.Allocate(Size, Alignment);
+ return Allocation;
+}
+
+void GLTFResourceManager::FreeBufferSpace(BufferAllocation&& Allocation)
+{
+ auto& BuffCache = m_Buffers[Allocation.BufferIndex];
+
+ std::lock_guard<std::mutex> Lock{BuffCache.Mtx};
+ BuffCache.Mgr.Free(std::move(Allocation.Region));
+}
+
+GLTFResourceManager::TextureAllocation GLTFResourceManager::AllocateTextureSpace(Uint32 TextureIndex, Uint32 Width, Uint32 Height)
+{
+ auto& TexCache = m_Textures[TextureIndex];
+
+ Width = (Width + TexCache.Granularity - 1) / TexCache.Granularity;
+ Height = (Height + TexCache.Granularity - 1) / TexCache.Granularity;
+
+ std::lock_guard<std::mutex> Lock{TexCache.Mtx};
+
+ TextureAllocation Allocation;
+ Allocation.TextureIndex = TextureIndex;
+ Allocation.Region = TexCache.Mgr.Allocate(Width, Height);
+ if (!Allocation.Region.IsEmpty())
+ {
+ Allocation.Region.x *= TexCache.Granularity;
+ Allocation.Region.y *= TexCache.Granularity;
+ Allocation.Region.width *= TexCache.Granularity;
+ Allocation.Region.height *= TexCache.Granularity;
+ }
+ return Allocation;
+}
+
+void GLTFResourceManager::FreeTextureSpace(TextureAllocation&& 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;
+
+ std::lock_guard<std::mutex> Lock{TexCache.Mtx};
+ TexCache.Mgr.Free(std::move(Region));
+}
+
+} // namespace Diligent