Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions include/gpgmm_d3d12.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.

Expand Down
9 changes: 8 additions & 1 deletion src/fuzzers/D3D12ResidencyManagerFuzzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ namespace {
: 0;
}

gpgmm::d3d12::RESOURCE_ALLOCATOR_STATS GetStats(
ComPtr<gpgmm::d3d12::IResourceAllocator> resourceAllocator) {
gpgmm::d3d12::RESOURCE_ALLOCATOR_STATS stats = {};
resourceAllocator->QueryStats(&stats);
return stats;
}

} // namespace

extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
Expand Down Expand Up @@ -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<gpgmm::d3d12::IResourceAllocation> allocation;
if (FAILED(gResourceAllocator->CreateResource({}, bufferDesc, D3D12_RESOURCE_STATE_COMMON,
nullptr, &allocation))) {
Expand Down
16 changes: 11 additions & 5 deletions src/gpgmm/d3d12/ResidencyManagerD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::mutex> 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
Expand All @@ -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) {
Expand All @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions src/gpgmm/d3d12/ResidencyManagerD3D12.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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();
Expand Down Expand Up @@ -139,7 +139,7 @@ namespace gpgmm::d3d12 {

VideoMemorySegment mLocalVideoMemorySegment;
VideoMemorySegment mNonLocalVideoMemorySegment;
RESIDENCY_STATS mStats = {};
RESIDENCY_MANAGER_STATS mStats = {};

std::shared_ptr<BudgetUpdateEvent> mBudgetNotificationUpdateEvent;
};
Expand Down
24 changes: 17 additions & 7 deletions src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ namespace gpgmm::d3d12 {

// Update allocation metrics.
if (bytesReleased > 0) {
GetStatsInternal();
QueryStatsInternal(nullptr);
}

return bytesReleased;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 "
Expand Down Expand Up @@ -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<std::mutex> 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.
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/gpgmm/d3d12/ResourceAllocatorD3D12.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -168,7 +168,7 @@ namespace gpgmm::d3d12 {
// MemoryAllocator interface
void DeallocateMemory(std::unique_ptr<MemoryAllocation> allocation) override;

RESOURCE_ALLOCATOR_STATS GetStatsInternal() const;
HRESULT QueryStatsInternal(RESOURCE_ALLOCATOR_STATS* pResourceAllocatorStats);

ID3D12Device* mDevice = nullptr;
ComPtr<ResidencyManager> mResidencyManager;
Expand Down
8 changes: 4 additions & 4 deletions src/mvi/gpgmm_d3d12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/mvi/gpgmm_d3d12.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions src/tests/D3D12Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -46,6 +48,18 @@ namespace gpgmm::d3d12 {
return unknown->Release();
}

RESOURCE_ALLOCATOR_STATS GetStats(ComPtr<IResourceAllocator> resourceAllocator) {
RESOURCE_ALLOCATOR_STATS stats = {};
resourceAllocator->QueryStats(&stats);
return stats;
}

RESIDENCY_MANAGER_STATS GetStats(ComPtr<IResidencyManager> residencyManager) {
RESIDENCY_MANAGER_STATS stats = {};
residencyManager->QueryStats(&stats);
return stats;
}

void D3D12TestBase::SetUp() {
GPGMMTestBase::SetUp();

Expand Down
7 changes: 7 additions & 0 deletions src/tests/D3D12Test.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <vector>

#include <gpgmm_d3d12.h>
#include "gpgmm/d3d12/d3d12_platform.h"

#define ASSERT_FAILED(expr) ASSERT_TRUE(FAILED(expr))
Expand All @@ -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<IResourceAllocator> resourceAllocator);
RESIDENCY_MANAGER_STATS GetStats(ComPtr<IResidencyManager> residencyManager);

class D3D12TestBase : public GPGMMTestBase {
public:
void SetUp();
Expand Down
4 changes: 2 additions & 2 deletions src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ class D3D12EventTraceReplay : public D3D12TestBase, public CaptureReplayTestWith
playbackContext.currentAllocatorID);
ASSERT_TRUE(it != playbackContext.CreatedAllocatorsToID.end());

IResourceAllocator* resourceAllocator =
ComPtr<IResourceAllocator> resourceAllocator =
playbackContext
.CreatedAllocatorsToID[playbackContext.currentAllocatorID]
.Get();
Expand Down Expand Up @@ -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;
Expand Down
Loading