diff --git a/src/gpgmm/d3d12/HeapD3D12.cpp b/src/gpgmm/d3d12/HeapD3D12.cpp index c20eb7a9f..993493190 100644 --- a/src/gpgmm/d3d12/HeapD3D12.cpp +++ b/src/gpgmm/d3d12/HeapD3D12.cpp @@ -78,14 +78,14 @@ namespace gpgmm::d3d12 { // Resource heaps created without the "create not resident" flag are always // resident. if (!(resourceHeapFlags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT)) { - heap->mState = CURRENT_RESIDENT; + heap->mState = RESIDENCY_STATUS_CURRENT_RESIDENT; } else { - heap->mState = PENDING_RESIDENCY; + heap->mState = RESIDENCY_STATUS_PENDING_RESIDENCY; } } // Heap created not resident requires no budget to be created. - if (heap->mState == PENDING_RESIDENCY && + if (heap->mState == RESIDENCY_STATUS_PENDING_RESIDENCY && (descriptor.Flags & HEAP_FLAG_ALWAYS_IN_BUDGET)) { gpgmm::ErrorLog() << "Creating a heap always in budget cannot be used with " "D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT."; @@ -96,7 +96,7 @@ namespace gpgmm::d3d12 { // should be always inserted in the residency cache. For other heap types (eg. // descriptor heap), they must be manually locked and unlocked to be inserted into the // residency cache. - if (heap->mState != RESIDENCY_UNKNOWN) { + if (heap->mState != RESIDENCY_STATUS_UNKNOWN) { ReturnIfFailed(pResidencyManager->InsertHeap(heap.get())); } } @@ -119,7 +119,7 @@ namespace gpgmm::d3d12 { mMemorySegmentGroup(descriptor.MemorySegmentGroup), mResidencyLock(0), mIsResidencyDisabled(isResidencyDisabled), - mState(RESIDENCY_UNKNOWN) { + mState(RESIDENCY_STATUS_UNKNOWN) { ASSERT(mPageable != nullptr); if (!mIsResidencyDisabled) { GPGMM_TRACE_EVENT_OBJECT_NEW(this); diff --git a/src/gpgmm/d3d12/HeapD3D12.h b/src/gpgmm/d3d12/HeapD3D12.h index c861f7393..fc7837563 100644 --- a/src/gpgmm/d3d12/HeapD3D12.h +++ b/src/gpgmm/d3d12/HeapD3D12.h @@ -33,29 +33,32 @@ namespace gpgmm::d3d12 { /** \enum RESIDENCY_STATUS - Heaps are created in one of three states: never made resident or unknown, about to become + D3D12 allows heaps to be explicitly created resident or not. This means the expected residency + status of the heap cannot be solely determined by checking for the existence in a residency + cache. + + Heaps are in one of three exclusive states: never made resident or unknown, about to become resident or pending residency, and currently resident. When a heap gets evicted or paged-out, it transitions from currently resident to pending residency. Paged-in is the reverse of this, - pending residency to currently resident. - - If the heap was pinned or locked, it will stay currently resident until it is unlocked, then - back to pending residency. - - D3D12 does not provide a means to determine what state the heap is in so this status is used to - track the approximate state. + pending residency to currently resident. If the heap was known to be created resident by D3D12, + it will immediately become currently resident. If the heap becomes locked, it will stay + currently resident until it is evicted, then back to pending residency. */ enum RESIDENCY_STATUS { - /** \brief Heap is not being managed for residency. + /** \brief Heap residency status is not known and cannot be made resident. + Heap must become locked to be managed for residency. */ - RESIDENCY_UNKNOWN = 0, + RESIDENCY_STATUS_UNKNOWN = 0, - /** \brief Heap is about to be resident. - */ - PENDING_RESIDENCY = 1, + /** \brief Heap is about to be made resident. + Heap must be previously locked, evicted, or currently resident at creation. + */ + RESIDENCY_STATUS_PENDING_RESIDENCY = 1, - /** \brief Heap was made resident. - */ - CURRENT_RESIDENT = 2, + /** \brief Heap was made resident and can be evicted. + Heaps that stay locked will always be currently resident. + */ + RESIDENCY_STATUS_CURRENT_RESIDENT = 2, }; /** \struct HEAP_INFO @@ -66,7 +69,7 @@ namespace gpgmm::d3d12 { */ bool IsLocked; - /** \brief Check if the heap is resident or not. + /** \brief Check if the heap was made resident or not. */ RESIDENCY_STATUS Status; }; diff --git a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp index ba13a9054..e0926cbf2 100644 --- a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp +++ b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp @@ -294,7 +294,7 @@ namespace gpgmm::d3d12 { ReturnIfFailed(pHeap->QueryInterface(IID_PPV_ARGS(&pageable))); ReturnIfFailed(MakeResident(pHeap->GetMemorySegmentGroup(), pHeap->GetSize(), 1, pageable.GetAddressOf())); - pHeap->SetResidencyState(CURRENT_RESIDENT); + pHeap->SetResidencyState(RESIDENCY_STATUS_CURRENT_RESIDENT); // Untracked heaps, created not resident, are not already attributed toward residency // usage because they are not in the residency cache. @@ -308,7 +308,7 @@ namespace gpgmm::d3d12 { // Untracked heaps, previously made resident, are not attributed toward residency usage // because they will be removed from the residency cache. - if (pHeap->mState == CURRENT_RESIDENT) { + if (pHeap->mState == RESIDENCY_STATUS_CURRENT_RESIDENT) { mInfo.CurrentMemoryCount++; mInfo.CurrentMemoryUsage += pHeap->GetSize(); } @@ -613,7 +613,7 @@ namespace gpgmm::d3d12 { ReturnIfFailed(mResidencyFence->WaitFor(lastUsedFenceValue)); heap->RemoveFromList(); - heap->SetResidencyState(PENDING_RESIDENCY); + heap->SetResidencyState(RESIDENCY_STATUS_PENDING_RESIDENCY); bytesEvicted += heap->GetSize(); @@ -729,7 +729,7 @@ namespace gpgmm::d3d12 { // Once MakeResident succeeds, we must assume the heaps are resident since D3D12 provides // no way of knowing for certain. for (Heap* heap : heapsToMakeResident) { - heap->SetResidencyState(CURRENT_RESIDENT); + heap->SetResidencyState(RESIDENCY_STATUS_CURRENT_RESIDENT); } GPGMM_TRACE_EVENT_METRIC( @@ -806,14 +806,14 @@ namespace gpgmm::d3d12 { RESIDENCY_INFO info = mInfo; for (const auto& entry : mLocalVideoMemorySegment.cache) { - if (entry.value()->GetInfo().Status == CURRENT_RESIDENT) { + if (entry.value()->GetInfo().Status == RESIDENCY_STATUS_CURRENT_RESIDENT) { info.CurrentMemoryUsage += entry.value()->GetSize(); info.CurrentMemoryCount++; } } for (const auto& entry : mNonLocalVideoMemorySegment.cache) { - if (entry.value()->GetInfo().Status == CURRENT_RESIDENT) { + if (entry.value()->GetInfo().Status == RESIDENCY_STATUS_CURRENT_RESIDENT) { info.CurrentMemoryUsage += entry.value()->GetSize(); info.CurrentMemoryCount++; } diff --git a/src/include/min/gpgmm_d3d12.h b/src/include/min/gpgmm_d3d12.h index 002419681..1a10fa8e8 100644 --- a/src/include/min/gpgmm_d3d12.h +++ b/src/include/min/gpgmm_d3d12.h @@ -75,9 +75,9 @@ namespace gpgmm::d3d12 { }; enum RESIDENCY_STATUS { - RESIDENCY_UNKNOWN = 0, - PENDING_RESIDENCY = 1, - CURRENT_RESIDENT = 2, + RESIDENCY_STATUS_UNKNOWN = 0, + RESIDENCY_STATUS_PENDING_RESIDENCY = 1, + RESIDENCY_STATUS_CURRENT_RESIDENT = 2, }; struct HEAP_INFO { diff --git a/src/tests/end2end/D3D12ResidencyManagerTests.cpp b/src/tests/end2end/D3D12ResidencyManagerTests.cpp index 54aee2fba..89e0f6952 100644 --- a/src/tests/end2end/D3D12ResidencyManagerTests.cpp +++ b/src/tests/end2end/D3D12ResidencyManagerTests.cpp @@ -177,8 +177,8 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { // Ensure the unmanaged resource heap state is always unknown. Even though D3D12 implicitly // creates heaps as resident, untrack resource heaps would never transition out from - // CURRENT_RESIDENT and must be left RESIDENCY_UNKNOWN. - EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_UNKNOWN); + // RESIDENCY_STATUS_CURRENT_RESIDENT and must be left RESIDENCY_STATUS_UNKNOWN. + EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_UNKNOWN); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); // Create a resource heap with residency. @@ -186,7 +186,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { Heap::CreateHeap(resourceHeapDesc, residencyManager.Get(), createHeapFn, &resourceHeap)); ASSERT_NE(resourceHeap, nullptr); - EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::CURRENT_RESIDENT); + EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_CURRENT_RESIDENT); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); // Residency status of resource heap types is always known. @@ -199,7 +199,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { ASSERT_SUCCEEDED(residencyManager->LockHeap(resourceHeap.Get())); - EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::CURRENT_RESIDENT); + EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_CURRENT_RESIDENT); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, true); EXPECT_EQ(residencyManager->GetInfo().CurrentMemoryUsage, resourceHeapDesc.SizeInBytes); @@ -207,7 +207,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { ASSERT_SUCCEEDED(residencyManager->UnlockHeap(resourceHeap.Get())); - EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::CURRENT_RESIDENT); + EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_CURRENT_RESIDENT); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); // Unlocking a heap does not evict it, the memory usage should not change. @@ -245,7 +245,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeap) { ASSERT_SUCCEEDED(Heap::CreateHeap(descriptorHeapDesc, residencyManager.Get(), createHeapFn, &descriptorHeap)); - EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_UNKNOWN); + EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_UNKNOWN); EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, false); ComPtr heap; @@ -259,7 +259,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeap) { ASSERT_SUCCEEDED(residencyManager->LockHeap(descriptorHeap.Get())); - EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::CURRENT_RESIDENT); + EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_CURRENT_RESIDENT); EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, true); EXPECT_EQ(residencyManager->GetInfo().CurrentMemoryUsage, descriptorHeapDesc.SizeInBytes); @@ -267,7 +267,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeap) { ASSERT_SUCCEEDED(residencyManager->UnlockHeap(descriptorHeap.Get())); - EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::CURRENT_RESIDENT); + EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_STATUS_CURRENT_RESIDENT); EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, false); // Unlocking a heap does not evict it, the memory usage should not change. @@ -602,7 +602,7 @@ TEST_F(D3D12ResidencyManagerTests, ExecuteCommandListOverBudget) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( {}, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, CURRENT_RESIDENT); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_STATUS_CURRENT_RESIDENT); firstSetOfHeaps.push_back(std::move(allocation)); } @@ -612,7 +612,7 @@ TEST_F(D3D12ResidencyManagerTests, ExecuteCommandListOverBudget) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( {}, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, CURRENT_RESIDENT); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_STATUS_CURRENT_RESIDENT); secondSetOfHeaps.push_back(std::move(allocation)); } @@ -644,12 +644,12 @@ TEST_F(D3D12ResidencyManagerTests, ExecuteCommandListOverBudget) { // Everything below the budget should now be resident. for (auto& allocation : firstSetOfHeaps) { - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, CURRENT_RESIDENT); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_STATUS_CURRENT_RESIDENT); } // Everything above the budget should now be evicted. for (auto& allocation : secondSetOfHeaps) { - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, PENDING_RESIDENCY); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_STATUS_PENDING_RESIDENCY); } // Page-in the second set of heaps using ExecuteCommandLists (and page-out the first set). @@ -667,11 +667,11 @@ TEST_F(D3D12ResidencyManagerTests, ExecuteCommandListOverBudget) { // Everything below the budget should now be evicted. for (auto& allocation : firstSetOfHeaps) { - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, PENDING_RESIDENCY); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_STATUS_PENDING_RESIDENCY); } // Everything above the budget should now be resident. for (auto& allocation : secondSetOfHeaps) { - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, CURRENT_RESIDENT); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_STATUS_CURRENT_RESIDENT); } } \ No newline at end of file