Skip to content

Commit b58b417

Browse files
authored
Do not track created non-resource heaps in residency cache by default. (#649)
1 parent 8700324 commit b58b417

File tree

7 files changed

+190
-62
lines changed

7 files changed

+190
-62
lines changed

src/gpgmm/d3d12/HeapD3D12.cpp

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,35 @@
2323

2424
namespace gpgmm::d3d12 {
2525

26+
namespace {
27+
28+
// Returns the resource heap flags or E_INVALIDARG, when the memory type doesn't allow
29+
// resources.
30+
HRESULT GetResourceHeapFlags(ComPtr<ID3D12Pageable> pageable, D3D12_HEAP_FLAGS* heapFlags) {
31+
ComPtr<ID3D12Heap> heap;
32+
if (SUCCEEDED(pageable.As(&heap))) {
33+
*heapFlags = heap->GetDesc().Flags;
34+
return S_OK;
35+
}
36+
37+
ComPtr<ID3D12Resource> committedResource;
38+
if (SUCCEEDED(pageable.As(&committedResource))) {
39+
ReturnIfFailed(committedResource->GetHeapProperties(nullptr, heapFlags));
40+
return S_OK;
41+
}
42+
43+
return E_INVALIDARG;
44+
}
45+
} // namespace
46+
2647
// static
2748
HRESULT Heap::CreateHeap(const HEAP_DESC& descriptor,
2849
ResidencyManager* const pResidencyManager,
2950
CreateHeapFn&& createHeapFn,
3051
Heap** ppHeapOut) {
3152
const bool isResidencyDisabled = (pResidencyManager == nullptr);
3253

33-
// Ensure enough budget exists before allocating to avoid an out-of-memory error.
54+
// Ensure enough budget exists before creating the heap to avoid an out-of-memory error.
3455
if (!isResidencyDisabled && (descriptor.Flags & HEAP_FLAG_ALWAYS_IN_BUDGET)) {
3556
ReturnIfFailed(pResidencyManager->EnsureInBudget(descriptor.SizeInBytes,
3657
descriptor.MemorySegmentGroup));
@@ -51,28 +72,33 @@ namespace gpgmm::d3d12 {
5172
std::unique_ptr<Heap> heap(new Heap(pageable, descriptor, isResidencyDisabled));
5273

5374
if (!isResidencyDisabled) {
54-
ReturnIfFailed(pResidencyManager->InsertHeap(heap.get()));
55-
5675
// Check if the underlying memory was implicitly made resident.
57-
// This is always the case for resource heaps unless the "not resident" flag was
58-
// explicitly used in createHeapFn().
5976
D3D12_HEAP_FLAGS resourceHeapFlags = D3D12_HEAP_FLAG_NONE;
60-
61-
ComPtr<ID3D12Heap> d3d12Heap;
62-
if (SUCCEEDED(pageable.As(&d3d12Heap))) {
63-
resourceHeapFlags = d3d12Heap->GetDesc().Flags;
77+
if (SUCCEEDED(GetResourceHeapFlags(pageable, &resourceHeapFlags))) {
78+
// Resource heaps created without the "create not resident" flag are always
79+
// resident.
80+
if (!(resourceHeapFlags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT)) {
81+
heap->mState = CURRENT_RESIDENT;
82+
} else {
83+
heap->mState = PENDING_RESIDENCY;
84+
}
6485
}
6586

66-
ComPtr<ID3D12Resource> committedResource;
67-
if (SUCCEEDED(pageable.As(&committedResource))) {
68-
ReturnIfFailed(committedResource->GetHeapProperties(nullptr, &resourceHeapFlags));
87+
// Heap created not resident requires no budget to be created.
88+
if (heap->mState == PENDING_RESIDENCY &&
89+
(descriptor.Flags & HEAP_FLAG_ALWAYS_IN_BUDGET)) {
90+
gpgmm::ErrorLog() << "Creating a heap always in budget cannot be used with "
91+
"D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT.";
92+
return E_INVALIDARG;
6993
}
7094

71-
if ((d3d12Heap || committedResource) &&
72-
!(resourceHeapFlags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT)) {
73-
heap->mState = CURRENT_RESIDENT;
74-
} else {
75-
heap->mState = PENDING_RESIDENCY;
95+
// Only heap types that are known to be created resident are eligable for evicition and
96+
// should be always inserted in the residency cache. For other heap types (eg.
97+
// descriptor heap), they must be manually locked and unlocked to be inserted into the
98+
// residency cache. This is to ensure MakeResident is always called on heaps which are
99+
// not known (or guarenteed) to be created implicitly resident by D3D12.
100+
if (heap->mState != RESIDENCY_UNKNOWN) {
101+
ReturnIfFailed(pResidencyManager->InsertHeap(heap.get()));
76102
}
77103
}
78104

src/gpgmm/d3d12/ResidencyManagerD3D12.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,23 @@ namespace gpgmm::d3d12 {
289289
ReturnIfFailed(MakeResident(pHeap->GetMemorySegmentGroup(), pHeap->GetSize(), 1,
290290
pageable.GetAddressOf()));
291291
pHeap->SetResidencyState(CURRENT_RESIDENT);
292+
293+
// Untracked heaps, created not resident, are not already attributed toward residency
294+
// usage because they are not in the residency cache.
295+
mInfo.CurrentMemoryCount++;
296+
mInfo.CurrentMemoryUsage += pHeap->GetSize();
292297
}
293298

294299
// Since we can't evict the heap, it's unnecessary to track the heap in the LRU Cache.
295300
if (pHeap->IsInList()) {
296301
pHeap->RemoveFromList();
297302

298-
// Untracked heaps are not attributed toward residency usage.
299-
mInfo.CurrentMemoryCount++;
300-
mInfo.CurrentMemoryUsage += pHeap->GetSize();
303+
// Untracked heaps, previously made resident, are not attributed toward residency usage
304+
// because they will be removed from the residency cache.
305+
if (pHeap->mState == CURRENT_RESIDENT) {
306+
mInfo.CurrentMemoryCount++;
307+
mInfo.CurrentMemoryUsage += pHeap->GetSize();
308+
}
301309
}
302310

303311
pHeap->AddResidencyLockRef();

src/tests/D3D12Test.cpp

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,6 @@ namespace gpgmm::d3d12 {
6161
ASSERT_SUCCEEDED(dxgiFactory4->EnumAdapterByLuid(adapterLUID, IID_PPV_ARGS(&mAdapter)));
6262
ASSERT_NE(mAdapter.Get(), nullptr);
6363

64-
D3D12_FEATURE_DATA_ARCHITECTURE arch = {};
65-
ASSERT_SUCCEEDED(
66-
mDevice->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &arch, sizeof(arch)));
67-
mIsUMA = arch.UMA;
68-
69-
D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
70-
ASSERT_SUCCEEDED(
71-
mDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)));
72-
mResourceHeapTier = options.ResourceHeapTier;
73-
7464
DXGI_ADAPTER_DESC adapterDesc;
7565
ASSERT_SUCCEEDED(mAdapter->GetDesc(&adapterDesc));
7666

@@ -86,23 +76,20 @@ namespace gpgmm::d3d12 {
8676
DebugLog() << "GPU memory: " << GPGMM_BYTES_TO_GB(adapterDesc.DedicatedVideoMemory)
8777
<< " GBs.";
8878

89-
DebugLog() << "Unified memory: " << ((arch.UMA) ? "yes" : "no")
90-
<< ((arch.CacheCoherentUMA) ? " (cache-coherent)" : "");
79+
Caps* capsPtr = nullptr;
80+
ASSERT_SUCCEEDED(Caps::CreateCaps(mDevice.Get(), mAdapter.Get(), &capsPtr));
81+
mCaps.reset(capsPtr);
9182

92-
std::unique_ptr<Caps> caps;
93-
{
94-
Caps* capsPtr = nullptr;
95-
ASSERT_SUCCEEDED(Caps::CreateCaps(mDevice.Get(), mAdapter.Get(), &capsPtr));
96-
caps.reset(capsPtr);
97-
}
83+
DebugLog() << "Unified memory: " << ((mCaps->IsAdapterUMA()) ? "yes" : "no")
84+
<< ((mCaps->IsAdapterCacheCoherentUMA()) ? " (cache-coherent)" : "");
9885

99-
DebugLog() << "Max resource size: " << GPGMM_BYTES_TO_MB(caps->GetMaxResourceSize())
86+
DebugLog() << "Max resource size: " << GPGMM_BYTES_TO_MB(mCaps->GetMaxResourceSize())
10087
<< " MBs";
101-
DebugLog() << "Max resource heap tier: " << caps->GetMaxResourceHeapTierSupported();
88+
DebugLog() << "Max resource heap tier: " << mCaps->GetMaxResourceHeapTierSupported();
10289
DebugLog() << "Max resource heap size: "
103-
<< GPGMM_BYTES_TO_GB(caps->GetMaxResourceHeapSize()) << " GBs";
90+
<< GPGMM_BYTES_TO_GB(mCaps->GetMaxResourceHeapSize()) << " GBs";
10491
DebugLog() << "Creation of non-resident heaps: "
105-
<< ((caps->IsCreateHeapNotResidentSupported()) ? "Supported" : "Not supported");
92+
<< ((mCaps->IsCreateHeapNotResidentSupported()) ? "Supported" : "Not supported");
10693
}
10794

10895
void D3D12TestBase::TearDown() {
@@ -115,7 +102,7 @@ namespace gpgmm::d3d12 {
115102
// Required parameters.
116103
desc.Adapter = mAdapter;
117104
desc.Device = mDevice;
118-
desc.ResourceHeapTier = mResourceHeapTier;
105+
desc.ResourceHeapTier = mCaps->GetMaxResourceHeapTierSupported();
119106

120107
desc.MinLogLevel = GetMessageSeverity(GetLogLevel());
121108

src/tests/D3D12Test.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
namespace gpgmm::d3d12 {
3131

3232
struct ALLOCATOR_DESC;
33+
class Caps;
3334
class ResourceAllocator;
3435
class ResourceAllocation;
3536

@@ -59,9 +60,7 @@ namespace gpgmm::d3d12 {
5960
protected:
6061
ComPtr<IDXGIAdapter3> mAdapter;
6162
ComPtr<ID3D12Device> mDevice;
62-
63-
bool mIsUMA = false;
64-
D3D12_RESOURCE_HEAP_TIER mResourceHeapTier = D3D12_RESOURCE_HEAP_TIER_1;
63+
std::unique_ptr<Caps> mCaps;
6564
};
6665

6766
} // namespace gpgmm::d3d12

src/tests/capture_replay_tests/D3D12EventTraceReplay.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "gpgmm/common/SizeClass.h"
1919
#include "gpgmm/common/TraceEventPhase.h"
20+
#include "gpgmm/d3d12/CapsD3D12.h"
2021
#include "gpgmm/d3d12/ErrorD3D12.h"
2122
#include "gpgmm/d3d12/UtilsD3D12.h"
2223
#include "gpgmm/utils/Log.h"
@@ -300,18 +301,19 @@ class D3D12EventTraceReplay : public D3D12TestBase, public CaptureReplayTestWith
300301
ASSERT_FALSE(snapshot.empty());
301302

302303
if (GetLogLevel() <= gpgmm::LogSeverity::Warning &&
303-
mIsUMA != snapshot["IsUMA"].asBool() && iterationIndex == 0) {
304+
mCaps->IsAdapterUMA() != snapshot["IsUMA"].asBool() &&
305+
iterationIndex == 0) {
304306
gpgmm::WarningLog()
305307
<< "Capture device does not match playback device (IsUMA: " +
306308
std::to_string(snapshot["IsUMA"].asBool()) + " vs " +
307-
std::to_string(mIsUMA) + ").";
309+
std::to_string(mCaps->IsAdapterUMA()) + ").";
308310
GPGMM_SKIP_TEST_IF(!envParams.IsIgnoreCapsMismatchEnabled);
309311
}
310312

311313
RESIDENCY_DESC residencyDesc = {};
312314
residencyDesc.Device = mDevice;
313315
residencyDesc.Adapter = mAdapter;
314-
residencyDesc.IsUMA = mIsUMA;
316+
residencyDesc.IsUMA = mCaps->IsAdapterUMA();
315317
residencyDesc.MaxPctOfVideoMemoryToBudget =
316318
snapshot["MaxPctOfVideoMemoryToBudget"].asFloat();
317319
residencyDesc.MaxBudgetInBytes = snapshot["MaxBudgetInBytes"].asUInt64();
@@ -494,8 +496,8 @@ class D3D12EventTraceReplay : public D3D12TestBase, public CaptureReplayTestWith
494496
HEAP_DESC resourceHeapDesc = {};
495497
resourceHeapDesc.SizeInBytes = args["Heap"]["SizeInBytes"].asUInt64();
496498
resourceHeapDesc.Alignment = args["Heap"]["Alignment"].asUInt64();
497-
resourceHeapDesc.MemorySegmentGroup =
498-
GetMemorySegmentGroup(heapProperties.MemoryPoolPreference, mIsUMA);
499+
resourceHeapDesc.MemorySegmentGroup = GetMemorySegmentGroup(
500+
heapProperties.MemoryPoolPreference, mCaps->IsAdapterUMA());
499501

500502
ResidencyManager* residencyManager =
501503
createdResidencyManagerToID[currentResidencyID].Get();

0 commit comments

Comments
 (0)