/// <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);
        }