Removed Pool::SetMinBytes, Allocator::SetDefaultHeapMinBytes (compatibility breaking!)

More refactoring. Added private enum ResourceClass.
diff --git a/src/D3D12MemAlloc.cpp b/src/D3D12MemAlloc.cpp
index 490eda0..9a387a5 100644
--- a/src/D3D12MemAlloc.cpp
+++ b/src/D3D12MemAlloc.cpp
@@ -687,6 +687,42 @@
     }

 }

 

+static const D3D12_HEAP_FLAGS RESOURCE_CLASS_HEAP_FLAGS =

+    D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES | D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES;

+

+enum class ResourceClass

+{

+    Unknown, Buffer, Non_RT_DS_Texture, RT_DS_Texture

+};

+

+template<typename D3D12_RESOURCE_DESC_T>

+static inline ResourceClass ResourceDescToResourceClass(const D3D12_RESOURCE_DESC_T& resDesc)

+{

+    if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)

+        return ResourceClass::Buffer;

+    // Else: it's surely a texture.

+    const bool isRenderTargetOrDepthStencil =

+        (resDesc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) != 0;

+    return isRenderTargetOrDepthStencil ? ResourceClass::RT_DS_Texture : ResourceClass::Non_RT_DS_Texture;

+}

+

+static inline ResourceClass HeapFlagsToResourceClass(D3D12_HEAP_FLAGS heapFlags)

+{

+    const bool allowBuffers         = (heapFlags & D3D12_HEAP_FLAG_DENY_BUFFERS           ) == 0;

+    const bool allowRtDsTextures    = (heapFlags & D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES    ) == 0;

+    const bool allowNonRtDsTextures = (heapFlags & D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES) == 0;

+

+    const uint8_t allowedGroupCount = (allowBuffers ? 1 : 0) + (allowRtDsTextures ? 1 : 0) + (allowNonRtDsTextures ? 1 : 0);

+    if(allowedGroupCount != 1)

+        return ResourceClass::Unknown;

+    

+    if(allowRtDsTextures)

+        return ResourceClass::RT_DS_Texture;

+    if(allowNonRtDsTextures)

+        return ResourceClass::Non_RT_DS_Texture;

+    return ResourceClass::Buffer;

+}

+

 // This algorithm is overly conservative.

 template<typename D3D12_RESOURCE_DESC_T>

 static bool CanUseSmallAlignment(const D3D12_RESOURCE_DESC_T& resourceDesc)

@@ -728,13 +764,6 @@
     return tileCount <= 16;

 }

 

-static D3D12_HEAP_FLAGS GetExtraHeapFlagsToIgnore()

-{

-    D3D12_HEAP_FLAGS result =

-        D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES | D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES;

-    return result;

-}

-

 static inline bool IsHeapTypeStandard(D3D12_HEAP_TYPE type)

 {

     return type == D3D12_HEAP_TYPE_DEFAULT ||

@@ -2644,8 +2673,6 @@
         void** ppvResource);

 #endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__

 

-    HRESULT SetMinBytes(UINT64 minBytes);

-

     void AddStats(StatInfo& outStats);

     void AddStats(Stats& outStats);

 

@@ -2659,7 +2686,6 @@
     const size_t m_MinBlockCount;

     const size_t m_MaxBlockCount;

     const bool m_ExplicitBlockSize;

-    UINT64 m_MinBytes;

     /* There can be at most one allocation that is completely empty - a

     hysteresis to avoid pessimistic case of alternating creation and destruction

     of a VkDeviceMemory. */

@@ -2754,8 +2780,6 @@
     const POOL_DESC& GetDesc() const { return m_Desc; }

     BlockVector* GetBlockVector() { return m_BlockVector; }

 

-    HRESULT SetMinBytes(UINT64 minBytes) { return m_BlockVector->SetMinBytes(minBytes); }

-

     void CalculateStats(StatInfo& outStats);

 

     void SetName(LPCWSTR Name);

@@ -2865,11 +2889,6 @@
         REFIID riidResource,

         void** ppvResource);

 

-    HRESULT SetDefaultHeapMinBytes(

-        D3D12_HEAP_TYPE heapType,

-        D3D12_HEAP_FLAGS heapFlags,

-        UINT64 minBytes);

-

     // Unregisters allocation from the collection of dedicated allocations.

     // Allocation object must be deleted externally afterwards.

     void FreeCommittedMemory(Allocation* allocation);

@@ -2934,11 +2953,6 @@
 

     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

-    D3D12MA_RW_MUTEX m_DefaultPoolMinBytesMutex;

-

     // Allocates and registers new committed resource with implicit heap, as dedicated allocation.

     // Creates and returns Allocation object.

     HRESULT AllocateCommittedResource(

@@ -3027,18 +3041,8 @@
         8: D3D12_HEAP_TYPE_READBACK + texture RT or DS

     */

     UINT CalcDefaultPoolCount() const;

-    template<typename D3D12_RESOURCE_DESC_T>

-    UINT CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, const D3D12_RESOURCE_DESC_T& resourceDesc) const;

-    // This one returns UINT32_MAX if nonstandard heap flags are used and index cannot be calculcated.

-    static UINT CalcDefaultPoolIndex(D3D12_HEAP_TYPE heapType, D3D12_HEAP_FLAGS heapFlags, bool supportsResourceHeapTier2);

-    UINT CalcDefaultPoolIndex(D3D12_HEAP_TYPE heapType, D3D12_HEAP_FLAGS heapFlags) const

-    {

-        return CalcDefaultPoolIndex(heapType, heapFlags, SupportsResourceHeapTier2());

-    }

-    UINT CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc) const

-    {

-        return CalcDefaultPoolIndex(allocDesc.HeapType, allocDesc.ExtraHeapFlags);

-    }

+    // Returns UINT32_MAX if index cannot be calculcated.

+    UINT CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, ResourceClass resourceClass) const;

     void CalcDefaultPoolParams(D3D12_HEAP_TYPE& outHeapType, D3D12_HEAP_FLAGS& outHeapFlags, UINT index) const;

 

     // Registers Pool object in m_Pools.

@@ -3860,7 +3864,6 @@
     m_MinBlockCount(minBlockCount),

     m_MaxBlockCount(maxBlockCount),

     m_ExplicitBlockSize(explicitBlockSize),

-    m_MinBytes(0),

     m_HasEmptyBlock(false),

     m_Blocks(hAllocator->GetAllocs()),

     m_NextBlockId(0)

@@ -4084,8 +4087,7 @@
         {

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

+                blockCount > m_MinBlockCount)

             {

                 pBlockToDelete = pBlock;

                 Remove(pBlock);

@@ -4101,8 +4103,7 @@
         else if(m_HasEmptyBlock && blockCount > m_MinBlockCount)

         {

             NormalBlock* pLastBlock = m_Blocks.back();

-            if(pLastBlock->m_pMetadata->IsEmpty() &&

-                sumBlockSize - pLastBlock->m_pMetadata->GetSize() >= m_MinBytes)

+            if(pLastBlock->m_pMetadata->IsEmpty())

             {

                 pBlockToDelete = pLastBlock;

                 m_Blocks.pop_back();

@@ -4328,89 +4329,6 @@
     return hr;

 }

 

-HRESULT BlockVector::SetMinBytes(UINT64 minBytes)

-{

-    MutexLockWrite lock(m_Mutex, m_hAllocator->UseMutex());

-

-    if(minBytes == m_MinBytes)

-    {

-        return S_OK;

-    }

-

-    HRESULT hr = S_OK;

-    UINT64 sumBlockSize = CalcSumBlockSize();

-    size_t 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(size_t blockIndex = blockCount; blockIndex--; )

-        {

-            NormalBlock* const block = m_Blocks[blockIndex];

-            const UINT64 size = block->m_pMetadata->GetSize();

-            const 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;

-                }

-            }

-        }

-    }

-    // New minBytes is larger - may need to allocate some blocks.

-    else

-    {

-        const UINT64 minBlockSize = m_PreferredBlockSize >> NEW_BLOCK_SIZE_SHIFT_MAX;

-        while(SUCCEEDED(hr) && sumBlockSize < minBytes)

-        {

-            if(blockCount < m_MaxBlockCount)

-            {

-                UINT64 newBlockSize = m_PreferredBlockSize;

-                if(!m_ExplicitBlockSize)

-                {

-                    if(sumBlockSize + newBlockSize > minBytes)

-                    {

-                        newBlockSize = minBytes - sumBlockSize;

-                    }

-                    // 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.

-                    else if(blockCount + 1 < m_MaxBlockCount &&

-                        sumBlockSize + newBlockSize + minBlockSize > minBytes)

-                    {

-                        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;

-}

-

 void BlockVector::AddStats(StatInfo& outStats)

 {

     MutexLockRead lock(m_Mutex, m_hAllocator->UseMutex());

@@ -4561,11 +4479,6 @@
     return m_Pimpl->GetDesc();

 }

 

-HRESULT Pool::SetMinBytes(UINT64 minBytes)

-{

-    return m_Pimpl->SetMinBytes(minBytes);

-}

-

 void Pool::CalculateStats(StatInfo* pStats)

 {

     D3D12MA_ASSERT(pStats);

@@ -4615,12 +4528,6 @@
     ZeroMemory(&m_D3D12Architecture, sizeof(m_D3D12Architecture));

 

     ZeroMemory(m_BlockVectors, sizeof(m_BlockVectors));

-    ZeroMemory(m_DefaultPoolTier1MinBytes, sizeof(m_DefaultPoolTier1MinBytes));

-

-    for(UINT i = 0; i < HEAP_TYPE_COUNT; ++i)

-    {

-        m_DefaultPoolHeapTypeMinBytes[i] = UINT64_MAX;

-    }

 

     for(UINT i = 0; i < STANDARD_HEAP_TYPE_COUNT; ++i)

     {

@@ -4790,7 +4697,8 @@
     }

     else

     {

-        const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, finalResourceDesc);

+        const ResourceClass resourceClass = ResourceDescToResourceClass(finalResourceDesc);

+        const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, resourceClass);

         const bool requireCommittedMemory = defaultPoolIndex == UINT32_MAX;

         if(requireCommittedMemory)

     {

@@ -4969,7 +4877,8 @@
     }

     else

     {

-        const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, finalResourceDesc);

+        const ResourceClass resourceClass = ResourceDescToResourceClass(finalResourceDesc);

+        const UINT defaultPoolIndex = CalcDefaultPoolIndex(*pAllocDesc, resourceClass);

         requireCommittedMemory = requireCommittedMemory || defaultPoolIndex == UINT32_MAX;

         if(requireCommittedMemory)

         {

@@ -5154,71 +5063,6 @@
         ppvResource);

 }

 

-HRESULT AllocatorPimpl::SetDefaultHeapMinBytes(

-    D3D12_HEAP_TYPE heapType,

-    D3D12_HEAP_FLAGS heapFlags,

-    UINT64 minBytes)

-{

-    if(!IsHeapTypeStandard(heapType))

-    {

-        D3D12MA_ASSERT(0 && "Allocator::SetDefaultHeapMinBytes: Invalid heapType passed.");

-        return E_INVALIDARG;

-    }

-

-    if(SupportsResourceHeapTier2())

-    {

-        if(heapFlags != D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES &&

-            heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS &&

-            heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES &&

-            heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES)

-        {

-            D3D12MA_ASSERT(0 && "Allocator::SetDefaultHeapMinBytes: Invalid heapFlags passed.");

-            return E_INVALIDARG;

-        }

-

-        UINT64 newMinBytes = UINT64_MAX;

-

-        {

-            MutexLockWrite lock(m_DefaultPoolMinBytesMutex, m_UseMutex);

-

-            if(heapFlags == D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES)

-            {

-                m_DefaultPoolHeapTypeMinBytes[HeapTypeToIndex(heapType)] = minBytes;

-                newMinBytes = minBytes;

-            }

-            else

-            {

-                const UINT defaultPoolTier1Index = CalcDefaultPoolIndex(heapType, heapFlags, false);

-                m_DefaultPoolTier1MinBytes[defaultPoolTier1Index] = minBytes;

-

-                newMinBytes = m_DefaultPoolHeapTypeMinBytes[HeapTypeToIndex(heapType)];

-                if(newMinBytes == UINT64_MAX)

-                {

-                    newMinBytes = m_DefaultPoolTier1MinBytes[CalcDefaultPoolIndex(heapType, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS, false)] +

-                        m_DefaultPoolTier1MinBytes[CalcDefaultPoolIndex(heapType, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, false)] +

-                        m_DefaultPoolTier1MinBytes[CalcDefaultPoolIndex(heapType, D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES, false)];

-                }

-            }

-        }

-

-        const UINT defaultPoolIndex = CalcDefaultPoolIndex(heapType, D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES);

-        return m_BlockVectors[defaultPoolIndex]->SetMinBytes(newMinBytes);

-    }

-    else

-    {

-        if(heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS &&

-            heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES &&

-            heapFlags != D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES)

-        {

-            D3D12MA_ASSERT(0 && "Allocator::SetDefaultHeapMinBytes: Invalid heapFlags passed.");

-            return E_INVALIDARG;

-        }

-        

-        const UINT defaultPoolIndex = CalcDefaultPoolIndex(heapType, heapFlags);

-        return m_BlockVectors[defaultPoolIndex]->SetMinBytes(minBytes);

-    }

-}

-

 template<typename D3D12_RESOURCE_DESC_T>

 bool AllocatorPimpl::PrefersCommittedAllocation(const D3D12_RESOURCE_DESC_T& resourceDesc)

 {

@@ -5553,10 +5397,9 @@
 

     if(allocDesc.CustomPool != NULL)

     {

-        if((allocDesc.Flags & ALLOCATION_FLAG_COMMITTED) == 0)

-        {

-            outBlockVector = allocDesc.CustomPool->m_Pimpl->GetBlockVector();

-        }

+        PoolPimpl* const pool = allocDesc.CustomPool->m_Pimpl;

+        outBlockVector = pool->GetBlockVector();

+        outCommittedAllocationList = &pool->m_CommittedAllocations;

     }

     else

     {

@@ -5564,32 +5407,49 @@
         {

             return E_INVALIDARG;

         }

-        if((allocDesc.Flags & ALLOCATION_FLAG_NEVER_ALLOCATE) == 0)

+

+        outCommittedAllocationList = &m_CommittedAllocations[HeapTypeToIndex(allocDesc.HeapType)];

+        

+        const ResourceClass resourceClass = (resDesc != NULL) ?

+            ResourceDescToResourceClass(*resDesc) : HeapFlagsToResourceClass(allocDesc.ExtraHeapFlags);

+        const UINT defaultPoolIndex = CalcDefaultPoolIndex(allocDesc, resourceClass);

+        if(defaultPoolIndex != UINT32_MAX)

         {

-            outCommittedAllocationList = &m_CommittedAllocations[HeapTypeToIndex(allocDesc.HeapType)];

-        }

-        if(!m_AlwaysCommitted &&

-            (allocDesc.Flags & ALLOCATION_FLAG_COMMITTED) == 0)

-        {

-            const UINT defaultPoolIndex = CalcDefaultPoolIndex(allocDesc);

-            if(defaultPoolIndex != UINT32_MAX)

+            outBlockVector = m_BlockVectors[defaultPoolIndex];

+            const UINT64 preferredBlockSize = outBlockVector->GetPreferredBlockSize();

+            if(allocSize > preferredBlockSize)

             {

-                outBlockVector = m_BlockVectors[defaultPoolIndex];

-                const UINT64 preferredBlockSize = outBlockVector->GetPreferredBlockSize();

-                if(allocSize > preferredBlockSize)

-                {

-                    outBlockVector = NULL;

-                }

-                else if(allocSize > preferredBlockSize / 2)

-                {

-                    // Heuristics: Allocate committed memory if requested size if greater than half of preferred block size.

-                    outPreferCommitted = true;

-                }

+                outBlockVector = NULL;

+            }

+            else if(allocSize > preferredBlockSize / 2)

+            {

+                // Heuristics: Allocate committed memory if requested size if greater than half of preferred block size.

+                outPreferCommitted = true;

             }

         }

+        

+        const D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS;

+        if(outBlockVector != NULL && extraHeapFlags != 0)

+        {

+            outBlockVector = NULL;

+        }

     }

-    if(resDesc != NULL && PrefersCommittedAllocation(*resDesc))

+

+    if((allocDesc.Flags & ALLOCATION_FLAG_COMMITTED) != 0 ||

+        m_AlwaysCommitted)

+    {

+        outBlockVector = NULL;

+    }

+    if((allocDesc.Flags & ALLOCATION_FLAG_NEVER_ALLOCATE) != 0)

+    {

+        outCommittedAllocationList = NULL;

+    }

+

+    if(resDesc != NULL && !outPreferCommitted && PrefersCommittedAllocation(*resDesc))

+    {

         outPreferCommitted = true;

+    }

+

     return S_OK;

 }

 

@@ -5605,10 +5465,9 @@
     }

 }

 

-template<typename D3D12_RESOURCE_DESC_T>

-UINT AllocatorPimpl::CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, const D3D12_RESOURCE_DESC_T& resourceDesc) const

+UINT AllocatorPimpl::CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, ResourceClass resourceClass) const

 {

-    const D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~GetExtraHeapFlagsToIgnore();

+    const D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS;

     if(extraHeapFlags != 0)

     {

         return UINT32_MAX;

@@ -5623,66 +5482,22 @@
     default: D3D12MA_ASSERT(0);

     }

 

-    if(!SupportsResourceHeapTier2())

+    if(SupportsResourceHeapTier2())

+        return poolIndex;

+    else

     {

-        poolIndex *= 3;

-        if(resourceDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER)

+        switch(resourceClass)

         {

-            ++poolIndex;

-            const bool isRenderTargetOrDepthStencil =

-                (resourceDesc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) != 0;

-            if(isRenderTargetOrDepthStencil)

-            {

-                ++poolIndex;

-            }

-        }

-    }

-

-    return poolIndex;

-}

-

-UINT AllocatorPimpl::CalcDefaultPoolIndex(D3D12_HEAP_TYPE heapType, D3D12_HEAP_FLAGS heapFlags, bool supportsResourceHeapTier2)

-{

-    const D3D12_HEAP_FLAGS extraHeapFlags = heapFlags & ~GetExtraHeapFlagsToIgnore();

-    if(extraHeapFlags != 0)

-    {

-        return UINT32_MAX;

-    }

-

-    UINT poolIndex = UINT_MAX;

-    switch(heapType)

-    {

-    case D3D12_HEAP_TYPE_DEFAULT:  poolIndex = 0; break;

-    case D3D12_HEAP_TYPE_UPLOAD:   poolIndex = 1; break;

-    case D3D12_HEAP_TYPE_READBACK: poolIndex = 2; break;

-    default: D3D12MA_ASSERT(0);

-    }

-

-    if(!supportsResourceHeapTier2)

-    {

-        poolIndex *= 3;

-

-        const bool allowBuffers = (heapFlags & D3D12_HEAP_FLAG_DENY_BUFFERS) == 0;

-        const bool allowRtDsTextures = (heapFlags & D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES) == 0;

-        const bool allowNonRtDsTextures = (heapFlags & D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES) == 0;

-

-        const uint8_t allowedGroupCount = (allowBuffers ? 1 : 0) + (allowRtDsTextures ? 1 : 0) + (allowNonRtDsTextures ? 1 : 0);

-        if(allowedGroupCount != 1)

-        {

+        case ResourceClass::Buffer:

+            return poolIndex * 3;

+        case ResourceClass::Non_RT_DS_Texture:

+            return poolIndex * 3 + 1;

+        case ResourceClass::RT_DS_Texture:

+            return poolIndex * 3 + 2;

+        default:

             return UINT32_MAX;

         }

-

-        if(!allowBuffers)

-        {

-            ++poolIndex;

-            if(allowRtDsTextures)

-            {

-                ++poolIndex;

-            }

-        }

     }

-

-    return poolIndex;

 }

 

 void AllocatorPimpl::CalcDefaultPoolParams(D3D12_HEAP_TYPE& outHeapType, D3D12_HEAP_FLAGS& outHeapFlags, UINT index) const

@@ -6597,15 +6412,6 @@
     return hr;

 }

 

-HRESULT Allocator::SetDefaultHeapMinBytes(

-    D3D12_HEAP_TYPE heapType,

-    D3D12_HEAP_FLAGS heapFlags,

-    UINT64 minBytes)

-{

-    D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK

-    return m_Pimpl->SetDefaultHeapMinBytes(heapType, heapFlags, minBytes);

-}

-

 void Allocator::SetCurrentFrameIndex(UINT frameIndex)

 {

     D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK

diff --git a/src/D3D12MemAlloc.h b/src/D3D12MemAlloc.h
index 8e66565..301964b 100644
--- a/src/D3D12MemAlloc.h
+++ b/src/D3D12MemAlloc.h
@@ -40,7 +40,6 @@
         - [Mapping memory](@ref quick_start_mapping_memory)

     - \subpage custom_pools

     - \subpage resource_aliasing

-    - \subpage reserving_memory

     - \subpage virtual_allocator

 - \subpage configuration

   - [Custom CPU memory allocator](@ref custom_memory_allocator)

@@ -413,43 +412,6 @@
   Otherwise they must be placed in different memory heap types, and thus aliasing them is not possible.

 

 

-\page reserving_memory Reserving minimum amount of memory

-

-The library automatically allocates and frees memory heaps.

-It also applies some hysteresis so that it doesn't allocate and free entire heap

-when you repeatedly create and release a single resource.

-However, if you want to make sure certain number of bytes is always allocated as heaps in a specific pool,

-you can use functions designed for this purpose:

-

-- For default heaps use D3D12MA::Allocator::SetDefaultHeapMinBytes.

-- For custom heaps use D3D12MA::Pool::SetMinBytes.

-

-Default is 0. You can change this parameter any time.

-Setting it to higher value may cause new heaps to be allocated.

-If this allocation fails, the function returns appropriate error code, but the parameter remains set to the new value.

-Setting it to lower value may cause some empty heaps to be released.

-

-You can always call D3D12MA::Allocator::SetDefaultHeapMinBytes for 3 sets of heap flags separately:

-`D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS`, `D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES`, `D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES`.

-When ResourceHeapTier = 2, so that all types of resourced are kept together,

-these 3 values as simply summed up to calculate minimum amount of bytes for default pool with certain heap type.

-Alternatively, when ResourceHeapTier = 2, you can call this function with

-`D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES` = 0. This will set a single value for the default pool and

-will override the sum of those three.

-

-Reservation of minimum number of bytes interacts correctly with

-D3D12MA::POOL_DESC::MinBlockCount and D3D12MA::POOL_DESC::MaxBlockCount.

-For example, free blocks (heaps) of a custom pool will be released only when

-their number doesn't fall below `MinBlockCount` and their sum size doesn't fall below `MinBytes`.

-

-Some restrictions apply:

-

-- Setting `MinBytes` doesn't interact with memory budget. The allocator tries

-  to create additional heaps when necessary without checking if they will exceed the budget.

-- Resources created as committed don't count into the number of bytes compared with `MinBytes` set.

-  Only placed resources are considered.

-

-

 \page virtual_allocator Virtual allocator

 

 As an extra feature, the core allocation algorithm of the library is exposed through a simple and convenient API of "virtual allocator".

@@ -1096,12 +1058,6 @@
     */

     POOL_DESC GetDesc() const;

 

-    /** \brief Sets the minimum number of bytes that should always be allocated (reserved) in this pool.

-

-    See also: \subpage reserving_memory.

-    */

-    HRESULT SetMinBytes(UINT64 minBytes);

-

     /** \brief Retrieves statistics from the current state of this pool.

     */

     void CalculateStats(StatInfo* pStats);

@@ -1457,20 +1413,6 @@
         const POOL_DESC* pPoolDesc,

         Pool** ppPool);

 

-    /** \brief Sets the minimum number of bytes that should always be allocated (reserved) in a specific default pool.

-

-    \param heapType Must be one of: `D3D12_HEAP_TYPE_DEFAULT`, `D3D12_HEAP_TYPE_UPLOAD`, `D3D12_HEAP_TYPE_READBACK`.

-    \param heapFlags Must be one of: `D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS`, `D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES`,

-        `D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES`. If ResourceHeapTier = 2, it can also be `D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES`.

-    \param minBytes Minimum number of bytes to keep allocated.

-

-    See also: \subpage reserving_memory.

-    */

-    HRESULT SetDefaultHeapMinBytes(

-        D3D12_HEAP_TYPE heapType,

-        D3D12_HEAP_FLAGS heapFlags,

-        UINT64 minBytes);

-

     /** \brief Sets the index of the current frame.

 

     This function is used to set the frame index in the allocator when a new game frame begins.

diff --git a/src/Tests.cpp b/src/Tests.cpp
index 69d4261..3c3bed1 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -606,22 +606,6 @@
     pool->SetName(NAME);

     CHECK_BOOL( wcscmp(pool->GetName(), NAME) == 0 );

 

-    // # SetMinBytes

-

-    CHECK_HR( pool->SetMinBytes(15 * MEGABYTE) );

-    pool->CalculateStats(&poolStats);

-    CHECK_BOOL( poolStats.BlockCount == 2 );

-    CHECK_BOOL( poolStats.AllocationCount == 0 );

-    CHECK_BOOL( poolStats.UsedBytes == 0 );

-    CHECK_BOOL( poolStats.UnusedBytes == poolStats.BlockCount * poolDesc.BlockSize );

-

-    CHECK_HR( pool->SetMinBytes(0) );

-    pool->CalculateStats(&poolStats);

-    CHECK_BOOL( poolStats.BlockCount == 1 );

-    CHECK_BOOL( poolStats.AllocationCount == 0 );

-    CHECK_BOOL( poolStats.UsedBytes == 0 );

-    CHECK_BOOL( poolStats.UnusedBytes == poolStats.BlockCount * poolDesc.BlockSize );

-

     // # Create buffers 2x 5 MB

 

     D3D12MA::ALLOCATION_DESC allocDesc = {};

@@ -806,26 +790,6 @@
     CHECK_HR(hr);

 }

 

-static void TestDefaultPoolMinBytes(const TestContext& ctx)

-{

-    D3D12MA::Stats stats;

-    ctx.allocator->CalculateStats(&stats);

-    const UINT64 gpuAllocatedBefore = stats.HeapType[0].UsedBytes + stats.HeapType[0].UnusedBytes;

-

-    const UINT64 gpuAllocatedMin = gpuAllocatedBefore * 105 / 100;

-    CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,            CeilDiv(gpuAllocatedMin, 3ull)) );

-    CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, CeilDiv(gpuAllocatedMin, 3ull)) );

-    CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES,     CeilDiv(gpuAllocatedMin, 3ull)) );

-

-    ctx.allocator->CalculateStats(&stats);

-    const UINT64 gpuAllocatedAfter = stats.HeapType[0].UsedBytes + stats.HeapType[0].UnusedBytes;

-    CHECK_BOOL(gpuAllocatedAfter >= gpuAllocatedMin);

-

-    CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,            0) );

-    CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, 0) );

-    CHECK_HR( ctx.allocator->SetDefaultHeapMinBytes(D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES,     0) );

-}

-

 static void TestAliasingMemory(const TestContext& ctx)

 {

     wprintf(L"Test aliasing memory\n");

@@ -1526,7 +1490,6 @@
     TestOtherComInterface(ctx);

     TestCustomPools(ctx);

     TestCustomHeaps(ctx);

-    TestDefaultPoolMinBytes(ctx);

     TestAliasingMemory(ctx);

     TestMapping(ctx);

     TestStats(ctx);