From 70129fda4c75f7b8e6812190631e35a56eb2b9d2 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 30 Nov 2020 11:21:07 -0800 Subject: GLTF loader: initial implementation of GLTF resource cache --- AssetLoader/src/GLTFResourceManager.cpp | 137 ++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 AssetLoader/src/GLTFResourceManager.cpp (limited to 'AssetLoader/src/GLTFResourceManager.cpp') 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::Create(IRenderDevice* pDevice, + const CreateInfo& CI) +{ + return RefCntAutoPtr{MakeNewRCObj()(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 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 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 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 Lock{TexCache.Mtx}; + TexCache.Mgr.Free(std::move(Region)); +} + +} // namespace Diligent -- cgit v1.2.3