From d1b8b1c7fc625851f7e69eabf376f45f8476f05c Mon Sep 17 00:00:00 2001 From: "Bernhart, Bryan" Date: Thu, 9 Feb 2023 11:39:49 -0800 Subject: [PATCH] Replace GetStats with QueryStats. Also, renames RESIDENCY_STATS => RESIDENCY_MANAGER_STATS for consistency. --- include/gpgmm_d3d12.h | 23 ++-- src/fuzzers/D3D12ResidencyManagerFuzzer.cpp | 9 +- src/gpgmm/d3d12/ResidencyManagerD3D12.cpp | 16 ++- src/gpgmm/d3d12/ResidencyManagerD3D12.h | 6 +- src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp | 24 +++-- src/gpgmm/d3d12/ResourceAllocatorD3D12.h | 4 +- src/mvi/gpgmm_d3d12.cpp | 8 +- src/mvi/gpgmm_d3d12.h | 4 +- src/tests/D3D12Test.cpp | 14 +++ src/tests/D3D12Test.h | 7 ++ .../D3D12EventTraceReplay.cpp | 4 +- .../end2end/D3D12ResidencyManagerTests.cpp | 46 ++++---- .../end2end/D3D12ResourceAllocatorTests.cpp | 100 +++++++++--------- 13 files changed, 159 insertions(+), 106 deletions(-) diff --git a/include/gpgmm_d3d12.h b/include/gpgmm_d3d12.h index fc549043f..d6da474b8 100644 --- a/include/gpgmm_d3d12.h +++ b/include/gpgmm_d3d12.h @@ -411,10 +411,10 @@ namespace gpgmm::d3d12 { uint64_t InitialFenceValue; }; - /** \struct RESIDENCY_STATS + /** \struct RESIDENCY_MANAGER_STATS Additional information about residency manager usage. */ - struct RESIDENCY_STATS { + struct RESIDENCY_MANAGER_STATS { /** \brief Amount of memory, in bytes, currently resident. */ uint64_t CurrentMemoryUsage; @@ -504,11 +504,15 @@ namespace gpgmm::d3d12 { */ virtual HRESULT SetResidencyState(IHeap * pHeap, const RESIDENCY_STATUS& state) = 0; - /** \brief Return the current residency manager usage. + /** \brief Query the current residency usage. - \return A RESIDENCY_STATS struct. + @param pResidencyManagerStats A pointer to a RESIDENCY_MANAGER_STATS structure or NULL if + statistics information should only be gathered for recording. + + \return Returns S_OK if successful. Returns S_FALSE if statistics information was only + gathered for recording. */ - virtual RESIDENCY_STATS GetStats() const = 0; + virtual HRESULT QueryStats(RESIDENCY_MANAGER_STATS * pResidencyManagerStats) = 0; }; /** \brief Create residency residency manager to manage video memory. @@ -1143,15 +1147,20 @@ namespace gpgmm::d3d12 { */ virtual uint64_t ReleaseMemory(uint64_t bytesToRelease) = 0; - /** \brief Return the current allocator usage. + /** \brief Query the current allocator usage. Returned info can be used to monitor memory usage per allocator. For example, the amount of internal fragmentation is equal to UsedBlockUsage / UsedMemoryUsage. Or the percent of recycled memory is equal to FreeMemoryUsage / (UsedMemoryUsage + FreeMemoryUsage) * 100%. + @param pResourceAllocatorStats A pointer to a RESOURCE_ALLOCATOR_STATS structure or NULL if + statistics information should only be gathered for recording. + + \return Returns S_OK if successful. Returns S_FALSE if statistics information was only + gathered for recording. */ - virtual RESOURCE_ALLOCATOR_STATS GetStats() const = 0; + virtual HRESULT QueryStats(RESOURCE_ALLOCATOR_STATS * pResourceAllocatorStats) = 0; /** \brief Gets information about the features that are supported by the resource allocator. diff --git a/src/fuzzers/D3D12ResidencyManagerFuzzer.cpp b/src/fuzzers/D3D12ResidencyManagerFuzzer.cpp index 755e79d65..fe9f3e8d7 100644 --- a/src/fuzzers/D3D12ResidencyManagerFuzzer.cpp +++ b/src/fuzzers/D3D12ResidencyManagerFuzzer.cpp @@ -40,6 +40,13 @@ namespace { : 0; } + gpgmm::d3d12::RESOURCE_ALLOCATOR_STATS GetStats( + ComPtr resourceAllocator) { + gpgmm::d3d12::RESOURCE_ALLOCATOR_STATS stats = {}; + resourceAllocator->QueryStats(&stats); + return stats; + } + } // namespace extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { @@ -91,7 +98,7 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) { // Keep allocating until we reach the budget. uint64_t memoryUnderBudget = GetBudgetLeft(gResidencyManager.Get(), bufferMemorySegment); - while (gResourceAllocator->GetStats().UsedMemoryUsage + kBufferMemorySize < memoryUnderBudget) { + while (GetStats(gResourceAllocator).UsedMemoryUsage + kBufferMemorySize < memoryUnderBudget) { ComPtr allocation; if (FAILED(gResourceAllocator->CreateResource({}, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation))) { diff --git a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp index ad638d78d..d024972ee 100644 --- a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp +++ b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp @@ -853,12 +853,12 @@ namespace gpgmm::d3d12 { return S_OK; } - RESIDENCY_STATS ResidencyManager::GetStats() const { + HRESULT ResidencyManager::QueryStats(RESIDENCY_MANAGER_STATS* pResidencyManagerStats) { std::lock_guard lock(mMutex); - return GetStatsInternal(); + return QueryStatsInternal(pResidencyManagerStats); } - RESIDENCY_STATS ResidencyManager::GetStatsInternal() const { + HRESULT ResidencyManager::QueryStatsInternal(RESIDENCY_MANAGER_STATS* pResidencyManagerStats) { TRACE_EVENT0(TraceEventCategory::kDefault, "ResidencyManager.GetStats"); // Heaps inserted into the residency cache are not resident until MakeResident() is called @@ -867,7 +867,7 @@ namespace gpgmm::d3d12 { // Locked heaps are not stored in the residency cache, so usage must be tracked by the // residency manager on Lock/Unlock then added here to get the sum. - RESIDENCY_STATS result = mStats; + RESIDENCY_MANAGER_STATS result = mStats; for (const auto& entry : mLocalVideoMemorySegment.cache) { if (entry.value()->GetInfo().Status == RESIDENCY_STATUS_CURRENT_RESIDENT) { @@ -886,7 +886,13 @@ namespace gpgmm::d3d12 { GPGMM_TRACE_EVENT_METRIC("GPU currently resident (MB)", GPGMM_BYTES_TO_MB(result.CurrentMemoryUsage)); - return result; + if (pResidencyManagerStats != nullptr) { + *pResidencyManagerStats = result; + } else { + return S_FALSE; + } + + return S_OK; } // Starts updating video memory budget from OS notifications. diff --git a/src/gpgmm/d3d12/ResidencyManagerD3D12.h b/src/gpgmm/d3d12/ResidencyManagerD3D12.h index d89f0ea4a..f451e48fd 100644 --- a/src/gpgmm/d3d12/ResidencyManagerD3D12.h +++ b/src/gpgmm/d3d12/ResidencyManagerD3D12.h @@ -63,7 +63,7 @@ namespace gpgmm::d3d12 { DXGI_QUERY_VIDEO_MEMORY_INFO* pVideoMemoryInfoOut) override; HRESULT SetResidencyState(IHeap* pHeap, const RESIDENCY_STATUS& state) override; - RESIDENCY_STATS GetStats() const override; + HRESULT QueryStats(RESIDENCY_MANAGER_STATS* pResidencyManagerStats) override; DEFINE_Unknown_OVERRIDES() @@ -84,7 +84,7 @@ namespace gpgmm::d3d12 { HRESULT InsertHeapInternal(Heap* heap); - RESIDENCY_STATS GetStatsInternal() const; + HRESULT QueryStatsInternal(RESIDENCY_MANAGER_STATS* pResidencyManagerStats); friend BudgetUpdateTask; HRESULT UpdateMemorySegments(); @@ -139,7 +139,7 @@ namespace gpgmm::d3d12 { VideoMemorySegment mLocalVideoMemorySegment; VideoMemorySegment mNonLocalVideoMemorySegment; - RESIDENCY_STATS mStats = {}; + RESIDENCY_MANAGER_STATS mStats = {}; std::shared_ptr mBudgetNotificationUpdateEvent; }; diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 013cabda9..adca34e7a 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -866,7 +866,7 @@ namespace gpgmm::d3d12 { // Update allocation metrics. if (bytesReleased > 0) { - GetStatsInternal(); + QueryStatsInternal(nullptr); } return bytesReleased; @@ -896,7 +896,7 @@ namespace gpgmm::d3d12 { // Update the current usage counters. if (mUseDetailedTimingEvents) { - GetStatsInternal(); + ReturnIfFailed(QueryStatsInternal(nullptr)); } #if defined(GPGMM_ENABLE_MEMORY_ALIGN_CHECKS) @@ -1049,7 +1049,10 @@ namespace gpgmm::d3d12 { // If over-budget, only free memory is considered available. // TODO: Consider optimizing GetStatsInternal(). if (currentVideoInfo->CurrentUsage > currentVideoInfo->Budget) { - request.AvailableForAllocation = GetStatsInternal().FreeMemoryUsage; + RESOURCE_ALLOCATOR_STATS allocationStats = {}; + ReturnIfFailed(QueryStatsInternal(&allocationStats)); + + request.AvailableForAllocation = allocationStats.FreeMemoryUsage; DebugEvent(this) << "Current usage exceeded budget (" << std::to_string(currentVideoInfo->CurrentUsage) << " vs " @@ -1403,12 +1406,13 @@ namespace gpgmm::d3d12 { return S_OK; } - RESOURCE_ALLOCATOR_STATS ResourceAllocator::GetStats() const { + HRESULT ResourceAllocator::QueryStats(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats) { std::lock_guard lock(mMutex); - return GetStatsInternal(); + return QueryStatsInternal(pResourceAllocatorStats); } - RESOURCE_ALLOCATOR_STATS ResourceAllocator::GetStatsInternal() const { + HRESULT ResourceAllocator::QueryStatsInternal( + RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats) { TRACE_EVENT0(TraceEventCategory::kDefault, "ResourceAllocator.GetInfo"); // ResourceAllocator itself could call CreateCommittedResource directly. @@ -1443,7 +1447,13 @@ namespace gpgmm::d3d12 { "GPU allocation size cache hits (%)", SafeDivide(result.SizeCacheHits, result.SizeCacheMisses + result.SizeCacheHits) * 100); - return result; + if (pResourceAllocatorStats != nullptr) { + *pResourceAllocatorStats = result; + } else { + return S_FALSE; + } + + return S_OK; } // static diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h index 7385d18b0..d4a39962e 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h @@ -92,7 +92,7 @@ namespace gpgmm::d3d12 { ID3D12Resource* pCommittedResource, IResourceAllocation** ppResourceAllocationOut) override; uint64_t ReleaseMemory(uint64_t bytesToRelease) override; - RESOURCE_ALLOCATOR_STATS GetStats() const override; + HRESULT QueryStats(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats) override; HRESULT CheckFeatureSupport(ALLOCATOR_FEATURE feature, void* pFeatureSupportData, uint32_t featureSupportDataSize) const override; @@ -168,7 +168,7 @@ namespace gpgmm::d3d12 { // MemoryAllocator interface void DeallocateMemory(std::unique_ptr allocation) override; - RESOURCE_ALLOCATOR_STATS GetStatsInternal() const; + HRESULT QueryStatsInternal(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats); ID3D12Device* mDevice = nullptr; ComPtr mResidencyManager; diff --git a/src/mvi/gpgmm_d3d12.cpp b/src/mvi/gpgmm_d3d12.cpp index b94d37ac3..8898d6362 100644 --- a/src/mvi/gpgmm_d3d12.cpp +++ b/src/mvi/gpgmm_d3d12.cpp @@ -199,8 +199,8 @@ namespace gpgmm::d3d12 { return S_OK; } - RESIDENCY_STATS ResidencyManager::GetStats() const { - return {0, 0}; + HRESULT ResidencyManager::QueryStats(RESIDENCY_MANAGER_STATS* pResidencyManagerStats) { + return E_NOTIMPL; } ResidencyManager::ResidencyManager(const RESIDENCY_DESC& descriptor) @@ -384,8 +384,8 @@ namespace gpgmm::d3d12 { return 0; } - RESOURCE_ALLOCATOR_STATS ResourceAllocator::GetStats() const { - return mStats; + HRESULT ResourceAllocator::QueryStats(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats) { + return E_NOTIMPL; } HRESULT ResourceAllocator::CheckFeatureSupport(ALLOCATOR_FEATURE feature, diff --git a/src/mvi/gpgmm_d3d12.h b/src/mvi/gpgmm_d3d12.h index 1a6639467..f8938283c 100644 --- a/src/mvi/gpgmm_d3d12.h +++ b/src/mvi/gpgmm_d3d12.h @@ -123,7 +123,7 @@ namespace gpgmm::d3d12 { HRESULT QueryVideoMemoryInfo(const DXGI_MEMORY_SEGMENT_GROUP& memorySegmentGroup, DXGI_QUERY_VIDEO_MEMORY_INFO* pVideoMemoryInfoOut) override; HRESULT SetResidencyState(IHeap* pHeap, const RESIDENCY_STATUS& state) override; - RESIDENCY_STATS GetStats() const override; + HRESULT QueryStats(RESIDENCY_MANAGER_STATS* pResidencyManagerStats) override; // IUnknown interface HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override; @@ -218,7 +218,7 @@ namespace gpgmm::d3d12 { ID3D12Resource* pCommittedResource, IResourceAllocation** ppResourceAllocationOut) override; uint64_t ReleaseMemory(uint64_t bytesToRelease) override; - RESOURCE_ALLOCATOR_STATS GetStats() const override; + HRESULT QueryStats(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats) override; HRESULT CheckFeatureSupport(ALLOCATOR_FEATURE feature, void* pFeatureSupportData, uint32_t featureSupportDataSize) const override; diff --git a/src/tests/D3D12Test.cpp b/src/tests/D3D12Test.cpp index 5b7520c40..275759625 100644 --- a/src/tests/D3D12Test.cpp +++ b/src/tests/D3D12Test.cpp @@ -18,6 +18,8 @@ #include "gpgmm/common/SizeClass.h" #include "gpgmm/d3d12/CapsD3D12.h" +#include "gpgmm/d3d12/ResidencyManagerD3D12.h" +#include "gpgmm/d3d12/ResourceAllocatorD3D12.h" #include "gpgmm/utils/WindowsUtils.h" namespace gpgmm::d3d12 { @@ -46,6 +48,18 @@ namespace gpgmm::d3d12 { return unknown->Release(); } + RESOURCE_ALLOCATOR_STATS GetStats(ComPtr resourceAllocator) { + RESOURCE_ALLOCATOR_STATS stats = {}; + resourceAllocator->QueryStats(&stats); + return stats; + } + + RESIDENCY_MANAGER_STATS GetStats(ComPtr residencyManager) { + RESIDENCY_MANAGER_STATS stats = {}; + residencyManager->QueryStats(&stats); + return stats; + } + void D3D12TestBase::SetUp() { GPGMMTestBase::SetUp(); diff --git a/src/tests/D3D12Test.h b/src/tests/D3D12Test.h index 1740efd5d..c04aedb7a 100644 --- a/src/tests/D3D12Test.h +++ b/src/tests/D3D12Test.h @@ -19,6 +19,7 @@ #include +#include #include "gpgmm/d3d12/d3d12_platform.h" #define ASSERT_FAILED(expr) ASSERT_TRUE(FAILED(expr)) @@ -36,9 +37,15 @@ namespace gpgmm::d3d12 { class Caps; + GPGMM_INTERFACE IResourceAllocator; + GPGMM_INTERFACE IResidencyManager; + D3D12_MESSAGE_SEVERITY GetMessageSeverity(MessageSeverity MessageSeverity); long GetRefCount(IUnknown* unknown); + RESOURCE_ALLOCATOR_STATS GetStats(ComPtr resourceAllocator); + RESIDENCY_MANAGER_STATS GetStats(ComPtr residencyManager); + class D3D12TestBase : public GPGMMTestBase { public: void SetUp(); diff --git a/src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp b/src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp index bfbbbf195..794274aff 100644 --- a/src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp +++ b/src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp @@ -301,7 +301,7 @@ class D3D12EventTraceReplay : public D3D12TestBase, public CaptureReplayTestWith playbackContext.currentAllocatorID); ASSERT_TRUE(it != playbackContext.CreatedAllocatorsToID.end()); - IResourceAllocator* resourceAllocator = + ComPtr resourceAllocator = playbackContext .CreatedAllocatorsToID[playbackContext.currentAllocatorID] .Get(); @@ -330,7 +330,7 @@ class D3D12EventTraceReplay : public D3D12TestBase, public CaptureReplayTestWith } mReplayedMemoryStats.PeakUsage = - std::max(resourceAllocator->GetStats().UsedMemoryUsage, + std::max(GetStats(resourceAllocator).UsedMemoryUsage, mReplayedMemoryStats.PeakUsage); } break; diff --git a/src/tests/end2end/D3D12ResidencyManagerTests.cpp b/src/tests/end2end/D3D12ResidencyManagerTests.cpp index 56df44d62..7aa00f49a 100644 --- a/src/tests/end2end/D3D12ResidencyManagerTests.cpp +++ b/src/tests/end2end/D3D12ResidencyManagerTests.cpp @@ -203,8 +203,8 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); // Residency status of resource heap types is always known. - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryUsage, resourceHeapDesc.SizeInBytes); - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryCount, 1u); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryUsage, resourceHeapDesc.SizeInBytes); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryCount, 1u); ComPtr heap; ASSERT_SUCCEEDED(resourceHeap.As(&heap)); @@ -215,8 +215,8 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_CURRENT_RESIDENT); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, true); - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryUsage, resourceHeapDesc.SizeInBytes); - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryCount, 1u); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryUsage, resourceHeapDesc.SizeInBytes); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryCount, 1u); ASSERT_SUCCEEDED(residencyManager->UnlockHeap(resourceHeap.Get())); @@ -224,8 +224,8 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); // Unlocking a heap does not evict it, the memory usage should not change. - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryUsage, resourceHeapDesc.SizeInBytes); - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryCount, 1u); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryUsage, resourceHeapDesc.SizeInBytes); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryCount, 1u); ASSERT_SUCCEEDED(residencyManager->UnlockHeap(resourceHeap.Get())); // Not locked } @@ -261,16 +261,16 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeap) { // Residency status of non-resource heap types is unknown, there is no residency usage // yet. - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryUsage, 0u); - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryCount, 0u); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryUsage, 0u); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryCount, 0u); ASSERT_SUCCEEDED(residencyManager->LockHeap(descriptorHeap.Get())); EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_CURRENT_RESIDENT); EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, true); - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryUsage, descriptorHeapDesc.SizeInBytes); - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryCount, 1u); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryUsage, descriptorHeapDesc.SizeInBytes); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryCount, 1u); ASSERT_SUCCEEDED(residencyManager->UnlockHeap(descriptorHeap.Get())); @@ -278,8 +278,8 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeap) { EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, false); // Unlocking a heap does not evict it, the memory usage should not change. - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryUsage, descriptorHeapDesc.SizeInBytes); - EXPECT_EQ(residencyManager->GetStats().CurrentMemoryCount, 1u); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryUsage, descriptorHeapDesc.SizeInBytes); + EXPECT_EQ(GetStats(residencyManager).CurrentMemoryCount, 1u); ASSERT_SUCCEEDED(residencyManager->UnlockHeap(descriptorHeap.Get())); } @@ -470,7 +470,7 @@ TEST_F(D3D12ResidencyManagerTests, OverBudget) { // Keep allocating until we reach the budget. std::vector> allocationsBelowBudget = {}; - while (resourceAllocator->GetStats().UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { + while (GetStats(resourceAllocator).UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( bufferAllocationDesc, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); @@ -487,9 +487,9 @@ TEST_F(D3D12ResidencyManagerTests, OverBudget) { // Allocating the same amount over budget, where older allocations will be evicted. std::vector> allocationsAboveBudget = {}; - const uint64_t currentMemoryUsage = resourceAllocator->GetStats().UsedMemoryUsage; + const uint64_t currentMemoryUsage = GetStats(resourceAllocator).UsedMemoryUsage; - while (currentMemoryUsage + kMemoryOverBudget > resourceAllocator->GetStats().UsedMemoryUsage) { + while (currentMemoryUsage + kMemoryOverBudget > GetStats(resourceAllocator).UsedMemoryUsage) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( bufferAllocationDesc, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); @@ -537,7 +537,7 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetAsync) { // Keep allocating until we reach the budget. Should a budget change occur, we must also // terminate the loop since we cannot guarantee all allocations will be created resident. std::vector> allocations = {}; - while (resourceAllocator->GetStats().UsedMemoryUsage + kBufferMemorySize < memoryUnderBudget && + while (GetStats(resourceAllocator).UsedMemoryUsage + kBufferMemorySize < memoryUnderBudget && GetBudgetLeft(residencyManager.Get(), bufferMemorySegment) >= kBufferMemorySize) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( @@ -576,7 +576,7 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetDisablesGrowth) { ALLOCATION_DESC bufferAllocationDesc = {}; bufferAllocationDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT; - while (resourceAllocator->GetStats().UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { + while (GetStats(resourceAllocator).UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( bufferAllocationDesc, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); @@ -617,7 +617,7 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetWithLockedHeaps) { // Keep allocating until we reach the budget. std::vector> allocationsBelowBudget = {}; - while (resourceAllocator->GetStats().UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { + while (GetStats(resourceAllocator).UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( bufferAllocationDesc, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); @@ -663,7 +663,7 @@ TEST_F(D3D12ResidencyManagerTests, ExecuteCommandListOverBudget) { // Create the first set of heaps below the budget. std::vector> firstSetOfHeaps = {}; - while (resourceAllocator->GetStats().UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { + while (GetStats(resourceAllocator).UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( {}, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); @@ -760,7 +760,7 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetImported) { // Keep importing externally allocated resources until we reach the budget. std::vector> allocationsBelowBudget = {}; - while (resourceAllocator->GetStats().UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { + while (GetStats(resourceAllocator).UsedMemoryUsage + kBufferMemorySize <= kDefaultBudget) { D3D12_HEAP_PROPERTIES heapProperties = {}; heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT; @@ -785,9 +785,9 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetImported) { // Allocating the same amount over budget, where older allocations will be evicted. std::vector> allocationsAboveBudget = {}; - const uint64_t currentMemoryUsage = resourceAllocator->GetStats().UsedMemoryUsage; + const uint64_t currentMemoryUsage = GetStats(resourceAllocator).UsedMemoryUsage; - while (currentMemoryUsage + kMemoryOverBudget > resourceAllocator->GetStats().UsedMemoryUsage) { + while (currentMemoryUsage + kMemoryOverBudget > GetStats(resourceAllocator).UsedMemoryUsage) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( {}, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); @@ -803,4 +803,4 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetImported) { for (auto& allocation : allocationsBelowBudget) { EXPECT_FALSE(allocation->GetMemory()->GetInfo().IsCachedForResidency); } -} \ No newline at end of file +} diff --git a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp index 967d81373..618b63aae 100644 --- a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp +++ b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp @@ -32,24 +32,24 @@ static constexpr uint64_t kReleaseAllMemory = std::numeric_limits::max #define GPGMM_GET_VAR_NAME(x) (L#x) -#define EXPECT_SIZE_CACHE_HIT(allocator, statement) \ +#define EXPECT_SIZE_CACHE_HIT(allocator, statement) \ + do { \ + ASSERT_NE(allocator, nullptr); \ + uint64_t countBefore = GetStats(allocator).SizeCacheHits; \ + EXPECT_SUCCEEDED(statement); \ + uint64_t countAfter = GetStats(allocator).SizeCacheHits; \ + EXPECT_GT(countAfter, countBefore); \ + } while (0) + +#define EXPECT_SIZE_CACHE_MISS(allocator, statement) \ do { \ ASSERT_NE(allocator, nullptr); \ - uint64_t countBefore = allocator->GetStats().SizeCacheHits; \ + uint64_t countBefore = GetStats(allocator).SizeCacheMisses; \ EXPECT_SUCCEEDED(statement); \ - uint64_t countAfter = allocator->GetStats().SizeCacheHits; \ + uint64_t countAfter = GetStats(allocator).SizeCacheMisses; \ EXPECT_GT(countAfter, countBefore); \ } while (0) -#define EXPECT_SIZE_CACHE_MISS(allocator, statement) \ - do { \ - ASSERT_NE(allocator, nullptr); \ - uint64_t countBefore = allocator->GetStats().SizeCacheMisses; \ - EXPECT_SUCCEEDED(statement); \ - uint64_t countAfter = allocator->GetStats().SizeCacheMisses; \ - EXPECT_GT(countAfter, countBefore); \ - } while (0) - class D3D12ResourceAllocatorTests : public D3D12TestBase, public ::testing::Test { protected: void SetUp() override { @@ -210,7 +210,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferAndTextureInSameHeap) { nullptr, &bufferAllocation)); } - EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize); + EXPECT_EQ(GetStats(resourceAllocator).FreeMemoryUsage, kBufferOf4MBAllocationSize); // Reuse memory for texture in Heap A. { @@ -220,7 +220,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferAndTextureInSameHeap) { D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, &textureAllocation)); } - EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize); + EXPECT_EQ(GetStats(resourceAllocator).FreeMemoryUsage, kBufferOf4MBAllocationSize); } // Exceeding the max resource heap size should always fail. @@ -245,7 +245,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferAndTextureInSeperateHeap) { allocatorDesc.PreferredResourceHeapSize); } - EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize); + EXPECT_EQ(GetStats(resourceAllocator).FreeMemoryUsage, kBufferOf4MBAllocationSize); // Reuse memory for texture in Heap A. { @@ -258,7 +258,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferAndTextureInSeperateHeap) { allocatorDesc.PreferredResourceHeapSize); } - EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize * 2); + EXPECT_EQ(GetStats(resourceAllocator).FreeMemoryUsage, kBufferOf4MBAllocationSize * 2); } // Exceeding the max resource heap size should always fail. @@ -710,13 +710,13 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferUMA) { resourceAllocator->CreateResource({}, CreateBasicBufferDesc(kBufferOf4MBAllocationSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, nullptr)); - EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize); + EXPECT_EQ(GetStats(resourceAllocator).FreeMemoryUsage, kBufferOf4MBAllocationSize); ASSERT_SUCCEEDED( resourceAllocator->CreateResource({}, CreateBasicBufferDesc(kBufferOf4MBAllocationSize), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, nullptr)); - EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize); + EXPECT_EQ(GetStats(resourceAllocator).FreeMemoryUsage, kBufferOf4MBAllocationSize); ALLOCATION_DESC allocationDesc = {}; allocationDesc.HeapType = D3D12_HEAP_TYPE_READBACK; @@ -725,7 +725,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferUMA) { allocationDesc, CreateBasicBufferDesc(kBufferOf4MBAllocationSize), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, nullptr)); - EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize * 2); + EXPECT_EQ(GetStats(resourceAllocator).FreeMemoryUsage, kBufferOf4MBAllocationSize * 2); } TEST_F(D3D12ResourceAllocatorTests, CreateBufferDisableUMA) { @@ -772,7 +772,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferDisableUMA) { allocationDesc, CreateBasicBufferDesc(kBufferOf4MBAllocationSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, nullptr)); - EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize * 2); + EXPECT_EQ(GetStats(resourceAllocator).FreeMemoryUsage, kBufferOf4MBAllocationSize * 2); } } @@ -818,10 +818,10 @@ TEST_F(D3D12ResourceAllocatorTests, CreateMultisampledTexture) { allocation->GetInfo().SizeInBytes, static_cast(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT))); - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryCount, 1u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryCount, 1u); } - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryCount, 0u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryCount, 0u); } TEST_F(D3D12ResourceAllocatorTests, CreateBufferImported) { @@ -916,9 +916,9 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferAlwaysCommitted) { ASSERT_FAILED(resourceHeap.As(&heap)); // Commited resources must use all the memory allocated. - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryUsage, kBufferOf4MBAllocationSize); - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockUsage, - resourceAllocator->GetStats().UsedMemoryUsage); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryUsage, kBufferOf4MBAllocationSize); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockUsage, + GetStats(resourceAllocator).UsedMemoryUsage); } TEST_F(D3D12ResourceAllocatorTests, CreateBufferNeverAllocate) { @@ -982,9 +982,9 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferWithin) { EXPECT_EQ(smallBuffer->GetOffsetFromResource(), 0u); EXPECT_EQ(smallBuffer->GetInfo().Alignment, 4u); // Must re-align. - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockCount, 1u); - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryCount, 1u); - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockUsage, smallBuffer->GetInfo().SizeInBytes); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockCount, 1u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryCount, 1u); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockUsage, smallBuffer->GetInfo().SizeInBytes); } { ALLOCATION_DESC smallBufferWithinDesc = baseAllocationDesc; @@ -1000,9 +1000,9 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferWithin) { EXPECT_EQ(smallBuffer->GetOffsetFromResource(), 0u); EXPECT_EQ(smallBuffer->GetInfo().Alignment, 16u); - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockCount, 1u); - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryCount, 1u); - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockUsage, smallBuffer->GetInfo().SizeInBytes); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockCount, 1u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryCount, 1u); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockUsage, smallBuffer->GetInfo().SizeInBytes); } { ALLOCATION_DESC smallBufferWithinDesc = baseAllocationDesc; @@ -1018,9 +1018,9 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferWithin) { EXPECT_EQ(smallBuffer->GetOffsetFromResource(), 0u); EXPECT_EQ(smallBuffer->GetInfo().Alignment, 256u); // Re-align - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockCount, 1u); - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryCount, 1u); - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockUsage, smallBuffer->GetInfo().SizeInBytes); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockCount, 1u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryCount, 1u); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockUsage, smallBuffer->GetInfo().SizeInBytes); } { ALLOCATION_DESC smallBufferWithinDesc = baseAllocationDesc; @@ -1160,8 +1160,8 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferWithinMany) { EXPECT_EQ(smallBufferC->GetInfo().Method, gpgmm::AllocationMethod::kSubAllocatedWithin); EXPECT_EQ(smallBufferC->GetInfo().SizeInBytes, smallBufferDesc.Width); - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockCount, 3u); - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryCount, 1u); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockCount, 3u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryCount, 1u); // Should be allocated in sequence, back-to-back. EXPECT_EQ(smallBufferA->GetOffsetFromResource() + smallBufferDesc.Width, @@ -1231,8 +1231,8 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferWithinMany) { smallBufferB = nullptr; smallBufferC = nullptr; - EXPECT_EQ(resourceAllocator->GetStats().UsedBlockCount, 0u); - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryCount, 0u); + EXPECT_EQ(GetStats(resourceAllocator).UsedBlockCount, 0u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryCount, 0u); } TEST_F(D3D12ResourceAllocatorTests, CreateBufferNeverSubAllocated) { @@ -1376,11 +1376,11 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferPooled) { EXPECT_EQ(allocation->GetInfo().Method, gpgmm::AllocationMethod::kStandalone); } - EXPECT_EQ(poolAllocator->GetStats().FreeMemoryUsage, bufferSize + bufferSize / 2); + EXPECT_EQ(GetStats(poolAllocator).FreeMemoryUsage, bufferSize + bufferSize / 2); EXPECT_EQ(poolAllocator->ReleaseMemory(kReleaseAllMemory), bufferSize + bufferSize / 2); - EXPECT_EQ(poolAllocator->GetStats().FreeMemoryUsage, 0u); + EXPECT_EQ(GetStats(poolAllocator).FreeMemoryUsage, 0u); // Create buffer of size A again with it's own resource heap from the empty pool. { @@ -1420,7 +1420,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferPooled) { EXPECT_EQ(allocation->GetInfo().Method, gpgmm::AllocationMethod::kStandalone); } - EXPECT_EQ(poolAllocator->GetStats().FreeMemoryUsage, 0u); + EXPECT_EQ(GetStats(poolAllocator).FreeMemoryUsage, 0u); } TEST_F(D3D12ResourceAllocatorTests, CreateBufferStats) { @@ -1442,7 +1442,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferStats) { ASSERT_NE(firstAllocation, nullptr); EXPECT_EQ(firstAllocation->GetInfo().Method, gpgmm::AllocationMethod::kStandalone); - RESOURCE_ALLOCATOR_STATS stats = resourceAllocator->GetStats(); + RESOURCE_ALLOCATOR_STATS stats = GetStats(resourceAllocator); EXPECT_EQ(stats.UsedMemoryCount, 1u); EXPECT_EQ(stats.UsedMemoryUsage, kBufferOf4MBAllocationSize); } @@ -1466,7 +1466,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferStats) { ASSERT_NE(firstAllocation, nullptr); EXPECT_EQ(firstAllocation->GetInfo().Method, gpgmm::AllocationMethod::kStandalone); - RESOURCE_ALLOCATOR_STATS stats = resourceAllocator->GetStats(); + RESOURCE_ALLOCATOR_STATS stats = GetStats(resourceAllocator); EXPECT_EQ(stats.UsedMemoryCount, 1u); EXPECT_EQ(stats.UsedMemoryUsage, kBufferOf4MBAllocationSize); @@ -1477,7 +1477,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferStats) { ASSERT_NE(secondAllocation, nullptr); EXPECT_EQ(secondAllocation->GetInfo().Method, gpgmm::AllocationMethod::kStandalone); - stats = resourceAllocator->GetStats(); + stats = GetStats(resourceAllocator); EXPECT_EQ(stats.UsedMemoryCount, 2u); EXPECT_EQ(stats.UsedMemoryUsage, kBufferOf4MBAllocationSize * 2); } @@ -1505,7 +1505,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferStats) { GPGMM_SKIP_TEST_IF(firstAllocation->GetInfo().Method != gpgmm::AllocationMethod::kSubAllocated); - RESOURCE_ALLOCATOR_STATS stats = resourceAllocator->GetStats(); + RESOURCE_ALLOCATOR_STATS stats = GetStats(resourceAllocator); EXPECT_EQ(stats.UsedMemoryCount, 1u); EXPECT_GE(stats.UsedMemoryUsage, stats.UsedBlockUsage); EXPECT_EQ(stats.UsedBlockCount, 1u); @@ -1518,7 +1518,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferStats) { ASSERT_NE(secondAllocation, nullptr); EXPECT_EQ(secondAllocation->GetInfo().Method, gpgmm::AllocationMethod::kSubAllocated); - stats = resourceAllocator->GetStats(); + stats = GetStats(resourceAllocator); EXPECT_GE(stats.UsedMemoryCount, 1u); EXPECT_GE(stats.UsedMemoryUsage, stats.UsedBlockUsage); EXPECT_EQ(stats.UsedBlockCount, 2u); @@ -1545,7 +1545,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferStats) { ASSERT_NE(firstAllocation, nullptr); EXPECT_EQ(firstAllocation->GetInfo().Method, gpgmm::AllocationMethod::kSubAllocatedWithin); - RESOURCE_ALLOCATOR_STATS stats = resourceAllocator->GetStats(); + RESOURCE_ALLOCATOR_STATS stats = GetStats(resourceAllocator); EXPECT_EQ(stats.UsedMemoryCount, 1u); EXPECT_EQ(stats.UsedMemoryUsage, 64u * 1024u); EXPECT_EQ(stats.UsedBlockCount, 1u); @@ -1558,7 +1558,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferStats) { ASSERT_NE(secondAllocation, nullptr); EXPECT_EQ(secondAllocation->GetInfo().Method, gpgmm::AllocationMethod::kSubAllocatedWithin); - stats = resourceAllocator->GetStats(); + stats = GetStats(resourceAllocator); EXPECT_EQ(stats.UsedMemoryCount, 1u); EXPECT_EQ(stats.UsedMemoryUsage, 64u * 1024u); EXPECT_EQ(stats.UsedBlockCount, 2u); @@ -1729,7 +1729,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferManyThreaded) { thread.join(); } - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryUsage, 0u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryUsage, 0u); } // Creates a bunch of buffers concurrently. @@ -1762,7 +1762,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferWithinManyThreaded) { thread.join(); } - EXPECT_EQ(resourceAllocator->GetStats().UsedMemoryUsage, 0u); + EXPECT_EQ(GetStats(resourceAllocator).UsedMemoryUsage, 0u); } TEST_F(D3D12ResourceAllocatorTests, CreateBufferCacheSize) {