/// <summary>Releases given suballocation, making it free. Merges it with adjacent free suballocations if applicable. Returns iterator to new free suballocation at this place.</summary> public D3D12MA_List <D3D12MA_Suballocation> .iterator FreeSuballocation(D3D12MA_List <D3D12MA_Suballocation> .iterator suballocItem) { // Change this suballocation to be marked as free. D3D12MA_Suballocation *suballoc = suballocItem.Get(); suballoc->type = D3D12MA_SUBALLOCATION_TYPE_FREE; suballoc->userData = null; // Update totals. ++m_FreeCount; m_SumFreeSize += suballoc->size; // Merge with previous and/or next suballocation if it's also free. bool mergeWithNext = false; bool mergeWithPrev = false; D3D12MA_List <D3D12MA_Suballocation> .iterator nextItem = suballocItem; nextItem = nextItem.MoveNext(); if ((nextItem != m_Suballocations.end()) && (nextItem.Get()->type == D3D12MA_SUBALLOCATION_TYPE_FREE)) { mergeWithNext = true; } D3D12MA_List <D3D12MA_Suballocation> .iterator prevItem = suballocItem; if (suballocItem != m_Suballocations.begin()) { prevItem = prevItem.MoveBack(); if (prevItem.Get()->type == D3D12MA_SUBALLOCATION_TYPE_FREE) { mergeWithPrev = true; } } if (mergeWithNext) { UnregisterFreeSuballocation(nextItem); MergeFreeWithNext(suballocItem); } if (mergeWithPrev) { UnregisterFreeSuballocation(prevItem); MergeFreeWithNext(prevItem); RegisterFreeSuballocation(prevItem); return(prevItem); } else { RegisterFreeSuballocation(suballocItem); return(suballocItem); } }
/// <summary>Checks if requested suballocation with given parameters can be placed in given pFreeSuballocItem. If yes, fills pOffset and returns true. If no, returns false.</summary> public readonly bool CheckAllocation([NativeTypeName("UINT64")] ulong allocSize, [NativeTypeName("UINT64")] ulong allocAlignment, D3D12MA_List <D3D12MA_Suballocation> .iterator suballocItem, [NativeTypeName("UINT64*")] ulong *pOffset, [NativeTypeName("UINT64*")] ulong *pSumFreeSize, [NativeTypeName("UINT64*")] ulong *pSumItemSize, [NativeTypeName("BOOL")] int *pZeroInitialized) { D3D12MA_ASSERT((D3D12MA_DEBUG_LEVEL > 0) && (allocSize > 0)); D3D12MA_ASSERT((D3D12MA_DEBUG_LEVEL > 0) && (suballocItem != m_Suballocations.end())); D3D12MA_ASSERT((D3D12MA_DEBUG_LEVEL > 0) && (pOffset != null) && (pZeroInitialized != null)); *pSumFreeSize = 0; *pSumItemSize = 0; *pZeroInitialized = FALSE; D3D12MA_Suballocation *suballoc = suballocItem.Get(); D3D12MA_ASSERT((D3D12MA_DEBUG_LEVEL > 0) && (suballoc->type == D3D12MA_SUBALLOCATION_TYPE_FREE)); *pSumFreeSize = suballoc->size; // Size of this suballocation is too small for this request: Early return. if (suballoc->size < allocSize) { return(false); } // Start from offset equal to beginning of this suballocation. *pOffset = suballoc->offset; // Apply D3D12MA_DEBUG_MARGIN at the beginning. if (D3D12MA_DEBUG_MARGIN > 0) { *pOffset += D3D12MA_DEBUG_MARGIN; } // Apply alignment. *pOffset = AlignUp(*pOffset, allocAlignment); // Calculate padding at the beginning based on current offset. ulong paddingBegin = *pOffset - suballoc->offset; // Calculate required margin at the end. ulong requiredEndMargin = D3D12MA_DEBUG_MARGIN; // Fail if requested size plus margin before and after is bigger than size of this suballocation. if (paddingBegin + allocSize + requiredEndMargin > suballoc->size) { return(false); } // All tests passed: Success. pOffset is already filled. *pZeroInitialized = m_ZeroInitializedRange.IsRangeZeroInitialized(*pOffset, *pOffset + allocSize); return(true); }