public void CalculateStats([NativeTypeName("StatInfo&")] ref D3D12MA_StatInfo outStats) { ZeroMemory(Unsafe.AsPointer(ref outStats), (nuint)sizeof(D3D12MA_StatInfo)); outStats.AllocationSizeMin = UINT64_MAX; outStats.UnusedRangeSizeMin = UINT64_MAX; using D3D12MA_MutexLockRead @lock = new(ref m_Mutex, m_useMutex != 0); for (D3D12MA_Allocation *alloc = m_AllocationList.Front(); alloc != null; alloc = D3D12MA_IntrusiveLinkedList <D3D12MA_Allocation> .GetNext(alloc)) { ulong size = alloc->GetSize(); ++outStats.BlockCount; ++outStats.AllocationCount; outStats.UsedBytes += size; if (size > outStats.AllocationSizeMax) { outStats.AllocationSizeMax = size; } if (size < outStats.AllocationSizeMin) { outStats.AllocationSizeMin = size; } } }
public int CreateAliasingResource(D3D12MA_Allocation *pAllocation, [NativeTypeName("UINT64")] ulong AllocationLocalOffset, [NativeTypeName("const D3D12_RESOURCE_DESC*")] D3D12_RESOURCE_DESC *pResourceDesc, D3D12_RESOURCE_STATES InitialResourceState, [NativeTypeName("const D3D12_CLEAR_VALUE*")] D3D12_CLEAR_VALUE *pOptimizedClearValue, [NativeTypeName("REFIID")] Guid *riidResource, void **ppvResource) { if ((pAllocation == null) || (pResourceDesc == null) || (ppvResource == null)) { D3D12MA_ASSERT(false); // "Invalid arguments passed to Allocator::CreateAliasingResource." return(E_INVALIDARG); } using var debugGlobalMutexLock = D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK(); return(m_Pimpl->CreateAliasingResource(pAllocation, AllocationLocalOffset, pResourceDesc, InitialResourceState, pOptimizedClearValue, riidResource, ppvResource)); }
/// <summary>Writes JSON array with the list of allocations.</summary> public void BuildStatsString([NativeTypeName("JsonWriter&")] ref D3D12MA_JsonWriter json) { using D3D12MA_MutexLockRead @lock = new(ref m_Mutex, m_useMutex != 0); json.BeginArray(); for (D3D12MA_Allocation *alloc = m_AllocationList.Front(); alloc != null; alloc = D3D12MA_IntrusiveLinkedList <D3D12MA_Allocation> .GetNext(alloc)) { json.BeginObject(true); json.AddAllocationToObject(alloc); json.EndObject(); } json.EndArray(); }
public void Register(D3D12MA_Allocation *alloc) { using D3D12MA_MutexLockRead @lock = new(ref m_Mutex, m_useMutex != 0); m_AllocationList.PushBack(alloc); }
public void Unregister(D3D12MA_Allocation *alloc) { using D3D12MA_MutexLockRead @lock = new(ref m_Mutex, m_useMutex != 0); m_AllocationList.Remove(alloc); }
public void AddAllocationToObject(D3D12MA_Allocation *alloc) { WriteString("Type"); switch (alloc->m_PackedData.GetResourceDimension()) { case D3D12_RESOURCE_DIMENSION_UNKNOWN: { WriteString("UNKNOWN"); break; } case D3D12_RESOURCE_DIMENSION_BUFFER: { WriteString("BUFFER"); break; } case D3D12_RESOURCE_DIMENSION_TEXTURE1D: { WriteString("TEXTURE1D"); break; } case D3D12_RESOURCE_DIMENSION_TEXTURE2D: { WriteString("TEXTURE2D"); break; } case D3D12_RESOURCE_DIMENSION_TEXTURE3D: { WriteString("TEXTURE3D"); break; } default: { D3D12MA_ASSERT(false); break; } } WriteString("Size"); WriteNumber(alloc->GetSize()); ushort *name = alloc->GetName(); if (name != null) { WriteString("Name"); WriteString(name); } if (alloc->m_PackedData.GetResourceFlags() != 0) { WriteString("Flags"); WriteNumber((uint)alloc->m_PackedData.GetResourceFlags()); } if (alloc->m_PackedData.GetTextureLayout() != 0) { WriteString("Layout"); WriteNumber((uint)alloc->m_PackedData.GetTextureLayout()); } if (alloc->m_CreationFrameIndex != 0) { WriteString("CreationFrameIndex"); WriteNumber(alloc->m_CreationFrameIndex); } }
public void Free(D3D12MA_Allocation *alloc) { using var mutexLock = new D3D12MA_MutexLock(ref m_Mutex); m_Allocator.Free(alloc); }
public void Free(D3D12MA_Allocation *hAllocation) { D3D12MA_NormalBlock *pBlockToDelete = null; bool budgetExceeded = false; { D3D12MA_Budget budget = default; m_hAllocator->GetBudgetForHeapType(&budget, m_HeapType); budgetExceeded = budget.UsageBytes >= budget.BudgetBytes; } using (var @lock = new D3D12MA_MutexLockWrite(ref m_Mutex, m_hAllocator->UseMutex())) { D3D12MA_NormalBlock *pBlock = hAllocation->m_Placed.block; pBlock->m_pMetadata->FreeAtOffset(hAllocation->GetOffset()); D3D12MA_HEAVY_ASSERT((D3D12MA_DEBUG_LEVEL > 1) && pBlock->Validate()); nuint blockCount = m_Blocks.size(); ulong sumBlockSize = CalcSumBlockSize(); // pBlock became empty after this deallocation. if (pBlock->m_pMetadata->IsEmpty()) { // Already has empty Allocation. We don't want to have two, so delete this one. if ((m_HasEmptyBlock || budgetExceeded) && (blockCount > m_MinBlockCount) && ((sumBlockSize - pBlock->m_pMetadata->GetSize()) >= m_MinBytes)) { pBlockToDelete = pBlock; Remove(pBlock); } else { // We now have first empty block. m_HasEmptyBlock = true; } } else if (m_HasEmptyBlock && blockCount > m_MinBlockCount) { // pBlock didn't become empty, but we have another empty block - find and free that one. // (This is optional, heuristics.) D3D12MA_NormalBlock *pLastBlock = m_Blocks.back()->Value; if (pLastBlock->m_pMetadata->IsEmpty() && ((sumBlockSize - pLastBlock->m_pMetadata->GetSize()) >= m_MinBytes)) { pBlockToDelete = pLastBlock; m_Blocks.pop_back(); m_HasEmptyBlock = false; } } IncrementallySortBlocks(); } // Destruction of a free Allocation. Deferred until this point, outside of mutex // lock, for performance reason. if (pBlockToDelete != null) { D3D12MA_DELETE(m_hAllocator->GetAllocs(), pBlockToDelete); } }