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