Added POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT

Hopefully helps for https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator/issues/91
diff --git a/include/D3D12MemAlloc.h b/include/D3D12MemAlloc.h
index c34d1d7..735fb3b 100644
--- a/include/D3D12MemAlloc.h
+++ b/include/D3D12MemAlloc.h
@@ -889,10 +889,17 @@
     */

     POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED = 0x2,

     /** Every allocation made in this pool will be created as a committed resource - will have its own memory block.

-    

+     

     There is also an equivalent flag for the entire allocator: D3D12MA::ALLOCATOR_FLAG_ALWAYS_COMMITTED.

     */

     POOL_FLAG_ALWAYS_COMMITTED = 0x4,

+    /** Disables tight resource alignment for all resources created from this pool.

+    

+    When tight alignment is supported and enabled for the allocator, resources created from custom pools

+    normally use it automatically. Specify this flag to restore pre-tight-alignment behavior for this pool:

+    tight alignment won't be requested and small buffers may again be preferred as committed resources.

+    */

+    POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT = 0x8,

 

     // Bit mask to extract only `ALGORITHM` bits from entire set of flags.

     POOL_FLAG_ALGORITHM_MASK = POOL_FLAG_ALGORITHM_LINEAR

@@ -1114,7 +1121,8 @@
     It can also be disabled for a single allocation by using #ALLOCATION_FLAG_STRATEGY_MIN_TIME.

 

     If the tight resource alignment feature is used by the library (which happens automatically whenever supported,

-    unless you use flag #ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT), then small buffers are not preferred as committed.

+    unless you use flag #ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT or

+    #POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT on a custom pool), then small buffers are not preferred as committed.

     Long story short, you don't need to specify any of these flags.

     The library chooses the most optimal method automatically.

     */

@@ -2892,6 +2900,7 @@
 

 You can check if the tight alignment it is available in the current system by calling D3D12MA::Allocator::IsTightAlignmentSupported().

 You can tell the library to not use it by specifying D3D12MA::ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT.

+Custom pools can opt out independently by specifying D3D12MA::POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT.

 Typically, you don't need to do any of those.

 

 The library automatically aligns all buffers to at least 256 B, even when the system supports smaller alignment.

diff --git a/src/D3D12MemAlloc.cpp b/src/D3D12MemAlloc.cpp
index 7ebf580..b5a56d0 100644
--- a/src/D3D12MemAlloc.cpp
+++ b/src/D3D12MemAlloc.cpp
@@ -6086,7 +6086,7 @@
     const bool m_UseMutex;

     const bool m_AlwaysCommitted;

     const bool m_MsaaAlwaysCommitted;

-    bool m_PreferSmallBuffersCommitted;

+    const bool m_PreferSmallBuffersCommitted;

     const bool m_UseTightAlignment;

     bool m_DefaultPoolsNotZeroed = false;

     ID3D12Device* m_Device; // AddRef

@@ -6131,7 +6131,7 @@
     */

     template<typename D3D12_RESOURCE_DESC_T>

     bool PrefersCommittedAllocation(const D3D12_RESOURCE_DESC_T& resourceDesc,

-        ALLOCATION_FLAGS strategy);

+        ALLOCATION_FLAGS strategy, bool useTightAlignment) const;

 

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

     // Creates and returns Allocation object and optionally D3D12 resource.

@@ -6151,6 +6151,7 @@
     template<typename D3D12_RESOURCE_DESC_T>

     HRESULT CalcAllocationParams(const ALLOCATION_DESC& allocDesc, UINT64 allocSize,

         const D3D12_RESOURCE_DESC_T* resDesc, // Optional

+        bool useTightAlignment,

         BlockVector*& outBlockVector, CommittedAllocationParameters& outCommittedAllocationParams, bool& outPreferCommitted);

 

     // Returns UINT32_MAX if index cannot be calculcated.

@@ -6184,7 +6185,10 @@
     template<typename D3D12_RESOURCE_DESC_T>

     HRESULT GetResourceAllocationInfo(D3D12_RESOURCE_DESC_T& inOutResourceDesc,

         UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats,

-        D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const;

+        D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo,

+        bool useTightAlignment) const;

+

+    bool IsTightAlignmentEnabled(const ALLOCATION_DESC& allocDesc) const;

 

     bool NewAllocationWithinBudget(D3D12_HEAP_TYPE heapType, UINT64 size);

 

@@ -6295,13 +6299,6 @@
         {

             m_TightAlignmentSupported = tightAlignment.SupportTier >= D3D12_TIGHT_ALIGNMENT_TIER_1;

             

-            // If tight alignment is supported (checked by the code above) and wasn't disabled by the developer

-            // (with ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT), disable the preference for creating small buffers as committed,

-            // as if ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED was specified.

-            if (IsTightAlignmentEnabled())

-            {

-                m_PreferSmallBuffersCommitted = false;

-            }

         }

     }

 #endif // #if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED

@@ -6500,6 +6497,7 @@
     }

 

     HRESULT hr = E_NOINTERFACE;

+    const bool useTightAlignment = IsTightAlignmentEnabled(*pAllocDesc);

     CREATE_RESOURCE_PARAMS finalCreateParams = createParams;

     D3D12_RESOURCE_DESC finalResourceDesc;

 #ifdef __ID3D12Device8_INTERFACE_DEFINED__

@@ -6510,7 +6508,7 @@
     {

         finalResourceDesc = *createParams.GetResourceDesc();

         finalCreateParams.AccessResourceDesc() = &finalResourceDesc;

-        hr = GetResourceAllocationInfo(finalResourceDesc, 0, NULL, resAllocInfo);

+        hr = GetResourceAllocationInfo(finalResourceDesc, 0, NULL, resAllocInfo, useTightAlignment);

     }

 #ifdef __ID3D12Device8_INTERFACE_DEFINED__

     else if (createParams.Variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)

@@ -6519,7 +6517,7 @@
         {

             finalResourceDesc1 = *createParams.GetResourceDesc1();

             finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;

-            hr = GetResourceAllocationInfo(finalResourceDesc1, 0, NULL, resAllocInfo);

+            hr = GetResourceAllocationInfo(finalResourceDesc1, 0, NULL, resAllocInfo, useTightAlignment);

         }

     }

 #endif

@@ -6531,7 +6529,7 @@
             finalResourceDesc1 = *createParams.GetResourceDesc1();

             finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;

             hr = GetResourceAllocationInfo(finalResourceDesc1,

-                createParams.GetNumCastableFormats(), createParams.GetCastableFormats(), resAllocInfo);

+                createParams.GetNumCastableFormats(), createParams.GetCastableFormats(), resAllocInfo, useTightAlignment);

         }

     }

 #endif

@@ -6557,14 +6555,14 @@
     if (createParams.Variant >= CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)

     {

         hr = CalcAllocationParams<D3D12_RESOURCE_DESC1>(*pAllocDesc, resAllocInfo.SizeInBytes,

-            createParams.GetResourceDesc1(),

+            createParams.GetResourceDesc1(), useTightAlignment,

             blockVector, committedAllocationParams, preferCommitted);

     }

     else

 #endif

     {

         hr = CalcAllocationParams<D3D12_RESOURCE_DESC>(*pAllocDesc, resAllocInfo.SizeInBytes,

-            createParams.GetResourceDesc(),

+            createParams.GetResourceDesc(), useTightAlignment,

             blockVector, committedAllocationParams, preferCommitted);

     }

     if (FAILED(hr))

@@ -6611,6 +6609,7 @@
     bool preferCommitted = false;

     HRESULT hr = CalcAllocationParams<D3D12_RESOURCE_DESC>(*pAllocDesc, pAllocInfo->SizeInBytes,

         NULL, // pResDesc

+        false, // useTightAlignment - irrelevant for AllocateMemory

         blockVector, committedAllocationParams, preferCommitted);

     if (FAILED(hr))

         return hr;

@@ -6659,7 +6658,7 @@
     {

         finalResourceDesc = *createParams.GetResourceDesc();

         finalCreateParams.AccessResourceDesc() = &finalResourceDesc;

-        hr = GetResourceAllocationInfo(finalResourceDesc, 0, NULL, resAllocInfo);

+        hr = GetResourceAllocationInfo(finalResourceDesc, 0, NULL, resAllocInfo, IsTightAlignmentEnabled());

     }

 #ifdef __ID3D12Device8_INTERFACE_DEFINED__

     else if (createParams.Variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)

@@ -6668,7 +6667,7 @@
         {

             finalResourceDesc1 = *createParams.GetResourceDesc1();

             finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;

-            hr = GetResourceAllocationInfo(finalResourceDesc1, 0, NULL, resAllocInfo);

+            hr = GetResourceAllocationInfo(finalResourceDesc1, 0, NULL, resAllocInfo, IsTightAlignmentEnabled());

         }

     }

 #endif

@@ -6680,7 +6679,7 @@
             finalResourceDesc1 = *createParams.GetResourceDesc1();

             finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;

             hr = GetResourceAllocationInfo(finalResourceDesc1,

-                createParams.GetNumCastableFormats(), createParams.GetCastableFormats(), resAllocInfo);

+                createParams.GetNumCastableFormats(), createParams.GetCastableFormats(), resAllocInfo, IsTightAlignmentEnabled());

         }

     }

 #endif

@@ -7315,13 +7314,14 @@
 

 template<typename D3D12_RESOURCE_DESC_T>

 bool AllocatorPimpl::PrefersCommittedAllocation(const D3D12_RESOURCE_DESC_T& resourceDesc,

-    ALLOCATION_FLAGS strategy)

+    ALLOCATION_FLAGS strategy, bool useTightAlignment) const

 {

     // Prefer creating small buffers <= 32 KB as committed, because drivers pack them better,

     // while placed buffers require 64 KB alignment.

     if(resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&

         resourceDesc.Width <= D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT / 2 &&

         strategy != ALLOCATION_FLAG_STRATEGY_MIN_TIME &&  // Creating as committed would be slower.

+        !useTightAlignment &&

         m_PreferSmallBuffersCommitted)

     {

         return true;

@@ -7536,7 +7536,7 @@
 

 template<typename D3D12_RESOURCE_DESC_T>

 HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, UINT64 allocSize,

-    const D3D12_RESOURCE_DESC_T* resDesc,

+    const D3D12_RESOURCE_DESC_T* resDesc, bool useTightAlignment,

     BlockVector*& outBlockVector, CommittedAllocationParameters& outCommittedAllocationParams, bool& outPreferCommitted)

 {

     outBlockVector = NULL;

@@ -7609,7 +7609,7 @@
     {

         if (resDesc->SampleDesc.Count > 1 && msaaAlwaysCommitted)

             outBlockVector = NULL;

-        if (!outPreferCommitted && PrefersCommittedAllocation(*resDesc, allocDesc.Flags & ALLOCATION_FLAG_STRATEGY_MASK))

+        if (!outPreferCommitted && PrefersCommittedAllocation(*resDesc, allocDesc.Flags & ALLOCATION_FLAG_STRATEGY_MASK, useTightAlignment))

             outPreferCommitted = true;

     }

 

@@ -7820,12 +7820,13 @@
 HRESULT AllocatorPimpl::GetResourceAllocationInfo(

     D3D12_RESOURCE_DESC_T& inOutResourceDesc,

     UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats,

-    D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const

+    D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo,

+    bool useTightAlignment) const

 {

 #ifdef __ID3D12Device1_INTERFACE_DEFINED__

 

 #if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED

-    if (IsTightAlignmentEnabled())

+    if (useTightAlignment)

     {

         // Don't allow USE_TIGHT_ALIGNMENT together with ALLOW_CROSS_ADAPTER as there is a D3D Debug Layer error:

         // D3D12 ERROR: ID3D12Device::GetResourceAllocationInfo: D3D12_RESOURCE_DESC::Flag D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT will be ignored since D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER is set. [ STATE_CREATION ERROR #599: CREATERESOURCE_INVALIDMISCFLAGS]

@@ -7849,7 +7850,7 @@
     */

     if (inOutResourceDesc.Alignment == 0 &&

         inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&

-        !IsTightAlignmentEnabled())

+        !useTightAlignment)

     {

         outAllocInfo = {

             AlignUp<UINT64>(inOutResourceDesc.Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), // SizeInBytes

@@ -7896,6 +7897,20 @@
         inOutResourceDesc, NumCastableFormats, pCastableFormats, outAllocInfo);

 }

 

+bool AllocatorPimpl::IsTightAlignmentEnabled(const ALLOCATION_DESC& allocDesc) const

+{

+    if (!IsTightAlignmentEnabled())

+        return false;

+

+    if (allocDesc.CustomPool != NULL &&

+        (allocDesc.CustomPool->m_Pimpl->GetDesc().Flags & POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT) != 0)

+    {

+        return false;

+    }

+

+    return true;

+}

+

 bool AllocatorPimpl::NewAllocationWithinBudget(D3D12_HEAP_TYPE heapType, UINT64 size)

 {

     Budget budget = {};

diff --git a/src/Tests.cpp b/src/Tests.cpp
index 9e00157..42e402e 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -730,70 +730,77 @@
 

     const bool isTightAlignmentEnabled = ctx.allocator->IsTightAlignmentSupported() &&

         (ctx.allocatorFlags & D3D12MA::ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT) == 0;

-    const bool expectSmallBuffersCommitted = !isTightAlignmentEnabled &&

+    const bool allowSmallBuffersCommitted =

         (ctx.allocatorFlags & D3D12MA::ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED) == 0;

-        

+    const bool expectSmallBuffersCommitted = !isTightAlignmentEnabled &&

+        allowSmallBuffersCommitted;

 

-    D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{

-        D3D12_HEAP_TYPE_DEFAULT,

-        D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };

-    ComPtr<D3D12MA::Pool> pool;

-    CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

-

-    D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

-

-    D3D12_RESOURCE_DESC resDesc;

-    FillResourceDescForBuffer(resDesc, 8 * KILOBYTE);

-

-    D3D12_RESOURCE_DESC largeResDesc = resDesc;

-    largeResDesc.Width = 128 * KILOBYTE;

-

-    std::vector<ResourceWithAllocation> resources;

-

-    // A large buffer placed inside the heap to allocate first block.

+    const auto testPool = [&](D3D12MA::POOL_FLAGS poolFlags, bool expectDefaultCommitted)

     {

-        resources.emplace_back();

-        ResourceWithAllocation& resWithAlloc = resources.back();

-        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &largeResDesc, D3D12_RESOURCE_STATE_COMMON,

-            nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));

-        CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());

-        CHECK_BOOL(resWithAlloc.allocation->GetHeap()); // Expected to be placed.

-    }

+        D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{

+            D3D12_HEAP_TYPE_DEFAULT,

+            D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,

+            poolFlags };

+        ComPtr<D3D12MA::Pool> pool;

+        CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

 

-    // Test 1: COMMITTED.

-    {

-        resources.emplace_back();

-        ResourceWithAllocation& resWithAlloc = resources.back();

-        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;

-        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,

-            nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));

-        CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());

-        CHECK_BOOL(!resWithAlloc.allocation->GetHeap()); // Expected to be committed.

-    }

+        D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };

 

-    // Test 2: Default.

-    {

-        resources.emplace_back();

-        ResourceWithAllocation& resWithAlloc = resources.back();

-        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;

-        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,

-            nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));

-        CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());

-        // Expected to be committed?

-        const bool isCommitted = resWithAlloc.allocation->GetHeap() == NULL;

-        CHECK_BOOL(isCommitted == expectSmallBuffersCommitted);

-    }

+        D3D12_RESOURCE_DESC resDesc;

+        FillResourceDescForBuffer(resDesc, 8 * KILOBYTE);

 

-    // Test 3: NEVER_ALLOCATE.

-    {

-        resources.emplace_back();

-        ResourceWithAllocation& resWithAlloc = resources.back();

-        allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;

-        CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,

-            nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));

-        CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());

-        CHECK_BOOL(resWithAlloc.allocation->GetHeap()); // Expected to be placed.

-    }

+        D3D12_RESOURCE_DESC largeResDesc = resDesc;

+        largeResDesc.Width = 128 * KILOBYTE;

+

+        std::vector<ResourceWithAllocation> resources;

+

+        // A large buffer placed inside the heap to allocate first block.

+        {

+            resources.emplace_back();

+            ResourceWithAllocation& resWithAlloc = resources.back();

+            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &largeResDesc, D3D12_RESOURCE_STATE_COMMON,

+                nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));

+            CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());

+            CHECK_BOOL(resWithAlloc.allocation->GetHeap()); // Expected to be placed.

+        }

+

+        // Test 1: COMMITTED.

+        {

+            resources.emplace_back();

+            ResourceWithAllocation& resWithAlloc = resources.back();

+            allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;

+            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,

+                nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));

+            CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());

+            CHECK_BOOL(!resWithAlloc.allocation->GetHeap()); // Expected to be committed.

+        }

+

+        // Test 2: Default.

+        {

+            resources.emplace_back();

+            ResourceWithAllocation& resWithAlloc = resources.back();

+            allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;

+            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,

+                nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));

+            CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());

+            const bool isCommitted = resWithAlloc.allocation->GetHeap() == NULL;

+            CHECK_BOOL(isCommitted == expectDefaultCommitted);

+        }

+

+        // Test 3: NEVER_ALLOCATE.

+        {

+            resources.emplace_back();

+            ResourceWithAllocation& resWithAlloc = resources.back();

+            allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;

+            CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COMMON,

+                nullptr, &resWithAlloc.allocation, IID_PPV_ARGS(&resWithAlloc.resource)));

+            CHECK_BOOL(resWithAlloc.allocation && resWithAlloc.allocation->GetResource());

+            CHECK_BOOL(resWithAlloc.allocation->GetHeap()); // Expected to be placed.

+        }

+    };

+

+    testPool(D3D12MA::POOL_FLAG_NONE, expectSmallBuffersCommitted);

+    testPool(D3D12MA::POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT, allowSmallBuffersCommitted);

 }

 

 static void TestCustomHeapFlags(const TestContext& ctx)

@@ -3373,45 +3380,51 @@
     for (auto heapType : heapTypes)

     {

         poolDesc.HeapProperties.Type = heapType;

-        for (uint32_t minAlignmentTestIndex = 0; minAlignmentTestIndex < 2; ++minAlignmentTestIndex)

+        for (uint32_t poolFlagsIndex = 0; poolFlagsIndex < 2; ++poolFlagsIndex)

         {

-            // MinAllocationAlignment == 0 - default alignment.

-            // MinAllocationAlignment == 1 - minimum possible alignment.

-            poolDesc.MinAllocationAlignment = minAlignmentTestIndex;

-

-            ComPtr<Pool> pool;

-            CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

-

-            ALLOCATION_DESC allocDesc = {};

-            allocDesc.CustomPool = pool.Get();

-

-            ComPtr<Allocation> allocs[2] = {};

-

-            for (size_t i = 0; i < _countof(allocs); ++i)

+            poolDesc.Flags = poolFlagsIndex == 0 ? POOL_FLAG_NONE : POOL_FLAG_DONT_USE_TIGHT_ALIGNMENT;

+            const bool isPoolTightAlignmentEnabled = isTightAlignmentEnabled && poolDesc.Flags == POOL_FLAG_NONE;

+            for (uint32_t minAlignmentTestIndex = 0; minAlignmentTestIndex < 2; ++minAlignmentTestIndex)

             {

-                CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc,

-                    D3D12_RESOURCE_STATE_COMMON, NULL, &allocs[i], IID_NULL, NULL));

-                CHECK_BOOL(allocs[i] && allocs[i]->GetResource());

+                // MinAllocationAlignment == 0 - default alignment.

+                // MinAllocationAlignment == 1 - minimum possible alignment.

+                poolDesc.MinAllocationAlignment = minAlignmentTestIndex;

+

+                ComPtr<Pool> pool;

+                CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));

+

+                ALLOCATION_DESC allocDesc = {};

+                allocDesc.CustomPool = pool.Get();

+

+                ComPtr<Allocation> allocs[2] = {};

+

+                for (size_t i = 0; i < _countof(allocs); ++i)

+                {

+                    CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc,

+                        D3D12_RESOURCE_STATE_COMMON, NULL, &allocs[i], IID_NULL, NULL));

+                    CHECK_BOOL(allocs[i] && allocs[i]->GetResource());

+                }

+

+                const UINT64 secondAllocOffset = allocs[1]->GetOffset();

+

+                // Print the offset of the 2nd buffer.

+                wprintf(L"    In D3D12_HEAP_TYPE_%s, with Flags=0x%X, MinAllocationAlignment=%llu, a %llu B buffer was aligned to %llu B.\n",

+                    HEAP_TYPE_NAMES[(size_t)heapType],

+                    poolDesc.Flags,

+                    poolDesc.MinAllocationAlignment,

+                    resDesc.Width,

+                    secondAllocOffset);

+

+                UINT64 expectedMinAlignment = 1;

+                if (isPoolTightAlignmentEnabled)

+                {

+                    if (minAlignmentTestIndex == 0)

+                        expectedMinAlignment = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;

+                }

+                else

+                    expectedMinAlignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;

+                CHECK_BOOL(secondAllocOffset % expectedMinAlignment == 0);

             }

-

-            const UINT64 secondAllocOffset = allocs[1]->GetOffset();

-

-            // Print the offset of the 2nd buffer.

-            wprintf(L"    In D3D12_HEAP_TYPE_%s, with MinAllocationAlignment=%llu, a %llu B buffer was aligned to %llu B.\n",

-                HEAP_TYPE_NAMES[(size_t)heapType],

-                poolDesc.MinAllocationAlignment,

-                resDesc.Width,

-                secondAllocOffset);

-

-            UINT64 expectedMinAlignment = 1;

-            if (isTightAlignmentEnabled)

-            {

-                if (minAlignmentTestIndex == 0)

-                    expectedMinAlignment = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;

-            }

-            else

-                expectedMinAlignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;

-            CHECK_BOOL(secondAllocOffset % expectedMinAlignment == 0);

         }

     }

 }