diff --git a/include/gpgmm_d3d12.h b/include/gpgmm_d3d12.h index 934765d82..21c23761f 100644 --- a/include/gpgmm_d3d12.h +++ b/include/gpgmm_d3d12.h @@ -1137,17 +1137,19 @@ namespace gpgmm::d3d12 { When pooling is enabled, the allocator will retain resource heaps in order to speed-up subsequent resource allocation requests. These resource allocations count against the app's memory usage and in general, will lead to increased memory usage by the overall - system. Apps should call ReleaseMemory() when going idle for a period of time since there is + system. Apps should call ReleaseResourceHeaps() when going idle for a period of time since there is a brief performance hit when the internal resource heaps get reallocated by the OS. @param bytesToRelease Amount of memory to release, in bytes. A value of UINT64_MAX releases ALL memory held by the allocator. + @param pBytesReleased Optional pointer to integer which recieves the amount of memory released, in + bytes. - \return Amount of memory, in bytes, released. The released size might be smaller then - bytesToRelease if there was not enough memory or larger if releasable memory doesn't exactly - total up to the amount. + \return Returns S_OK if successfully released equal to or greater than the memory amount + specified. Or S_FALSE if the released size was smaller, there was not enough memory or + larger if releasable memory doesn't exactly total up to the amount. */ - virtual uint64_t ReleaseMemory(uint64_t bytesToRelease) = 0; + virtual HRESULT ReleaseResourceHeaps(uint64_t bytesToRelease, uint64_t * pBytesReleased) = 0; /** \brief Query the current allocator usage. diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 7f2b48ddc..dd38ec112 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -822,7 +822,7 @@ namespace gpgmm::d3d12 { return "ResourceAllocator"; } - uint64_t ResourceAllocator::ReleaseMemory(uint64_t bytesToRelease) { + HRESULT ResourceAllocator::ReleaseResourceHeaps(uint64_t bytesToRelease, uint64_t* pBytesReleased) { std::lock_guard lock(mMutex); uint64_t bytesReleased = 0; for (uint32_t resourceHeapTypeIndex = 0; resourceHeapTypeIndex < kNumOfResourceHeapTypes; @@ -866,10 +866,18 @@ namespace gpgmm::d3d12 { // Update allocation metrics. if (bytesReleased > 0) { - QueryStatsInternal(nullptr); + ReturnIfFailed(QueryStatsInternal(nullptr)); + } + + if (pBytesReleased != nullptr) { + *pBytesReleased = bytesReleased; } - return bytesReleased; + if (bytesToRelease > bytesReleased) { + return S_FALSE; + } + + return S_OK; } HRESULT ResourceAllocator::CreateResource(const ALLOCATION_DESC& allocationDescriptor, diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h index d4a39962e..1b8b1cd28 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h @@ -91,7 +91,7 @@ namespace gpgmm::d3d12 { HRESULT CreateResource(const ALLOCATION_DESC& allocationDescriptor, ID3D12Resource* pCommittedResource, IResourceAllocation** ppResourceAllocationOut) override; - uint64_t ReleaseMemory(uint64_t bytesToRelease) override; + HRESULT ReleaseResourceHeaps(uint64_t bytesToRelease, uint64_t* pBytesReleased) override; HRESULT QueryStats(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats) override; HRESULT CheckFeatureSupport(ALLOCATOR_FEATURE feature, void* pFeatureSupportData, diff --git a/src/mvi/gpgmm_d3d12.cpp b/src/mvi/gpgmm_d3d12.cpp index 8898d6362..d855edbb9 100644 --- a/src/mvi/gpgmm_d3d12.cpp +++ b/src/mvi/gpgmm_d3d12.cpp @@ -380,8 +380,8 @@ namespace gpgmm::d3d12 { return E_NOTIMPL; } - uint64_t ResourceAllocator::ReleaseMemory(uint64_t bytesToRelease) { - return 0; + HRESULT ResourceAllocator::ReleaseResourceHeaps(uint64_t bytesToRelease, uint64_t* pBytesReleased) { + return E_NOTIMPL; } HRESULT ResourceAllocator::QueryStats(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats) { diff --git a/src/mvi/gpgmm_d3d12.h b/src/mvi/gpgmm_d3d12.h index f8938283c..90f9fb8be 100644 --- a/src/mvi/gpgmm_d3d12.h +++ b/src/mvi/gpgmm_d3d12.h @@ -217,7 +217,7 @@ namespace gpgmm::d3d12 { HRESULT CreateResource(const ALLOCATION_DESC& allocationDescriptor, ID3D12Resource* pCommittedResource, IResourceAllocation** ppResourceAllocationOut) override; - uint64_t ReleaseMemory(uint64_t bytesToRelease) override; + HRESULT ReleaseResourceHeaps(uint64_t bytesToRelease, uint64_t* pBytesReleased) override; HRESULT QueryStats(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats) override; HRESULT CheckFeatureSupport(ALLOCATOR_FEATURE feature, void* pFeatureSupportData, diff --git a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp index 618b63aae..b0e08060a 100644 --- a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp +++ b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp @@ -755,7 +755,7 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferDisableUMA) { } // Abandonment of heap type attribution is disallowed when custom heaps are disabled. - resourceAllocator->ReleaseMemory(kReleaseAllMemory); + ASSERT_SUCCEEDED(resourceAllocator->ReleaseResourceHeaps(kReleaseAllMemory, nullptr)); { ALLOCATION_DESC allocationDesc = {}; allocationDesc.Flags = ALLOCATION_FLAG_ALWAYS_ATTRIBUTE_HEAPS; @@ -1378,7 +1378,10 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferPooled) { EXPECT_EQ(GetStats(poolAllocator).FreeMemoryUsage, bufferSize + bufferSize / 2); - EXPECT_EQ(poolAllocator->ReleaseMemory(kReleaseAllMemory), bufferSize + bufferSize / 2); + uint64_t releasedMemory = 0; + ASSERT_SUCCEEDED(poolAllocator->ReleaseResourceHeaps(kReleaseAllMemory, &releasedMemory)); + + EXPECT_EQ(releasedMemory, bufferSize + bufferSize / 2); EXPECT_EQ(GetStats(poolAllocator).FreeMemoryUsage, 0u);