diff --git a/include/gpgmm_d3d12.h b/include/gpgmm_d3d12.h index 6abaebda..26088f9e 100644 --- a/include/gpgmm_d3d12.h +++ b/include/gpgmm_d3d12.h @@ -68,33 +68,30 @@ namespace gpgmm::d3d12 { }; /** \enum RESIDENCY_HEAP_STATUS + Additional information about the heap residency status. - 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 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. + D3D12 heaps are in one of three exclusive states: never made resident or unknown, about to + become resident or evicted, and resident. When a heap gets paged-out, it transitions from + being resident to evicted. Paged-in is the reverse of this, evicted to resident. If the heap + was known to be created resident by D3D12, it will immediately become resident. If the heap + becomes locked, it will stay resident until unlocked, then back to evicted. */ enum RESIDENCY_HEAP_STATUS { - /** \brief Heap residency status is not known and cannot be made resident. - Heap must become locked to be managed for residency. - */ + /** \brief Heap residency status is not known. + + Unknown heaps must become locked to be managed for residency. + */ RESIDENCY_HEAP_STATUS_UNKNOWN = 0, - /** \brief Heap is about to be made resident. - Heap must be previously locked, evicted, or currently resident at creation. + /** \brief Heap is evicted or about to be made resident. + Evicted heaps must be previously locked, resident, or D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT. */ - RESIDENCY_HEAP_STATUS_PENDING = 1, + RESIDENCY_HEAP_STATUS_EVICTED = 1, - /** \brief Heap was made resident and can be evicted. - Heaps that stay locked will always be currently resident. + /** \brief Heap is resident and can be evicted. + Heaps that stay locked will always be resident. */ - RESIDENCY_HEAP_STATUS_CURRENT = 2, + RESIDENCY_HEAP_STATUS_RESIDENT = 2, }; /** \struct RESIDENCY_HEAP_INFO @@ -119,7 +116,7 @@ namespace gpgmm::d3d12 { */ bool IsLocked; - /** \brief Check if the heap was made resident or not. + /** \brief Determine if the heap is resident or not. */ RESIDENCY_HEAP_STATUS Status; }; diff --git a/src/gpgmm/d3d12/ResidencyHeapD3D12.cpp b/src/gpgmm/d3d12/ResidencyHeapD3D12.cpp index 6d441311..94b73e3b 100644 --- a/src/gpgmm/d3d12/ResidencyHeapD3D12.cpp +++ b/src/gpgmm/d3d12/ResidencyHeapD3D12.cpp @@ -95,14 +95,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->SetResidencyStatus(RESIDENCY_HEAP_STATUS_CURRENT); + heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_RESIDENT); } else { - heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_PENDING); + heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_EVICTED); } } // Heap created not resident requires no budget to be created. - if (heap->GetInfo().Status == RESIDENCY_HEAP_STATUS_PENDING && + if (heap->GetInfo().Status == RESIDENCY_HEAP_STATUS_EVICTED && (descriptor.Flags & RESIDENCY_HEAP_FLAG_CREATE_IN_BUDGET)) { ErrorLog(heap.get(), MessageId::kInvalidArgument) << "Creating a heap always in budget cannot be used with " @@ -123,7 +123,7 @@ namespace gpgmm::d3d12 { GetDevice(pPageable)); GPGMM_RETURN_IF_FAILED(residencyManager->UnlockHeap(heap.get()), GetDevice(pPageable)); - ASSERT(heap->GetInfo().Status == RESIDENCY_HEAP_STATUS_CURRENT); + ASSERT(heap->GetInfo().Status == RESIDENCY_HEAP_STATUS_RESIDENT); } } } else { diff --git a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp index 30de9a7f..3a1e5927 100644 --- a/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp +++ b/src/gpgmm/d3d12/ResidencyManagerD3D12.cpp @@ -206,7 +206,7 @@ namespace gpgmm::d3d12 { GPGMM_RETURN_IF_FAILED( MakeResident(heap->GetHeapSegment(), heap->GetSize(), 1, pageable.GetAddressOf()), mDevice); - heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_CURRENT); + heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_RESIDENT); // Untracked heaps, created not resident, are not already attributed toward residency // usage because they are not in the residency cache. @@ -220,7 +220,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 (heap->mState == RESIDENCY_HEAP_STATUS_CURRENT) { + if (heap->mState == RESIDENCY_HEAP_STATUS_RESIDENT) { mStats.CurrentHeapCount++; mStats.CurrentHeapUsage += heap->GetSize(); } @@ -564,7 +564,7 @@ namespace gpgmm::d3d12 { GPGMM_RETURN_IF_FAILED(mResidencyFence->WaitFor(lastUsedFenceValue), mDevice); heap->RemoveFromList(); - heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_PENDING); + heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_EVICTED); bytesEvicted += heap->GetSize(); @@ -702,7 +702,7 @@ namespace gpgmm::d3d12 { // Once MakeResident succeeds, we must assume the heaps are resident since D3D12 provides // no way of knowing for certain. for (ResidencyHeap* heap : heapsToMakeResident) { - heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_CURRENT); + heap->SetResidencyStatus(RESIDENCY_HEAP_STATUS_RESIDENT); } GPGMM_TRACE_EVENT_METRIC( @@ -803,14 +803,14 @@ namespace gpgmm::d3d12 { RESIDENCY_MANAGER_STATS result = mStats; for (const auto& entry : mLocalVideoMemorySegment.cache) { - if (entry.value()->GetInfo().Status == RESIDENCY_HEAP_STATUS_CURRENT) { + if (entry.value()->GetInfo().Status == RESIDENCY_HEAP_STATUS_RESIDENT) { result.CurrentHeapUsage += entry.value()->GetSize(); result.CurrentHeapCount++; } } for (const auto& entry : mNonLocalVideoMemorySegment.cache) { - if (entry.value()->GetInfo().Status == RESIDENCY_HEAP_STATUS_CURRENT) { + if (entry.value()->GetInfo().Status == RESIDENCY_HEAP_STATUS_RESIDENT) { result.CurrentHeapUsage += entry.value()->GetSize(); result.CurrentHeapCount++; } diff --git a/src/tests/end2end/D3D12ResidencyManagerTests.cpp b/src/tests/end2end/D3D12ResidencyManagerTests.cpp index 96a0e5e1..b2e157f4 100644 --- a/src/tests/end2end/D3D12ResidencyManagerTests.cpp +++ b/src/tests/end2end/D3D12ResidencyManagerTests.cpp @@ -79,7 +79,7 @@ class D3D12ResidencyManagerTests : public D3D12TestBase, public ::testing::Test bool IsResident(IResourceAllocation* pAllocation) const { ASSERT(pAllocation != nullptr); - return pAllocation->GetMemory()->GetInfo().Status == RESIDENCY_HEAP_STATUS_CURRENT; + return pAllocation->GetMemory()->GetInfo().Status == RESIDENCY_HEAP_STATUS_RESIDENT; } class CreateDescHeapCallbackContext { @@ -219,7 +219,7 @@ 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 - // RESIDENCY_HEAP_STATUS_CURRENT and must be left RESIDENCY_HEAP_STATUS_UNKNOWN. + // RESIDENCY_HEAP_STATUS_RESIDENT and must be left RESIDENCY_HEAP_STATUS_UNKNOWN. EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_UNKNOWN); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); @@ -229,7 +229,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { &createHeapContext, &resourceHeap)); ASSERT_NE(resourceHeap, nullptr); - EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_RESIDENT); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); // Residency status of resource heap types is always known. @@ -242,7 +242,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { ASSERT_SUCCEEDED(residencyManager->LockHeap(resourceHeap.Get())); - EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_RESIDENT); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, true); EXPECT_EQ(GetStats(residencyManager).CurrentHeapUsage, residencyHeapDesc.SizeInBytes); @@ -250,7 +250,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateResourceHeap) { ASSERT_SUCCEEDED(residencyManager->UnlockHeap(resourceHeap.Get())); - EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(resourceHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_RESIDENT); EXPECT_EQ(resourceHeap->GetInfo().IsLocked, false); // Unlocking a heap does not evict it, the memory usage should not change. @@ -296,7 +296,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeap) { ASSERT_SUCCEEDED(residencyManager->LockHeap(descriptorHeap.Get())); - EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_RESIDENT); EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, true); EXPECT_EQ(GetStats(residencyManager).CurrentHeapUsage, descriptorHeapDesc.SizeInBytes); @@ -304,7 +304,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeap) { ASSERT_SUCCEEDED(residencyManager->UnlockHeap(descriptorHeap.Get())); - EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_RESIDENT); EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, false); // Unlocking a heap does not evict it, the memory usage should not change. @@ -337,7 +337,7 @@ TEST_F(D3D12ResidencyManagerTests, CreateDescriptorHeapResident) { CreateDescHeapCallbackContext::CreateResidencyHeap, &createDescHeapCallbackContext, &descriptorHeap)); - EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(descriptorHeap->GetInfo().Status, gpgmm::d3d12::RESIDENCY_HEAP_STATUS_RESIDENT); EXPECT_EQ(descriptorHeap->GetInfo().IsLocked, false); } @@ -715,7 +715,7 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetExecuteCommandList) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( {}, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_RESIDENT); firstSetOfHeaps.push_back(std::move(allocation)); } @@ -725,7 +725,7 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetExecuteCommandList) { ComPtr allocation; ASSERT_SUCCEEDED(resourceAllocator->CreateResource( {}, bufferDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_RESIDENT); secondSetOfHeaps.push_back(std::move(allocation)); } @@ -765,12 +765,12 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetExecuteCommandList) { // Everything below the budget should now be resident. for (auto& allocation : firstSetOfHeaps) { - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_RESIDENT); } // Everything above the budget should now be evicted. for (auto& allocation : secondSetOfHeaps) { - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_PENDING); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_EVICTED); } // Page-in the second set of heaps using ExecuteCommandLists (and page-out the first set). @@ -790,12 +790,12 @@ TEST_F(D3D12ResidencyManagerTests, OverBudgetExecuteCommandList) { // Everything below the budget should now be evicted. for (auto& allocation : firstSetOfHeaps) { - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_PENDING); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_EVICTED); } // Everything above the budget should now be resident. for (auto& allocation : secondSetOfHeaps) { - EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_CURRENT); + EXPECT_EQ(allocation->GetMemory()->GetInfo().Status, RESIDENCY_HEAP_STATUS_RESIDENT); } }