Refactoring - added class CommittedAllocationList
diff --git a/src/D3D12MemAlloc.cpp b/src/D3D12MemAlloc.cpp
index a8ec007..a9ffb7a 100644
--- a/src/D3D12MemAlloc.cpp
+++ b/src/D3D12MemAlloc.cpp
@@ -2522,6 +2522,63 @@
};
////////////////////////////////////////////////////////////////////////////////
+// Private class CommittedAllocationList definition
+
+struct CommittedAllocationListItemTraits
+{
+ typedef Allocation ItemType;
+ static ItemType* GetPrev(const ItemType* item)
+ {
+ D3D12MA_ASSERT(item->m_PackedData.GetType() == Allocation::TYPE_COMMITTED || item->m_PackedData.GetType() == Allocation::TYPE_HEAP);
+ return item->m_Committed.prev;
+ }
+ static ItemType* GetNext(const ItemType* item)
+ {
+ D3D12MA_ASSERT(item->m_PackedData.GetType() == Allocation::TYPE_COMMITTED || item->m_PackedData.GetType() == Allocation::TYPE_HEAP);
+ return item->m_Committed.next;
+ }
+ static ItemType*& AccessPrev(ItemType* item)
+ {
+ D3D12MA_ASSERT(item->m_PackedData.GetType() == Allocation::TYPE_COMMITTED || item->m_PackedData.GetType() == Allocation::TYPE_HEAP);
+ return item->m_Committed.prev;
+ }
+ static ItemType*& AccessNext(ItemType* item)
+ {
+ D3D12MA_ASSERT(item->m_PackedData.GetType() == Allocation::TYPE_COMMITTED || item->m_PackedData.GetType() == Allocation::TYPE_HEAP);
+ return item->m_Committed.next;
+ }
+};
+
+/*
+Stores linked list of Allocation objects that are of TYPE_COMMITTED or TYPE_HEAP.
+Thread-safe, synchronized internally.
+*/
+class CommittedAllocationList
+{
+public:
+ CommittedAllocationList();
+ void Init(bool useMutex, D3D12_HEAP_TYPE heapType);
+ ~CommittedAllocationList();
+
+ D3D12_HEAP_TYPE GetHeapType() const { return m_HeapType; }
+
+ void CalculateStats(StatInfo& outStats);
+ // Writes JSON array with the list of allocations.
+ void BuildStatsString(JsonWriter& json);
+
+ void Register(Allocation* alloc);
+ void Unregister(Allocation* alloc);
+
+private:
+ bool m_UseMutex = true;
+ D3D12_HEAP_TYPE m_HeapType = D3D12_HEAP_TYPE_CUSTOM;
+
+ D3D12MA_RW_MUTEX m_Mutex;
+ typedef IntrusiveLinkedList<CommittedAllocationListItemTraits> CommittedAllocationLinkedList;
+ CommittedAllocationLinkedList m_AllocationList;
+};
+
+////////////////////////////////////////////////////////////////////////////////
// Private class BlockVector definition
/*
@@ -2683,31 +2740,6 @@
}
};
-struct CommittedAllocationListItemTraits
-{
- typedef Allocation ItemType;
- static ItemType* GetPrev(const ItemType* item)
- {
- D3D12MA_ASSERT(item->m_PackedData.GetType() == Allocation::TYPE_COMMITTED || item->m_PackedData.GetType() == Allocation::TYPE_HEAP);
- return item->m_Committed.prev;
- }
- static ItemType* GetNext(const ItemType* item)
- {
- D3D12MA_ASSERT(item->m_PackedData.GetType() == Allocation::TYPE_COMMITTED || item->m_PackedData.GetType() == Allocation::TYPE_HEAP);
- return item->m_Committed.next;
- }
- static ItemType*& AccessPrev(ItemType* item)
- {
- D3D12MA_ASSERT(item->m_PackedData.GetType() == Allocation::TYPE_COMMITTED || item->m_PackedData.GetType() == Allocation::TYPE_HEAP);
- return item->m_Committed.prev;
- }
- static ItemType*& AccessNext(ItemType* item)
- {
- D3D12MA_ASSERT(item->m_PackedData.GetType() == Allocation::TYPE_COMMITTED || item->m_PackedData.GetType() == Allocation::TYPE_HEAP);
- return item->m_Committed.next;
- }
-};
-
class PoolPimpl
{
public:
@@ -2890,10 +2922,6 @@
D3D12_FEATURE_DATA_ARCHITECTURE m_D3D12Architecture;
AllocationObjectAllocator m_AllocationObjectAllocator;
- typedef IntrusiveLinkedList<CommittedAllocationListItemTraits> CommittedAllocationList;
- CommittedAllocationList m_CommittedAllocations[HEAP_TYPE_COUNT];
- D3D12MA_RW_MUTEX m_CommittedAllocationsMutex[HEAP_TYPE_COUNT];
-
typedef IntrusiveLinkedList<PoolListItemTraits> PoolList;
PoolList m_Pools[HEAP_TYPE_COUNT];
D3D12MA_RW_MUTEX m_PoolsMutex[HEAP_TYPE_COUNT];
@@ -2901,6 +2929,8 @@
// Default pools.
BlockVector* m_BlockVectors[DEFAULT_POOL_MAX_COUNT];
+ CommittedAllocationList m_CommittedAllocations[STANDARD_HEAP_TYPE_COUNT];
+
// # Used only when ResourceHeapTier = 1
UINT64 m_DefaultPoolTier1MinBytes[DEFAULT_POOL_MAX_COUNT]; // Default 0
UINT64 m_DefaultPoolHeapTypeMinBytes[HEAP_TYPE_COUNT]; // Default UINT64_MAX, meaning not set
@@ -2990,11 +3020,6 @@
}
void CalcDefaultPoolParams(D3D12_HEAP_TYPE& outHeapType, D3D12_HEAP_FLAGS& outHeapFlags, UINT index) const;
- // Registers Allocation object in m_CommittedAllocations.
- void RegisterCommittedAllocation(Allocation* alloc, D3D12_HEAP_TYPE heapType);
- // Unregisters Allocation object from m_CommittedAllocations.
- void UnregisterCommittedAllocation(Allocation* alloc, D3D12_HEAP_TYPE heapType);
-
// Registers Pool object in m_Pools.
void RegisterPool(Pool* pool, D3D12_HEAP_TYPE heapType);
// Unregisters Pool object from m_Pools.
@@ -3726,6 +3751,84 @@
}
////////////////////////////////////////////////////////////////////////////////
+// Private class CommittedAllocationList implementation
+
+CommittedAllocationList::CommittedAllocationList()
+{
+}
+
+void CommittedAllocationList::Init(bool useMutex, D3D12_HEAP_TYPE heapType)
+{
+ m_UseMutex = useMutex;
+ m_HeapType = heapType;
+}
+
+CommittedAllocationList::~CommittedAllocationList()
+{
+ if(!m_AllocationList.IsEmpty())
+ {
+ D3D12MA_ASSERT(0 && "Unfreed committed allocations found!");
+ }
+}
+
+void CommittedAllocationList::CalculateStats(StatInfo& outStats)
+{
+ outStats.BlockCount = 0;
+ outStats.AllocationCount = 0;
+ outStats.UnusedRangeCount = 0;
+ outStats.UsedBytes = 0;
+ outStats.UnusedBytes = 0;
+ outStats.AllocationSizeMin = UINT64_MAX;
+ outStats.AllocationSizeAvg = 0;
+ outStats.AllocationSizeMax = 0;
+ outStats.UnusedRangeSizeMin = UINT64_MAX;
+ outStats.UnusedRangeSizeAvg = 0;
+ outStats.UnusedRangeSizeMax = 0;
+
+ MutexLockRead lock(m_Mutex, m_UseMutex);
+
+ for(Allocation* alloc = m_AllocationList.Front();
+ alloc != NULL; alloc = m_AllocationList.GetNext(alloc))
+ {
+ const UINT64 size = alloc->GetSize();
+ ++outStats.BlockCount;
+ ++outStats.AllocationCount;
+ outStats.UsedBytes += size;
+ if(size > outStats.AllocationSizeMax)
+ outStats.AllocationSizeMax = size;
+ if(size < outStats.AllocationSizeMin)
+ outStats.AllocationSizeMin = size;
+ }
+}
+
+void CommittedAllocationList::BuildStatsString(JsonWriter& json)
+{
+ MutexLockRead lock(m_Mutex, m_UseMutex);
+
+ json.BeginArray();
+ for(Allocation* alloc = m_AllocationList.Front();
+ alloc != NULL; alloc = m_AllocationList.GetNext(alloc))
+ {
+ json.BeginObject(true);
+ json.AddAllocationToObject(*alloc);
+ json.EndObject();
+ }
+ json.EndArray();
+}
+
+void CommittedAllocationList::Register(Allocation* alloc)
+{
+ MutexLockWrite lock(m_Mutex, m_UseMutex);
+ m_AllocationList.PushBack(alloc);
+}
+
+void CommittedAllocationList::Unregister(Allocation* alloc)
+{
+ MutexLockWrite lock(m_Mutex, m_UseMutex);
+ m_AllocationList.Remove(alloc);
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Private class BlockVector implementation
BlockVector::BlockVector(
@@ -4498,6 +4601,11 @@
m_DefaultPoolHeapTypeMinBytes[i] = UINT64_MAX;
}
+ for(UINT i = 0; i < STANDARD_HEAP_TYPE_COUNT; ++i)
+ {
+ m_CommittedAllocations[i].Init(m_UseMutex, (D3D12_HEAP_TYPE)(D3D12_HEAP_TYPE_DEFAULT + i));
+ }
+
m_Device->AddRef();
m_Adapter->AddRef();
}
@@ -4592,14 +4700,6 @@
D3D12MA_ASSERT(0 && "Unfreed pools found!");
}
}
-
- for(UINT i = HEAP_TYPE_COUNT; i--; )
- {
- if(!m_CommittedAllocations[i].IsEmpty())
- {
- D3D12MA_ASSERT(0 && "Unfreed committed allocations found!");
- }
- }
}
bool AllocatorPimpl::HeapFlagsFulfillResourceHeapTier(D3D12_HEAP_FLAGS flags) const
@@ -5172,14 +5272,16 @@
}
if(SUCCEEDED(hr))
{
+ CommittedAllocationList& allocList = m_CommittedAllocations[HeapTypeToIndex(pAllocDesc->HeapType)];
+
const BOOL wasZeroInitialized = TRUE;
Allocation* alloc = m_AllocationObjectAllocator.Allocate(this, resAllocInfo.SizeInBytes, wasZeroInitialized);
- alloc->InitCommitted(pAllocDesc->HeapType);
+ alloc->InitCommitted(&allocList);
alloc->SetResource(res, pResourceDesc);
*ppAllocation = alloc;
- RegisterCommittedAllocation(*ppAllocation, pAllocDesc->HeapType);
+ allocList.Register(alloc);
const UINT heapTypeIndex = HeapTypeToIndex(pAllocDesc->HeapType);
m_Budget.AddAllocation(heapTypeIndex, resAllocInfo.SizeInBytes);
@@ -5238,14 +5340,16 @@
}
if(SUCCEEDED(hr))
{
+ CommittedAllocationList& allocList = m_CommittedAllocations[HeapTypeToIndex(pAllocDesc->HeapType)];
+
const BOOL wasZeroInitialized = TRUE;
Allocation* alloc = m_AllocationObjectAllocator.Allocate(this, resAllocInfo.SizeInBytes, wasZeroInitialized);
- alloc->InitCommitted(pAllocDesc->HeapType);
+ alloc->InitCommitted(&allocList);
alloc->SetResource(res, pResourceDesc);
*ppAllocation = alloc;
- RegisterCommittedAllocation(*ppAllocation, pAllocDesc->HeapType);
+ allocList.Register(alloc);
const UINT heapTypeIndex = HeapTypeToIndex(pAllocDesc->HeapType);
m_Budget.AddAllocation(heapTypeIndex, resAllocInfo.SizeInBytes);
@@ -5305,14 +5409,16 @@
}
if(SUCCEEDED(hr))
{
+ CommittedAllocationList& allocList = m_CommittedAllocations[HeapTypeToIndex(pAllocDesc->HeapType)];
+
const BOOL wasZeroInitialized = TRUE;
Allocation* alloc = m_AllocationObjectAllocator.Allocate(this, resAllocInfo.SizeInBytes, wasZeroInitialized);
- alloc->InitCommitted(pAllocDesc->HeapType);
+ alloc->InitCommitted(&allocList);
alloc->SetResource(res, pResourceDesc);
*ppAllocation = alloc;
- RegisterCommittedAllocation(*ppAllocation, pAllocDesc->HeapType);
+ allocList.Register(alloc);
const UINT heapTypeIndex = HeapTypeToIndex(pAllocDesc->HeapType);
m_Budget.AddAllocation(heapTypeIndex, resAllocInfo.SizeInBytes);
@@ -5357,10 +5463,12 @@
HRESULT hr = m_Device->CreateHeap(&heapDesc, __uuidof(*heap), (void**)&heap);
if(SUCCEEDED(hr))
{
+ CommittedAllocationList& allocList = m_CommittedAllocations[HeapTypeToIndex(pAllocDesc->HeapType)];
+
const BOOL wasZeroInitialized = TRUE;
(*ppAllocation) = m_AllocationObjectAllocator.Allocate(this, allocInfo.SizeInBytes, wasZeroInitialized);
- (*ppAllocation)->InitHeap(pAllocDesc->HeapType, heap);
- RegisterCommittedAllocation(*ppAllocation, pAllocDesc->HeapType);
+ (*ppAllocation)->InitHeap(&allocList, heap);
+ allocList.Register(*ppAllocation);
const UINT heapTypeIndex = HeapTypeToIndex(pAllocDesc->HeapType);
m_Budget.AddAllocation(heapTypeIndex, allocInfo.SizeInBytes);
@@ -5406,10 +5514,12 @@
HRESULT hr = m_Device4->CreateHeap1(&heapDesc, pProtectedSession, __uuidof(*heap), (void**)&heap);
if(SUCCEEDED(hr))
{
+ CommittedAllocationList& allocList = m_CommittedAllocations[HeapTypeToIndex(pAllocDesc->HeapType)];
+
const BOOL wasZeroInitialized = TRUE;
(*ppAllocation) = m_AllocationObjectAllocator.Allocate(this, allocInfo.SizeInBytes, wasZeroInitialized);
- (*ppAllocation)->InitHeap(pAllocDesc->HeapType, heap);
- RegisterCommittedAllocation(*ppAllocation, pAllocDesc->HeapType);
+ (*ppAllocation)->InitHeap(&allocList, heap);
+ allocList.Register(*ppAllocation);
const UINT heapTypeIndex = HeapTypeToIndex(pAllocDesc->HeapType);
m_Budget.AddAllocation(heapTypeIndex, allocInfo.SizeInBytes);
@@ -5550,24 +5660,6 @@
}
}
-void AllocatorPimpl::RegisterCommittedAllocation(Allocation* alloc, D3D12_HEAP_TYPE heapType)
-{
- const UINT heapTypeIndex = HeapTypeToIndex(heapType);
-
- MutexLockWrite lock(m_CommittedAllocationsMutex[heapTypeIndex], m_UseMutex);
- CommittedAllocationList& committedAllocations = m_CommittedAllocations[heapTypeIndex];
- committedAllocations.PushBack(alloc);
-}
-
-void AllocatorPimpl::UnregisterCommittedAllocation(Allocation* alloc, D3D12_HEAP_TYPE heapType)
-{
- const UINT heapTypeIndex = HeapTypeToIndex(heapType);
-
- MutexLockWrite lock(m_CommittedAllocationsMutex[heapTypeIndex], m_UseMutex);
- CommittedAllocationList& committedAllocations = m_CommittedAllocations[heapTypeIndex];
- committedAllocations.Remove(alloc);
-}
-
void AllocatorPimpl::RegisterPool(Pool* pool, D3D12_HEAP_TYPE heapType)
{
const UINT heapTypeIndex = HeapTypeToIndex(heapType);
@@ -5587,10 +5679,12 @@
void AllocatorPimpl::FreeCommittedMemory(Allocation* allocation)
{
D3D12MA_ASSERT(allocation && allocation->m_PackedData.GetType() == Allocation::TYPE_COMMITTED);
- UnregisterCommittedAllocation(allocation, allocation->m_Committed.heapType);
+
+ CommittedAllocationList* const allocList = allocation->m_Committed.list;
+ allocList->Unregister(allocation);
const UINT64 allocationSize = allocation->GetSize();
- const UINT heapTypeIndex = HeapTypeToIndex(allocation->m_Committed.heapType);
+ const UINT heapTypeIndex = HeapTypeToIndex(allocList->GetHeapType());
m_Budget.RemoveAllocation(heapTypeIndex, allocationSize);
m_Budget.m_BlockBytes[heapTypeIndex] -= allocationSize;
}
@@ -5610,10 +5704,12 @@
void AllocatorPimpl::FreeHeapMemory(Allocation* allocation)
{
D3D12MA_ASSERT(allocation && allocation->m_PackedData.GetType() == Allocation::TYPE_HEAP);
- UnregisterCommittedAllocation(allocation, allocation->m_Heap.heapType);
+
+ CommittedAllocationList* const allocList = allocation->m_Committed.list;
+ allocList->Unregister(allocation);
SAFE_RELEASE(allocation->m_Heap.heap);
- const UINT heapTypeIndex = HeapTypeToIndex(allocation->m_Heap.heapType);
+ const UINT heapTypeIndex = HeapTypeToIndex(allocList->GetHeapType());
const UINT64 allocationSize = allocation->GetSize();
m_Budget.m_BlockBytes[heapTypeIndex] -= allocationSize;
m_Budget.RemoveAllocation(heapTypeIndex, allocationSize);
@@ -5679,28 +5775,12 @@
}
// Process committed allocations.
- for(size_t heapTypeIndex = 0; heapTypeIndex < HEAP_TYPE_COUNT; ++heapTypeIndex)
+ for(size_t heapTypeIndex = 0; heapTypeIndex < STANDARD_HEAP_TYPE_COUNT; ++heapTypeIndex)
{
- StatInfo& heapStatInfo = outStats.HeapType[heapTypeIndex];
- MutexLockRead lock(m_CommittedAllocationsMutex[heapTypeIndex], m_UseMutex);
- CommittedAllocationList& committedAllocations = m_CommittedAllocations[heapTypeIndex];
- for(Allocation* alloc = committedAllocations.Front();
- alloc != NULL; alloc = committedAllocations.GetNext(alloc))
- {
- UINT64 size = alloc->GetSize();
- StatInfo statInfo = {};
- statInfo.BlockCount = 1;
- statInfo.AllocationCount = 1;
- statInfo.UnusedRangeCount = 0;
- statInfo.UsedBytes = size;
- statInfo.UnusedBytes = 0;
- statInfo.AllocationSizeMin = size;
- statInfo.AllocationSizeMax = size;
- statInfo.UnusedRangeSizeMin = UINT64_MAX;
- statInfo.UnusedRangeSizeMax = 0;
- AddStatInfo(outStats.Total, statInfo);
- AddStatInfo(heapStatInfo, statInfo);
- }
+ StatInfo statInfo; // Uninitialized.
+ m_CommittedAllocations[heapTypeIndex].CalculateStats(statInfo);
+ AddStatInfo(outStats.Total, statInfo);
+ AddStatInfo(outStats.HeapType[heapTypeIndex], statInfo);
}
// Post process
@@ -5924,22 +6004,10 @@
json.WriteString(L"CommittedAllocations");
json.BeginObject();
- for (size_t heapType = 0; heapType < HEAP_TYPE_COUNT; ++heapType)
+ for (size_t heapTypeIndex = 0; heapTypeIndex < STANDARD_HEAP_TYPE_COUNT; ++heapTypeIndex)
{
- json.WriteString(HeapTypeNames[heapType]);
- MutexLockRead lock(m_CommittedAllocationsMutex[heapType], m_UseMutex);
-
- json.BeginArray();
- CommittedAllocationList& committedAllocations = m_CommittedAllocations[heapType];
- for(Allocation* alloc = committedAllocations.Front();
- alloc != NULL; alloc = committedAllocations.GetNext(alloc))
- {
- D3D12MA_ASSERT(alloc);
- json.BeginObject(true);
- json.AddAllocationToObject(*alloc);
- json.EndObject();
- }
- json.EndArray();
+ json.WriteString(HeapTypeNames[heapTypeIndex]);
+ m_CommittedAllocations[heapTypeIndex].BuildStatsString(json);
}
json.EndObject(); // CommittedAllocations
@@ -6210,10 +6278,10 @@
// Nothing here, everything already done in Release.
}
-void Allocation::InitCommitted(D3D12_HEAP_TYPE heapType)
+void Allocation::InitCommitted(CommittedAllocationList* list)
{
m_PackedData.SetType(TYPE_COMMITTED);
- m_Committed.heapType = heapType;
+ m_Committed.list = list;
m_Committed.prev = NULL;
m_Committed.next = NULL;
}
@@ -6225,10 +6293,10 @@
m_Placed.block = block;
}
-void Allocation::InitHeap(D3D12_HEAP_TYPE heapType, ID3D12Heap* heap)
+void Allocation::InitHeap(CommittedAllocationList* list, ID3D12Heap* heap)
{
m_PackedData.SetType(TYPE_HEAP);
- m_Heap.heapType = heapType;
+ m_Heap.list = list;
m_Committed.prev = NULL;
m_Committed.next = NULL;
m_Heap.heap = heap;
diff --git a/src/D3D12MemAlloc.h b/src/D3D12MemAlloc.h
index d70f07c..8e66565 100644
--- a/src/D3D12MemAlloc.h
+++ b/src/D3D12MemAlloc.h
@@ -757,6 +757,7 @@
class PoolPimpl;
class NormalBlock;
class BlockVector;
+class CommittedAllocationList;
class JsonWriter;
class VirtualBlockPimpl;
/// \endcond
@@ -946,6 +947,7 @@
private:
friend class AllocatorPimpl;
friend class BlockVector;
+ friend class CommittedAllocationList;
friend class JsonWriter;
friend struct CommittedAllocationListItemTraits;
template<typename T> friend void D3D12MA_DELETE(const ALLOCATION_CALLBACKS&, T*);
@@ -969,7 +971,7 @@
{
struct
{
- D3D12_HEAP_TYPE heapType;
+ CommittedAllocationList* list;
Allocation* prev;
Allocation* next;
} m_Committed;
@@ -983,7 +985,7 @@
struct
{
// Beginning must be compatible with m_Committed.
- D3D12_HEAP_TYPE heapType;
+ CommittedAllocationList* list;
Allocation* prev;
Allocation* next;
ID3D12Heap* heap;
@@ -1018,9 +1020,9 @@
Allocation(AllocatorPimpl* allocator, UINT64 size, BOOL wasZeroInitialized);
~Allocation();
- void InitCommitted(D3D12_HEAP_TYPE heapType);
+ void InitCommitted(CommittedAllocationList* list);
void InitPlaced(UINT64 offset, UINT64 alignment, NormalBlock* block);
- void InitHeap(D3D12_HEAP_TYPE heapType, ID3D12Heap* heap);
+ void InitHeap(CommittedAllocationList* list, ID3D12Heap* heap);
template<typename D3D12_RESOURCE_DESC_T>
void SetResource(ID3D12Resource* resource, const D3D12_RESOURCE_DESC_T* pResourceDesc);
void FreeName();