Added POOL_DESC::MinAllocationAlignment

This commit is contained in:
Adam Sawicki 2021-06-18 16:17:16 +02:00
parent 10f148cef0
commit ea913f3849
3 changed files with 57 additions and 9 deletions

View File

@ -2637,7 +2637,8 @@ public:
UINT64 preferredBlockSize,
size_t minBlockCount,
size_t maxBlockCount,
bool explicitBlockSize);
bool explicitBlockSize,
UINT64 minAllocationAlignment);
~BlockVector();
HRESULT CreateMinBlocks();
@ -2695,6 +2696,7 @@ private:
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 @@ BlockVector::BlockVector(
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 @@ BlockVector::BlockVector(
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 @@ HRESULT BlockVector::AllocateFromBlock(
ALLOCATION_FLAGS allocFlags,
Allocation** pAllocation)
{
alignment = D3D12MA_MAX(alignment, m_MinAllocationAlignment);
AllocationRequest currRequest = {};
if(pBlock->m_pMetadata->CreateAllocationRequest(
size,
@ -4412,7 +4418,8 @@ PoolPimpl::PoolPimpl(AllocatorPimpl* allocator, const POOL_DESC& desc) :
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 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
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 @@ HRESULT AllocatorPimpl::CreateResource(
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 @@ HRESULT AllocatorPimpl::CreateResource1(
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 @@ HRESULT AllocatorPimpl::CreateResource2(
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 @@ HRESULT AllocatorPimpl::CreateAliasingResource(
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 @@ HRESULT Allocator::CreatePool(
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;

View File

@ -1053,6 +1053,11 @@ struct POOL_DESC
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

View File

@ -711,6 +711,43 @@ static void TestCustomPools(const TestContext& ctx)
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 @@ static void TestGroupBasics(const TestContext& ctx)
TestPlacedResources(ctx);
TestOtherComInterface(ctx);
TestCustomPools(ctx);
TestCustomPool_MinAllocationAlignment(ctx);
TestCustomHeaps(ctx);
TestStandardCustomCommittedPlaced(ctx);
TestAliasingMemory(ctx);