From 5dd63ff5b888f8d861aa2327507fcefa7103ffeb Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 1 Jul 2020 20:59:18 -0700 Subject: VariableSizeAllocationsManager: added Extend method --- .../interface/VariableSizeAllocationsManager.hpp | 40 +++++++++++++++++++++ .../VariableSizeGPUAllocationsManagerTest.cpp | 41 ++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.hpp b/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.hpp index c1fc083f..0788db23 100644 --- a/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.hpp +++ b/Graphics/GraphicsAccessories/interface/VariableSizeAllocationsManager.hpp @@ -175,6 +175,12 @@ public: return UnalignedOffset != InvalidAllocation().UnalignedOffset; } + bool operator==(const Allocation& rhs) const + { + return UnalignedOffset == rhs.UnalignedOffset && + Size == rhs.Size; + } + OffsetType UnalignedOffset = InvalidOffset; OffsetType Size = 0; }; @@ -357,6 +363,40 @@ public: return m_FreeBlocksByOffset.size(); } + void Extend(size_t ExtraSize) + { + size_t NewBlockOffset = m_MaxSize; + size_t NewBlockSize = ExtraSize; + + if (!m_FreeBlocksByOffset.empty()) + { + auto LastBlockIt = m_FreeBlocksByOffset.end(); + --LastBlockIt; + + const auto LastBlockOffset = LastBlockIt->first; + const auto LastBlockSize = LastBlockIt->second.Size; + if (LastBlockOffset + LastBlockSize == m_MaxSize) + { + // Extend the last block + NewBlockOffset = LastBlockOffset; + NewBlockSize += LastBlockSize; + + VERIFY_EXPR(LastBlockIt->second.OrderBySizeIt->first == LastBlockOffset); + m_FreeBlocksBySize.erase(LastBlockIt->second.OrderBySizeIt); + m_FreeBlocksByOffset.erase(LastBlockIt); + } + } + + AddNewBlock(NewBlockOffset, NewBlockSize); + + m_MaxSize += ExtraSize; + m_FreeSize += ExtraSize; + +#ifdef DILIGENT_DEBUG + DbgVerifyList(); +#endif + } + private: void AddNewBlock(OffsetType Offset, OffsetType Size) { diff --git a/Tests/DiligentCoreTest/src/GraphicsAccessories/VariableSizeGPUAllocationsManagerTest.cpp b/Tests/DiligentCoreTest/src/GraphicsAccessories/VariableSizeGPUAllocationsManagerTest.cpp index 3fa579da..45711497 100644 --- a/Tests/DiligentCoreTest/src/GraphicsAccessories/VariableSizeGPUAllocationsManagerTest.cpp +++ b/Tests/DiligentCoreTest/src/GraphicsAccessories/VariableSizeGPUAllocationsManagerTest.cpp @@ -128,6 +128,47 @@ TEST(GraphicsAccessories_VariableSizeGPUAllocationsManager, AllocateFree) EXPECT_TRUE(ListMgr.IsEmpty()); } + + { + VariableSizeAllocationsManager ListMgr(128, Allocator); + + auto a1 = ListMgr.Allocate(64, 1); + EXPECT_EQ(a1.UnalignedOffset, OffsetType{0}); + EXPECT_EQ(a1.Size, OffsetType{64}); + EXPECT_EQ(ListMgr.GetNumFreeBlocks(), size_t{1}); + + auto a2 = ListMgr.Allocate(128, 1); + EXPECT_EQ(a2, VariableSizeAllocationsManager::Allocation::InvalidAllocation()); + + ListMgr.Extend(128); + EXPECT_EQ(ListMgr.GetNumFreeBlocks(), size_t{1}); + + a2 = ListMgr.Allocate(128, 1); + EXPECT_EQ(a2.UnalignedOffset, 64); + EXPECT_EQ(a2.Size, 128); + + auto a3 = ListMgr.Allocate(64, 1); + EXPECT_TRUE(ListMgr.IsFull()); + + ListMgr.Extend(32); + EXPECT_EQ(ListMgr.GetNumFreeBlocks(), size_t{1}); + + auto a4 = ListMgr.Allocate(32, 1); + EXPECT_TRUE(ListMgr.IsFull()); + + ListMgr.Free(std::move(a1)); + EXPECT_EQ(ListMgr.GetNumFreeBlocks(), size_t{1}); + + ListMgr.Extend(1024); + EXPECT_EQ(ListMgr.GetNumFreeBlocks(), size_t{2}); + + auto a5 = ListMgr.Allocate(512, 1); + + ListMgr.Free(std::move(a4)); + ListMgr.Free(std::move(a2)); + ListMgr.Free(std::move(a5)); + ListMgr.Free(std::move(a3)); + } } TEST(GraphicsAccessories_VariableSizeGPUAllocationsManager, FreeOrder) -- cgit v1.2.3