Skip to content

Commit 3924c72

Browse files
Improved TestCustomHeaps
1 parent 42981b7 commit 3924c72

File tree

1 file changed

+166
-135
lines changed

1 file changed

+166
-135
lines changed

src/Tests.cpp

Lines changed: 166 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,83 +1365,193 @@ static void TestCustomPool_AlwaysCommitted(const TestContext& ctx)
13651365
CHECK_BOOL(detailedStats.UnusedRangeSizeMax == 0);
13661366
}
13671367

1368-
static HRESULT TestCustomHeap(const TestContext& ctx, const D3D12_HEAP_PROPERTIES& heapProps)
1368+
static void CheckBudgetBasics(const TestContext& ctx,
1369+
const D3D12MA::Budget& localBudget, const D3D12MA::Budget& nonLocalBudget)
13691370
{
1370-
D3D12MA::TotalStatistics globalStatsBeg = {};
1371-
ctx.allocator->CalculateStatistics(&globalStatsBeg);
1372-
1373-
D3D12MA::CPOOL_DESC poolDesc = D3D12MA::CPOOL_DESC{
1374-
heapProps,
1375-
D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
1376-
D3D12MA::POOL_FLAG_NONE,
1377-
10 * MEGABYTE, // blockSize
1378-
1, // minBlockCount
1379-
1 }; // maxBlockCount
1380-
1381-
const UINT64 BUFFER_SIZE = 1 * MEGABYTE;
1371+
CHECK_BOOL(localBudget.BudgetBytes > 0);
1372+
CHECK_BOOL(localBudget.BudgetBytes <= ctx.allocator->GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_LOCAL));
1373+
CHECK_BOOL(localBudget.Stats.AllocationBytes <= localBudget.Stats.BlockBytes);
13821374

1383-
ComPtr<D3D12MA::Pool> pool;
1384-
HRESULT hr = ctx.allocator->CreatePool(&poolDesc, &pool);
1385-
if(SUCCEEDED(hr))
1375+
// Discrete graphics card with separate video memory.
1376+
if (!ctx.allocator->IsUMA())
13861377
{
1387-
D3D12MA::CALLOCATION_DESC allocDesc = D3D12MA::CALLOCATION_DESC{ pool.Get() };
1378+
CHECK_BOOL(nonLocalBudget.BudgetBytes > 0);
1379+
CHECK_BOOL(nonLocalBudget.BudgetBytes <= ctx.allocator->GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL));
1380+
CHECK_BOOL(nonLocalBudget.Stats.AllocationBytes <= nonLocalBudget.Stats.BlockBytes);
1381+
}
1382+
}
13881383

1389-
D3D12_RESOURCE_DESC resDesc;
1390-
FillResourceDescForBuffer(resDesc, BUFFER_SIZE);
1384+
static D3D12MA::DetailedStatistics GetEmptyDetailedStatistics()
1385+
{
1386+
D3D12MA::DetailedStatistics out = {};
1387+
out.AllocationSizeMin = UINT64_MAX;
1388+
out.UnusedRangeSizeMin = UINT64_MAX;
1389+
return out;
1390+
}
13911391

1392-
// Pool already allocated a block. We don't expect CreatePlacedResource to fail.
1393-
ComPtr<D3D12MA::Allocation> alloc;
1394-
CHECK_HR( ctx.allocator->CreateResource(&allocDesc, &resDesc,
1395-
D3D12_RESOURCE_STATE_COPY_DEST,
1396-
NULL, // pOptimizedClearValue
1397-
&alloc,
1398-
__uuidof(ID3D12Resource), NULL) ); // riidResource, ppvResource
1392+
static void AddDetailedStatistics(D3D12MA::DetailedStatistics& inoutSum, const D3D12MA::DetailedStatistics& stats)
1393+
{
1394+
inoutSum.Stats.AllocationBytes += stats.Stats.AllocationBytes;
1395+
inoutSum.Stats.AllocationCount += stats.Stats.AllocationCount;
1396+
inoutSum.Stats.BlockBytes += stats.Stats.BlockBytes;
1397+
inoutSum.Stats.BlockCount += stats.Stats.BlockCount;
1398+
inoutSum.UnusedRangeCount += stats.UnusedRangeCount;
1399+
inoutSum.AllocationSizeMax = std::max(inoutSum.AllocationSizeMax, stats.AllocationSizeMax);
1400+
inoutSum.AllocationSizeMin = std::min(inoutSum.AllocationSizeMin, stats.AllocationSizeMin);
1401+
inoutSum.UnusedRangeSizeMax = std::max(inoutSum.UnusedRangeSizeMax, stats.UnusedRangeSizeMax);
1402+
inoutSum.UnusedRangeSizeMin = std::min(inoutSum.UnusedRangeSizeMin, stats.UnusedRangeSizeMin);
1403+
}
13991404

1400-
D3D12MA::TotalStatistics globalStatsCurr = {};
1401-
ctx.allocator->CalculateStatistics(&globalStatsCurr);
1405+
static inline bool StatisticsEqual(const D3D12MA::DetailedStatistics& lhs, const D3D12MA::DetailedStatistics& rhs)
1406+
{
1407+
return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
1408+
}
14021409

1403-
// Make sure it is accounted only in CUSTOM heap not any of the standard heaps.
1404-
CHECK_BOOL(memcmp(&globalStatsCurr.HeapType[0], &globalStatsBeg.HeapType[0], sizeof(D3D12MA::DetailedStatistics)) == 0);
1405-
CHECK_BOOL(memcmp(&globalStatsCurr.HeapType[1], &globalStatsBeg.HeapType[1], sizeof(D3D12MA::DetailedStatistics)) == 0);
1406-
CHECK_BOOL(memcmp(&globalStatsCurr.HeapType[2], &globalStatsBeg.HeapType[2], sizeof(D3D12MA::DetailedStatistics)) == 0);
1407-
CHECK_BOOL( globalStatsCurr.HeapType[3].Stats.AllocationCount == globalStatsBeg.HeapType[3].Stats.AllocationCount + 1 );
1408-
CHECK_BOOL( globalStatsCurr.HeapType[3].Stats.BlockCount == globalStatsBeg.HeapType[3].Stats.BlockCount + 1 );
1409-
CHECK_BOOL( globalStatsCurr.HeapType[3].Stats.AllocationBytes == globalStatsBeg.HeapType[3].Stats.AllocationBytes + BUFFER_SIZE );
1410-
CHECK_BOOL( globalStatsCurr.Total.Stats.AllocationCount == globalStatsBeg.Total.Stats.AllocationCount + 1 );
1411-
CHECK_BOOL( globalStatsCurr.Total.Stats.BlockCount == globalStatsBeg.Total.Stats.BlockCount + 1 );
1412-
CHECK_BOOL( globalStatsCurr.Total.Stats.AllocationBytes == globalStatsBeg.Total.Stats.AllocationBytes + BUFFER_SIZE );
1410+
static inline bool StatisticsEqual(const D3D12MA::Statistics& lhs, const D3D12MA::Statistics& rhs)
1411+
{
1412+
return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
1413+
}
14131414

1414-
// Map and write some data.
1415-
if(heapProps.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE ||
1416-
heapProps.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)
1417-
{
1418-
ID3D12Resource* const res = alloc->GetResource();
1415+
static void CheckStatistics(const D3D12MA::DetailedStatistics& stats)
1416+
{
1417+
CHECK_BOOL(stats.Stats.AllocationBytes <= stats.Stats.BlockBytes);
1418+
if (stats.Stats.AllocationBytes > 0)
1419+
{
1420+
CHECK_BOOL(stats.Stats.AllocationCount > 0);
1421+
CHECK_BOOL(stats.AllocationSizeMin <= stats.AllocationSizeMax);
1422+
}
1423+
if (stats.UnusedRangeCount > 0)
1424+
{
1425+
CHECK_BOOL(stats.UnusedRangeSizeMax > 0);
1426+
CHECK_BOOL(stats.UnusedRangeSizeMin <= stats.UnusedRangeSizeMax);
1427+
}
1428+
}
14191429

1420-
UINT* mappedPtr = nullptr;
1421-
const D3D12_RANGE readRange = {0, 0};
1422-
CHECK_HR(res->Map(0, &readRange, (void**)&mappedPtr));
1423-
1424-
*mappedPtr = 0xDEADC0DE;
1425-
1426-
res->Unmap(0, nullptr);
1427-
}
1430+
static void CheckTotalStatistics(const D3D12MA::TotalStatistics& stats)
1431+
{
1432+
D3D12MA::DetailedStatistics sum = GetEmptyDetailedStatistics();
1433+
for (size_t i = 0; i < _countof(stats.HeapType); ++i)
1434+
{
1435+
AddDetailedStatistics(sum, stats.HeapType[i]);
14281436
}
1437+
CHECK_BOOL(StatisticsEqual(sum, stats.Total));
14291438

1430-
return hr;
1439+
sum = GetEmptyDetailedStatistics();
1440+
for (size_t i = 0; i < _countof(stats.MemorySegmentGroup); ++i)
1441+
{
1442+
AddDetailedStatistics(sum, stats.MemorySegmentGroup[i]);
1443+
}
1444+
CHECK_BOOL(StatisticsEqual(sum, stats.Total));
14311445
}
14321446

14331447
static void TestCustomHeaps(const TestContext& ctx)
14341448
{
1435-
wprintf(L"Test custom heap\n");
1449+
using namespace D3D12MA;
14361450

1437-
D3D12_HEAP_PROPERTIES heapProps = {};
1451+
wprintf(L"Test custom heap\n");
14381452

14391453
// Use custom pool but the same as READBACK, which should be always available.
1454+
D3D12_HEAP_PROPERTIES heapProps = {};
14401455
heapProps.Type = D3D12_HEAP_TYPE_CUSTOM;
14411456
heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
14421457
heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; // System memory
1443-
HRESULT hr = TestCustomHeap(ctx, heapProps);
1444-
CHECK_HR(hr);
1458+
1459+
const UINT64 BUFFER_SIZE = 1 * MEGABYTE;
1460+
D3D12_RESOURCE_DESC resDesc;
1461+
FillResourceDescForBuffer(resDesc, BUFFER_SIZE);
1462+
1463+
Budget localBudgetBeg = {}, nonLocalBudgetBeg = {};
1464+
ctx.allocator->GetBudget(&localBudgetBeg, &nonLocalBudgetBeg);
1465+
CheckBudgetBasics(ctx, localBudgetBeg, nonLocalBudgetBeg);
1466+
1467+
TotalStatistics globalStatsBeg = {};
1468+
ctx.allocator->CalculateStatistics(&globalStatsBeg);
1469+
CheckTotalStatistics(globalStatsBeg);
1470+
1471+
// Test 0: Custom pool with fixed block size (it must end up as placed).
1472+
// Test 1: Custom pool, requested committed.
1473+
1474+
for (size_t testIndex = 0; testIndex < 2; ++testIndex)
1475+
{
1476+
const bool requestCommitted = testIndex == 1;
1477+
1478+
POOL_DESC poolDesc = CPOOL_DESC{ heapProps, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS };
1479+
if (testIndex == 0)
1480+
{
1481+
poolDesc.BlockSize = 10 * MEGABYTE;
1482+
poolDesc.MinBlockCount = 1;
1483+
poolDesc.MaxBlockCount = 1;
1484+
}
1485+
ComPtr<Pool> pool;
1486+
CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));
1487+
1488+
ALLOCATION_DESC allocDesc = CALLOCATION_DESC{ pool.Get() };
1489+
if (requestCommitted)
1490+
{
1491+
allocDesc.Flags = ALLOCATION_FLAG_COMMITTED;
1492+
}
1493+
1494+
ComPtr<Allocation> alloc;
1495+
CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc,
1496+
D3D12_RESOURCE_STATE_COMMON, NULL, &alloc, IID_NULL, NULL));
1497+
1498+
const bool isCommitted = alloc->GetHeap() == NULL;
1499+
CHECK_BOOL(isCommitted == requestCommitted);
1500+
1501+
Budget localBudgetEnd = {}, nonLocalBudgetEnd = {};
1502+
ctx.allocator->GetBudget(&localBudgetEnd, &nonLocalBudgetEnd);
1503+
CheckBudgetBasics(ctx, localBudgetEnd, nonLocalBudgetEnd);
1504+
1505+
D3D12MA::TotalStatistics globalStatsEnd = {};
1506+
ctx.allocator->CalculateStatistics(&globalStatsEnd);
1507+
CheckTotalStatistics(globalStatsEnd);
1508+
1509+
// Make sure it is accounted only in CUSTOM heap not any of the standard heaps.
1510+
1511+
const UINT thisMemSegmentGroupIndex = ctx.allocator->IsUMA() ? 0 : 1;
1512+
const UINT otherMemSegmentGroupIndex = 1 - thisMemSegmentGroupIndex;
1513+
1514+
CHECK_BOOL(globalStatsEnd.Total.Stats.AllocationCount == globalStatsBeg.Total.Stats.AllocationCount + 1);
1515+
CHECK_BOOL(globalStatsEnd.Total.Stats.BlockCount == globalStatsBeg.Total.Stats.BlockCount + 1);
1516+
CHECK_BOOL(globalStatsEnd.Total.Stats.AllocationBytes == globalStatsBeg.Total.Stats.AllocationBytes + BUFFER_SIZE);
1517+
1518+
CHECK_BOOL(memcmp(&globalStatsEnd.HeapType[0], &globalStatsBeg.HeapType[0], sizeof(D3D12MA::DetailedStatistics)) == 0);
1519+
CHECK_BOOL(memcmp(&globalStatsEnd.HeapType[1], &globalStatsBeg.HeapType[1], sizeof(D3D12MA::DetailedStatistics)) == 0);
1520+
CHECK_BOOL(memcmp(&globalStatsEnd.HeapType[2], &globalStatsBeg.HeapType[2], sizeof(D3D12MA::DetailedStatistics)) == 0);
1521+
CHECK_BOOL(memcmp(&globalStatsEnd.HeapType[4], &globalStatsBeg.HeapType[4], sizeof(D3D12MA::DetailedStatistics)) == 0);
1522+
1523+
CHECK_BOOL(globalStatsEnd.HeapType[3].Stats.AllocationCount == globalStatsBeg.HeapType[3].Stats.AllocationCount + 1);
1524+
CHECK_BOOL(globalStatsEnd.HeapType[3].Stats.BlockCount == globalStatsBeg.HeapType[3].Stats.BlockCount + 1);
1525+
CHECK_BOOL(globalStatsEnd.HeapType[3].Stats.AllocationBytes == globalStatsBeg.HeapType[3].Stats.AllocationBytes + BUFFER_SIZE);
1526+
1527+
CHECK_BOOL(globalStatsEnd.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.AllocationCount ==
1528+
globalStatsBeg.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.AllocationCount + 1);
1529+
CHECK_BOOL(globalStatsEnd.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.BlockCount ==
1530+
globalStatsBeg.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.BlockCount + 1);
1531+
CHECK_BOOL(globalStatsEnd.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.AllocationBytes ==
1532+
globalStatsBeg.MemorySegmentGroup[thisMemSegmentGroupIndex].Stats.AllocationBytes + BUFFER_SIZE);
1533+
1534+
CHECK_BOOL(memcmp(&globalStatsEnd.MemorySegmentGroup[otherMemSegmentGroupIndex],
1535+
&globalStatsBeg.MemorySegmentGroup[otherMemSegmentGroupIndex], sizeof(D3D12MA::DetailedStatistics)) == 0);
1536+
1537+
const Budget& thisBudgetBeg = ctx.allocator->IsUMA() ? localBudgetBeg : nonLocalBudgetBeg;
1538+
const Budget& thisBudgetEnd = ctx.allocator->IsUMA() ? localBudgetEnd : nonLocalBudgetEnd;
1539+
1540+
CHECK_BOOL(thisBudgetEnd.Stats.AllocationCount == thisBudgetBeg.Stats.AllocationCount + 1);
1541+
CHECK_BOOL(thisBudgetEnd.Stats.BlockCount == thisBudgetBeg.Stats.BlockCount + 1);
1542+
CHECK_BOOL(thisBudgetEnd.Stats.AllocationBytes == thisBudgetBeg.Stats.AllocationBytes + BUFFER_SIZE);
1543+
1544+
// Map and write some data.
1545+
if (heapProps.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE ||
1546+
heapProps.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)
1547+
{
1548+
ID3D12Resource* const res = alloc->GetResource();
1549+
UINT* mappedPtr = nullptr;
1550+
CHECK_HR(res->Map(0, &EMPTY_RANGE, (void**)&mappedPtr));
1551+
*mappedPtr = 0xDEADC0DE;
1552+
res->Unmap(0, nullptr);
1553+
}
1554+
}
14451555
}
14461556

14471557
static void TestStandardCustomCommittedPlaced(const TestContext& ctx)
@@ -1694,85 +1804,6 @@ static void TestMapping(const TestContext& ctx)
16941804
}
16951805
}
16961806

1697-
static inline bool StatisticsEqual(const D3D12MA::DetailedStatistics& lhs, const D3D12MA::DetailedStatistics& rhs)
1698-
{
1699-
return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
1700-
}
1701-
1702-
static inline bool StatisticsEqual(const D3D12MA::Statistics& lhs, const D3D12MA::Statistics& rhs)
1703-
{
1704-
return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
1705-
}
1706-
1707-
static void CheckStatistics(const D3D12MA::DetailedStatistics& stats)
1708-
{
1709-
CHECK_BOOL(stats.Stats.AllocationBytes <= stats.Stats.BlockBytes);
1710-
if(stats.Stats.AllocationBytes > 0)
1711-
{
1712-
CHECK_BOOL(stats.Stats.AllocationCount > 0);
1713-
CHECK_BOOL(stats.AllocationSizeMin <= stats.AllocationSizeMax);
1714-
}
1715-
if(stats.UnusedRangeCount > 0)
1716-
{
1717-
CHECK_BOOL(stats.UnusedRangeSizeMax > 0);
1718-
CHECK_BOOL(stats.UnusedRangeSizeMin <= stats.UnusedRangeSizeMax);
1719-
}
1720-
}
1721-
1722-
static void CheckBudgetBasics(const TestContext& ctx,
1723-
const D3D12MA::Budget& localBudget, const D3D12MA::Budget& nonLocalBudget)
1724-
{
1725-
CHECK_BOOL(localBudget.BudgetBytes > 0);
1726-
CHECK_BOOL(localBudget.BudgetBytes <= ctx.allocator->GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_LOCAL));
1727-
CHECK_BOOL(localBudget.Stats.AllocationBytes <= localBudget.Stats.BlockBytes);
1728-
1729-
// Discrete graphics card with separate video memory.
1730-
if (!ctx.allocator->IsUMA())
1731-
{
1732-
CHECK_BOOL(nonLocalBudget.BudgetBytes > 0);
1733-
CHECK_BOOL(nonLocalBudget.BudgetBytes <= ctx.allocator->GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL));
1734-
CHECK_BOOL(nonLocalBudget.Stats.AllocationBytes <= nonLocalBudget.Stats.BlockBytes);
1735-
}
1736-
}
1737-
1738-
static D3D12MA::DetailedStatistics GetEmptyDetailedStatistics()
1739-
{
1740-
D3D12MA::DetailedStatistics out = {};
1741-
out.AllocationSizeMin = UINT64_MAX;
1742-
out.UnusedRangeSizeMin = UINT64_MAX;
1743-
return out;
1744-
}
1745-
1746-
static void AddDetailedStatistics(D3D12MA::DetailedStatistics& inoutSum, const D3D12MA::DetailedStatistics& stats)
1747-
{
1748-
inoutSum.Stats.AllocationBytes += stats.Stats.AllocationBytes;
1749-
inoutSum.Stats.AllocationCount += stats.Stats.AllocationCount;
1750-
inoutSum.Stats.BlockBytes += stats.Stats.BlockBytes;
1751-
inoutSum.Stats.BlockCount += stats.Stats.BlockCount;
1752-
inoutSum.UnusedRangeCount += stats.UnusedRangeCount;
1753-
inoutSum.AllocationSizeMax = std::max(inoutSum.AllocationSizeMax, stats.AllocationSizeMax);
1754-
inoutSum.AllocationSizeMin = std::min(inoutSum.AllocationSizeMin, stats.AllocationSizeMin);
1755-
inoutSum.UnusedRangeSizeMax = std::max(inoutSum.UnusedRangeSizeMax, stats.UnusedRangeSizeMax);
1756-
inoutSum.UnusedRangeSizeMin = std::min(inoutSum.UnusedRangeSizeMin, stats.UnusedRangeSizeMin);
1757-
}
1758-
1759-
static void CheckTotalStatistics(const D3D12MA::TotalStatistics& stats)
1760-
{
1761-
D3D12MA::DetailedStatistics sum = GetEmptyDetailedStatistics();
1762-
for (size_t i = 0; i < _countof(stats.HeapType); ++i)
1763-
{
1764-
AddDetailedStatistics(sum, stats.HeapType[i]);
1765-
}
1766-
CHECK_BOOL(StatisticsEqual(sum, stats.Total));
1767-
1768-
sum = GetEmptyDetailedStatistics();
1769-
for (size_t i = 0; i < _countof(stats.MemorySegmentGroup); ++i)
1770-
{
1771-
AddDetailedStatistics(sum, stats.MemorySegmentGroup[i]);
1772-
}
1773-
CHECK_BOOL(StatisticsEqual(sum, stats.Total));
1774-
}
1775-
17761807
static void TestStats(const TestContext& ctx)
17771808
{
17781809
using namespace D3D12MA;

0 commit comments

Comments
 (0)