@@ -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
14331447static 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
14471557static 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-
17761807static void TestStats (const TestContext& ctx)
17771808{
17781809 using namespace D3D12MA ;
0 commit comments