/// <summary>Given free suballocation, it removes it from sorted list of <see cref="m_FreeSuballocationsBySize"/> if it's suitable.</summary> public void UnregisterFreeSuballocation(D3D12MA_List <D3D12MA_Suballocation> .iterator item) { D3D12MA_ASSERT((D3D12MA_DEBUG_LEVEL > 0) && (item.Get()->type == D3D12MA_SUBALLOCATION_TYPE_FREE)); D3D12MA_ASSERT((D3D12MA_DEBUG_LEVEL > 0) && (item.Get()->size > 0)); // You may want to enable this validation at the beginning or at the end of // this function, depending on what do you want to check. D3D12MA_HEAVY_ASSERT((D3D12MA_DEBUG_LEVEL > 1) && ValidateFreeSuballocationList()); if (item.Get()->size >= MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) { D3D12MA_List <D3D12MA_Suballocation> .iterator *it = BinaryFindFirstNotLess( m_FreeSuballocationsBySize.data(), m_FreeSuballocationsBySize.data() + m_FreeSuballocationsBySize.size(), in item, new D3D12MA_SuballocationItemSizeLess() ); for (nuint index = (nuint)(it - m_FreeSuballocationsBySize.data()); index < m_FreeSuballocationsBySize.size(); ++index) { if (*m_FreeSuballocationsBySize[index] == item) { m_FreeSuballocationsBySize.remove(index); return; } D3D12MA_ASSERT((D3D12MA_DEBUG_LEVEL > 0) && (m_FreeSuballocationsBySize[index]->Get()->size == item.Get()->size)); // "Not found!" } D3D12MA_ASSERT(false); // "Not found!" } // D3D12MA_HEAVY_ASSERT((D3D12MA_DEBUG_LEVEL > 1) && ValidateFreeSuballocationList()); }
public int SetMinBytes([NativeTypeName("UINT64")] ulong minBytes) { using var @lock = new D3D12MA_MutexLockWrite(ref m_Mutex, m_hAllocator->UseMutex()); if (minBytes == m_MinBytes) { return(S_OK); } HRESULT hr = S_OK; ulong sumBlockSize = CalcSumBlockSize(); nuint blockCount = m_Blocks.size(); // New minBytes is smaller - may be able to free some blocks. if (minBytes < m_MinBytes) { m_HasEmptyBlock = false; // Will recalculate this value from scratch. for (nuint blockIndex = blockCount; unchecked (blockIndex-- != 0);) { D3D12MA_NormalBlock *block = m_Blocks[blockIndex]->Value; ulong size = block->m_pMetadata->GetSize(); bool isEmpty = block->m_pMetadata->IsEmpty(); if (isEmpty && ((sumBlockSize - size) >= minBytes) && ((blockCount - 1) >= m_MinBlockCount)) { D3D12MA_DELETE(m_hAllocator->GetAllocs(), block); m_Blocks.remove(blockIndex); sumBlockSize -= size; --blockCount; } else { if (isEmpty) { m_HasEmptyBlock = true; } } } } else { // New minBytes is larger - may need to allocate some blocks. ulong minBlockSize = m_PreferredBlockSize >> (int)NEW_BLOCK_SIZE_SHIFT_MAX; while (SUCCEEDED(hr) && sumBlockSize < minBytes) { if (blockCount < m_MaxBlockCount) { ulong newBlockSize = m_PreferredBlockSize; if (!m_ExplicitBlockSize) { if (sumBlockSize + newBlockSize > minBytes) { newBlockSize = minBytes - sumBlockSize; } else if (((blockCount + 1) < m_MaxBlockCount) && ((sumBlockSize + newBlockSize + minBlockSize) > minBytes)) { // Next one would be the last block to create and its size would be smaller than // the smallest block size we want to use here, so make this one smaller. newBlockSize -= minBlockSize + sumBlockSize + m_PreferredBlockSize - minBytes; } } hr = CreateBlock(newBlockSize, null); if (SUCCEEDED(hr)) { m_HasEmptyBlock = true; sumBlockSize += newBlockSize; ++blockCount; } } else { hr = E_INVALIDARG; } } } m_MinBytes = minBytes; return(hr); }