Added POOL_DESC::MinAllocationAlignment
diff --git a/src/D3D12MemAlloc.cpp b/src/D3D12MemAlloc.cpp
index 9706e31..f38e597 100644
--- a/src/D3D12MemAlloc.cpp
+++ b/src/D3D12MemAlloc.cpp
@@ -2637,7 +2637,8 @@
UINT64 preferredBlockSize,
size_t minBlockCount,
size_t maxBlockCount,
- bool explicitBlockSize);
+ bool explicitBlockSize,
+ UINT64 minAllocationAlignment);
~BlockVector();
HRESULT CreateMinBlocks();
@@ -2695,6 +2696,7 @@
const size_t m_MinBlockCount;
const size_t m_MaxBlockCount;
const bool m_ExplicitBlockSize;
+ const UINT64 m_MinAllocationAlignment;
/* 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. */
@@ -3864,7 +3866,8 @@
UINT64 preferredBlockSize,
size_t minBlockCount,
size_t maxBlockCount,
- bool explicitBlockSize) :
+ bool explicitBlockSize,
+ UINT64 minAllocationAlignment) :
m_hAllocator(hAllocator),
m_HeapProps(heapProps),
m_HeapFlags(heapFlags),
@@ -3872,6 +3875,7 @@
m_MinBlockCount(minBlockCount),
m_MaxBlockCount(maxBlockCount),
m_ExplicitBlockSize(explicitBlockSize),
+ m_MinAllocationAlignment(minAllocationAlignment),
m_HasEmptyBlock(false),
m_Blocks(hAllocator->GetAllocs()),
m_NextBlockId(0)
@@ -4290,6 +4294,8 @@
ALLOCATION_FLAGS allocFlags,
Allocation** pAllocation)
{
+ alignment = D3D12MA_MAX(alignment, m_MinAllocationAlignment);
+
AllocationRequest currRequest = {};
if(pBlock->m_pMetadata->CreateAllocationRequest(
size,
@@ -4412,7 +4418,8 @@
allocator, desc.HeapProperties, heapFlags,
preferredBlockSize,
desc.MinBlockCount, maxBlockCount,
- explicitBlockSize);
+ explicitBlockSize,
+ D3D12MA_MAX(desc.MinAllocationAlignment, (UINT64)D3D12MA_DEBUG_ALIGNMENT));
}
HRESULT PoolPimpl::Init()
@@ -4608,7 +4615,8 @@
m_PreferredBlockSize,
0, // minBlockCount
SIZE_MAX, // maxBlockCount
- false); // explicitBlockSize
+ false, // explicitBlockSize
+ D3D12MA_DEBUG_ALIGNMENT); // minAllocationAlignment
// No need to call m_pBlockVectors[i]->CreateMinBlocks here, becase minBlockCount is 0.
}
@@ -4685,7 +4693,6 @@
D3D12_RESOURCE_DESC finalResourceDesc = *pResourceDesc;
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
- resAllocInfo.Alignment = D3D12MA_MAX<UINT64>(resAllocInfo.Alignment, D3D12MA_DEBUG_ALIGNMENT);
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
@@ -4755,7 +4762,6 @@
D3D12_RESOURCE_DESC finalResourceDesc = *pResourceDesc;
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
- resAllocInfo.Alignment = D3D12MA_MAX<UINT64>(resAllocInfo.Alignment, D3D12MA_DEBUG_ALIGNMENT);
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
@@ -4807,7 +4813,6 @@
D3D12_RESOURCE_DESC1 finalResourceDesc = *pResourceDesc;
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
- resAllocInfo.Alignment = D3D12MA_MAX<UINT64>(resAllocInfo.Alignment, D3D12MA_DEBUG_ALIGNMENT);
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
@@ -4945,7 +4950,6 @@
D3D12_RESOURCE_DESC resourceDesc2 = *pResourceDesc;
D3D12_RESOURCE_ALLOCATION_INFO resAllocInfo = GetResourceAllocationInfo(resourceDesc2);
- resAllocInfo.Alignment = D3D12MA_MAX<UINT64>(resAllocInfo.Alignment, D3D12MA_DEBUG_ALIGNMENT);
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
@@ -6225,7 +6229,8 @@
Pool** ppPool)
{
if(!pPoolDesc || !ppPool ||
- (pPoolDesc->MaxBlockCount > 0 && pPoolDesc->MaxBlockCount < pPoolDesc->MinBlockCount))
+ (pPoolDesc->MaxBlockCount > 0 && pPoolDesc->MaxBlockCount < pPoolDesc->MinBlockCount) ||
+ (pPoolDesc->MinAllocationAlignment > 0 && !IsPow2(pPoolDesc->MinAllocationAlignment)))
{
D3D12MA_ASSERT(0 && "Invalid arguments passed to Allocator::CreatePool.");
return E_INVALIDARG;
diff --git a/src/D3D12MemAlloc.h b/src/D3D12MemAlloc.h
index ded69c3..8b8674a 100644
--- a/src/D3D12MemAlloc.h
+++ b/src/D3D12MemAlloc.h
@@ -1053,6 +1053,11 @@
throughout whole lifetime of this pool.
*/
UINT MaxBlockCount;
+ /** \brief Additional minimum alignment to be used for all allocations created from this pool. Can be 0.
+
+ Leave 0 (default) not to impose any additional alignment. If not 0, it must be a power of two.
+ */
+ UINT64 MinAllocationAlignment;
};
/** \brief Custom memory pool
diff --git a/src/Tests.cpp b/src/Tests.cpp
index f3784be..4bd44df 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -711,6 +711,43 @@
IID_PPV_ARGS(&res)) );
}
+static void TestCustomPool_MinAllocationAlignment(const TestContext& ctx)
+{
+ wprintf(L"Test custom pool MinAllocationAlignment\n");
+
+ const UINT64 BUFFER_SIZE = 32;
+ constexpr size_t BUFFER_COUNT = 4;
+ const UINT64 MIN_ALIGNMENT = 128 * 1024;
+
+ D3D12MA::POOL_DESC poolDesc = {};
+ poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
+ poolDesc.HeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
+ poolDesc.MinAllocationAlignment = MIN_ALIGNMENT;
+
+ D3D12MA::Pool* poolPtr;
+ CHECK_HR( ctx.allocator->CreatePool(&poolDesc, &poolPtr) );
+ PoolUniquePtr pool{poolPtr};
+
+ D3D12MA::Allocation* allocPtr;
+ D3D12MA::ALLOCATION_DESC allocDesc = {};
+ allocDesc.CustomPool = pool.get();
+
+ D3D12_RESOURCE_DESC resDesc;
+ FillResourceDescForBuffer(resDesc, BUFFER_SIZE);
+
+ AllocationUniquePtr allocs[BUFFER_COUNT];
+ for(size_t i = 0; i < BUFFER_COUNT; ++i)
+ {
+ CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
+ D3D12_RESOURCE_STATE_GENERIC_READ,
+ NULL, // pOptimizedClearValue
+ &allocPtr,
+ IID_NULL, NULL) ); // riidResource, ppvResource
+ allocs[i].reset(allocPtr);
+ CHECK_BOOL(allocPtr->GetOffset() % MIN_ALIGNMENT == 0);
+ }
+}
+
static HRESULT TestCustomHeap(const TestContext& ctx, const D3D12_HEAP_PROPERTIES& heapProps)
{
D3D12MA::Stats globalStatsBeg = {};
@@ -1589,6 +1626,7 @@
TestPlacedResources(ctx);
TestOtherComInterface(ctx);
TestCustomPools(ctx);
+ TestCustomPool_MinAllocationAlignment(ctx);
TestCustomHeaps(ctx);
TestStandardCustomCommittedPlaced(ctx);
TestAliasingMemory(ctx);