Added tests: TestPoolsAndAllocationParameters
diff --git a/src/Tests.cpp b/src/Tests.cpp
index bd7a669..8b011cc 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -678,6 +678,128 @@
IID_PPV_ARGS(&res)) );
}
+static void TestPoolsAndAllocationParameters(const TestContext& ctx)
+{
+ wprintf(L"Test pools and allocation parameters\n");
+
+ ComPtr<D3D12MA::Pool> pool1, pool2;
+ std::vector<ComPtr<D3D12MA::Allocation>> bufs;
+
+ D3D12MA::ALLOCATION_DESC allocDesc = {};
+
+ uint32_t totalNewAllocCount = 0, totalNewBlockCount = 0;
+ D3D12MA::Stats statsBeg, statsEnd;
+ ctx.allocator->CalculateStats(&statsBeg);
+
+ HRESULT hr;
+ ComPtr<D3D12MA::Allocation> alloc;
+
+ // poolTypeI:
+ // 0 = default pool
+ // 1 = custom pool, default (flexible) block size and block count
+ // 2 = custom pool, fixed block size and limited block count
+ for(size_t poolTypeI = 0; poolTypeI < 3; ++poolTypeI)
+ {
+ if(poolTypeI == 0)
+ {
+ allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
+ allocDesc.CustomPool = nullptr;
+ }
+ else if(poolTypeI == 1)
+ {
+ D3D12MA::POOL_DESC poolDesc = {};
+ poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
+ poolDesc.HeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
+ hr = ctx.allocator->CreatePool(&poolDesc, &pool1);
+ CHECK_HR(hr);
+ allocDesc.CustomPool = pool1.Get();
+ }
+ else if(poolTypeI == 2)
+ {
+ D3D12MA::POOL_DESC poolDesc = {};
+ poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
+ poolDesc.HeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
+ poolDesc.MaxBlockCount = 1;
+ poolDesc.BlockSize = 2 * MEGABYTE + MEGABYTE / 2; // 2.5 MB
+ hr = ctx.allocator->CreatePool(&poolDesc, &pool2);
+ CHECK_HR(hr);
+ allocDesc.CustomPool = pool2.Get();
+ }
+
+ uint32_t poolAllocCount = 0, poolBlockCount = 0;
+ D3D12_RESOURCE_DESC resDesc;
+ FillResourceDescForBuffer(resDesc, MEGABYTE);
+
+ // Default parameters
+ allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NONE;
+ hr = ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &alloc, IID_NULL, nullptr);
+ CHECK_BOOL(SUCCEEDED(hr) && alloc && alloc->GetResource());
+ ID3D12Heap* const defaultAllocHeap = alloc->GetHeap();
+ const UINT64 defaultAllocOffset = alloc->GetOffset();
+ bufs.push_back(std::move(alloc));
+ ++poolAllocCount;
+
+ // COMMITTED. Should not try pool2 as it may assert on invalid call.
+ if(poolTypeI != 2)
+ {
+ allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_COMMITTED;
+ hr = ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &alloc, IID_NULL, nullptr);
+ CHECK_BOOL(SUCCEEDED(hr) && alloc && alloc->GetResource());
+ CHECK_BOOL(alloc->GetOffset() == 0); // Committed
+ CHECK_BOOL(alloc->GetHeap() == nullptr); // Committed
+ bufs.push_back(std::move(alloc));
+ ++poolAllocCount;
+ }
+
+ // NEVER_ALLOCATE #1
+ allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;
+ hr = ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &alloc, IID_NULL, nullptr);
+ CHECK_BOOL(SUCCEEDED(hr) && alloc && alloc->GetResource());
+ CHECK_BOOL(alloc->GetHeap() == defaultAllocHeap); // Same memory block as default one.
+ CHECK_BOOL(alloc->GetOffset() != defaultAllocOffset);
+ bufs.push_back(std::move(alloc));
+ ++poolAllocCount;
+
+ // NEVER_ALLOCATE #2. Should fail in pool2 as it has no space.
+ allocDesc.Flags = D3D12MA::ALLOCATION_FLAG_NEVER_ALLOCATE;
+ hr = ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &alloc, IID_NULL, nullptr);
+ if(poolTypeI == 2)
+ CHECK_BOOL(FAILED(hr));
+ else
+ {
+ CHECK_BOOL(SUCCEEDED(hr) && alloc && alloc->GetResource());
+ bufs.push_back(std::move(alloc));
+ ++poolAllocCount;
+ }
+
+ // Pool stats
+ switch(poolTypeI)
+ {
+ case 0: poolBlockCount = 1; break; // At least 1 added for dedicated allocation.
+ case 1: poolBlockCount = 2; break; // 1 for custom pool block and 1 for dedicated allocation.
+ case 2: poolBlockCount = 1; break; // Only custom pool, no dedicated allocation.
+ }
+
+ if(poolTypeI > 0)
+ {
+ D3D12MA::StatInfo poolStats = {};
+ (poolTypeI == 2 ? pool2 : pool1)->CalculateStats(&poolStats);
+ CHECK_BOOL(poolStats.AllocationCount == poolAllocCount);
+ CHECK_BOOL(poolStats.UsedBytes == poolAllocCount * MEGABYTE);
+ CHECK_BOOL(poolStats.BlockCount == poolBlockCount);
+ }
+
+ totalNewAllocCount += poolAllocCount;
+ totalNewBlockCount += poolBlockCount;
+ }
+
+ ctx.allocator->CalculateStats(&statsEnd);
+
+ CHECK_BOOL(statsEnd.Total.AllocationCount == statsBeg.Total.AllocationCount + totalNewAllocCount);
+ CHECK_BOOL(statsEnd.Total.BlockCount >= statsBeg.Total.BlockCount + totalNewBlockCount);
+ CHECK_BOOL(statsEnd.Total.UsedBytes == statsBeg.Total.UsedBytes + totalNewAllocCount * MEGABYTE);
+}
+
static void TestCustomPool_MinAllocationAlignment(const TestContext& ctx)
{
wprintf(L"Test custom pool MinAllocationAlignment\n");
@@ -1598,6 +1720,7 @@
TestCustomPools(ctx);
TestCustomPool_MinAllocationAlignment(ctx);
TestCustomPool_Committed(ctx);
+ TestPoolsAndAllocationParameters(ctx);
TestCustomHeaps(ctx);
TestStandardCustomCommittedPlaced(ctx);
TestAliasingMemory(ctx);