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
1 change: 1 addition & 0 deletions src/gpgmm/d3d12/ResidencyManagerD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ namespace gpgmm::d3d12 {

DXGI_MEMORY_SEGMENT_GROUP ResidencyManager::GetMemorySegmentGroup(
D3D12_MEMORY_POOL memoryPool) const {
ASSERT(memoryPool != D3D12_MEMORY_POOL_UNKNOWN);
return d3d12::GetMemorySegmentGroup(memoryPool, mIsUMA);
}

Expand Down
73 changes: 56 additions & 17 deletions src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,36 @@ namespace gpgmm::d3d12 {
return hr;
}

D3D12_HEAP_PROPERTIES GetHeapProperties(ID3D12Device* device,
D3D12_HEAP_TYPE heapType,
bool isCustomHeapDisabled,
bool isUMA,
bool isResidencyEnabled) {
// Produces the corresponding properties from the corresponding heap type per this table
// https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-getcustomheapproperties
if (!isCustomHeapDisabled) {
return device->GetCustomHeapProperties(0, heapType);
}

D3D12_HEAP_PROPERTIES heapProperties = {};
heapProperties.Type = heapType;

// When residency is disabled, the D3D12 memory pool does not need to be specified
// before allocation.
if (!isResidencyEnabled) {
return heapProperties;
}

// Only L1 exists when non-UMA adapter per MSDN.
if (!isUMA && heapProperties.Type == D3D12_HEAP_TYPE_DEFAULT) {
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_L1;
} else {
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
}

return heapProperties;
}

} // namespace

// static
Expand Down Expand Up @@ -444,7 +474,8 @@ namespace gpgmm::d3d12 {
mIsAlwaysInBudget(descriptor.Flags & ALLOCATOR_FLAG_ALWAYS_IN_BUDGET),
mFlushEventBuffersOnDestruct(descriptor.RecordOptions.EventScope &
EVENT_RECORD_SCOPE_PER_INSTANCE),
mUseDetailedTimingEvents(descriptor.RecordOptions.UseDetailedTimingEvents) {
mUseDetailedTimingEvents(descriptor.RecordOptions.UseDetailedTimingEvents),
mIsCustomHeapsDisabled(descriptor.Flags & ALLOCATOR_FLAG_DISABLE_CUSTOM_HEAPS) {
GPGMM_TRACE_EVENT_OBJECT_NEW(this);

#if defined(GPGMM_ENABLE_ALLOCATOR_LEAK_CHECKS)
Expand All @@ -458,32 +489,34 @@ namespace gpgmm::d3d12 {

const D3D12_HEAP_FLAGS& heapFlags =
GetHeapFlags(resourceHeapType, IsCreateHeapNotResident());
const D3D12_HEAP_TYPE heapType = GetHeapType(resourceHeapType);

const uint64_t msaaHeapAlignment = GetHeapAlignment(heapFlags, true);
const uint64_t heapAlignment = GetHeapAlignment(heapFlags, false);

const D3D12_HEAP_PROPERTIES customHeapProperties =
mDevice->GetCustomHeapProperties(0, GetHeapType(resourceHeapType));
const D3D12_HEAP_PROPERTIES heapProperties =
GetHeapProperties(mDevice.Get(), heapType, mIsCustomHeapsDisabled,
mCaps->IsAdapterUMA(), IsResidencyEnabled());

// General-purpose allocators.
// Used for dynamic resource allocation or when the resource size is not known at
// compile-time.
mResourceAllocatorOfType[resourceHeapTypeIndex] = CreateResourceHeapSubAllocator(
descriptor, heapFlags, customHeapProperties, heapAlignment);
descriptor, heapFlags, heapProperties, heapAlignment);

mMSAAResourceAllocatorOfType[resourceHeapTypeIndex] = CreateResourceHeapSubAllocator(
descriptor, heapFlags, customHeapProperties, msaaHeapAlignment);
descriptor, heapFlags, heapProperties, msaaHeapAlignment);

mResourceHeapAllocatorOfType[resourceHeapTypeIndex] = CreateResourceHeapAllocator(
descriptor, heapFlags, customHeapProperties, heapAlignment);
mResourceHeapAllocatorOfType[resourceHeapTypeIndex] =
CreateResourceHeapAllocator(descriptor, heapFlags, heapProperties, heapAlignment);

mMSAAResourceHeapAllocatorOfType[resourceHeapTypeIndex] = CreateResourceHeapAllocator(
descriptor, heapFlags, customHeapProperties, msaaHeapAlignment);
descriptor, heapFlags, heapProperties, msaaHeapAlignment);

// Resource specific allocators.
mSmallBufferAllocatorOfType[resourceHeapTypeIndex] = CreateSmallBufferAllocator(
descriptor, heapFlags, customHeapProperties, heapAlignment,
GetInitialResourceState(GetHeapType(resourceHeapType)));
mSmallBufferAllocatorOfType[resourceHeapTypeIndex] =
CreateSmallBufferAllocator(descriptor, heapFlags, heapProperties, heapAlignment,
GetInitialResourceState(heapType));

// Cache resource sizes commonly requested.
// Allows the next memory block to be made available upon request without
Expand Down Expand Up @@ -864,12 +897,14 @@ namespace gpgmm::d3d12 {
}
}

D3D12_HEAP_PROPERTIES customHeapProperties = mDevice->GetCustomHeapProperties(0, heapType);
const D3D12_HEAP_PROPERTIES heapProperties =
GetHeapProperties(mDevice.Get(), heapType, mIsCustomHeapsDisabled,
mCaps->IsAdapterUMA(), IsResidencyEnabled());

// Limit available memory to unused budget when residency is enabled.
if (mResidencyManager != nullptr) {
if (IsResidencyEnabled()) {
const DXGI_MEMORY_SEGMENT_GROUP segment =
mResidencyManager->GetMemorySegmentGroup(customHeapProperties.MemoryPoolPreference);
mResidencyManager->GetMemorySegmentGroup(heapProperties.MemoryPoolPreference);
DXGI_QUERY_VIDEO_MEMORY_INFO* currentVideoInfo =
mResidencyManager->GetVideoMemoryInfo(segment);

Expand Down Expand Up @@ -1040,7 +1075,7 @@ namespace gpgmm::d3d12 {

ComPtr<ID3D12Resource> committedResource;
Heap* resourceHeap = nullptr;
ReturnIfFailed(CreateCommittedResource(customHeapProperties, heapFlags, resourceInfo,
ReturnIfFailed(CreateCommittedResource(heapProperties, heapFlags, resourceInfo,
&newResourceDesc, clearValue, initialResourceState,
&committedResource, &resourceHeap));

Expand Down Expand Up @@ -1161,7 +1196,7 @@ namespace gpgmm::d3d12 {
resourceHeapDesc.Alignment = info.Alignment;
resourceHeapDesc.AlwaysInBudget = mIsAlwaysInBudget;

if (mResidencyManager != nullptr) {
if (IsResidencyEnabled()) {
resourceHeapDesc.MemorySegmentGroup =
mResidencyManager->GetMemorySegmentGroup(heapProperties.MemoryPoolPreference);
}
Expand Down Expand Up @@ -1295,7 +1330,11 @@ namespace gpgmm::d3d12 {
}

bool ResourceAllocator::IsCreateHeapNotResident() const {
return mResidencyManager != nullptr && !mIsAlwaysInBudget;
return IsResidencyEnabled() && !mIsAlwaysInBudget;
}

bool ResourceAllocator::IsResidencyEnabled() const {
return mResidencyManager != nullptr;
}

HRESULT ResourceAllocator::CheckFeatureSupport(FEATURE feature,
Expand Down
9 changes: 9 additions & 0 deletions src/gpgmm/d3d12/ResourceAllocatorD3D12.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ namespace gpgmm::d3d12 {
minimal possible GPU memory footprint or debugging OOM failures.
*/
ALLOCATOR_FLAG_ALWAYS_ON_DEMAND = 0x8,

/** \brief Disables use of D3D12_HEAP_TYPE_CUSTOM.

Used to workaround issues when a custom-equivalent heap is not considered equal to
the corresponding heap type.
*/
ALLOCATOR_FLAG_DISABLE_CUSTOM_HEAPS = 0x10,
};

DEFINE_ENUM_FLAG_OPERATORS(ALLOCATOR_FLAGS)
Expand Down Expand Up @@ -585,6 +592,7 @@ namespace gpgmm::d3d12 {
static HRESULT ReportLiveDeviceObjects(ComPtr<ID3D12Device> device);

bool IsCreateHeapNotResident() const;
bool IsResidencyEnabled() const;

// MemoryAllocator interface
void DeallocateMemory(std::unique_ptr<MemoryAllocation> allocation) override;
Expand All @@ -601,6 +609,7 @@ namespace gpgmm::d3d12 {
const bool mIsAlwaysInBudget;
const bool mFlushEventBuffersOnDestruct;
const bool mUseDetailedTimingEvents;
const bool mIsCustomHeapsDisabled;

static constexpr uint64_t kNumOfResourceHeapTypes = 8u;

Expand Down
1 change: 1 addition & 0 deletions src/include/min/gpgmm_d3d12.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ namespace gpgmm::d3d12 {
ALLOCATOR_FLAG_ALWAYS_IN_BUDGET = 0x2,
ALLOCATOR_FLAG_DISABLE_MEMORY_PREFETCH = 0x4,
ALLOCATOR_FLAG_ALWAYS_ON_DEMAND = 0x8,
ALLOCATOR_FLAG_DISABLE_CUSTOM_HEAPS = 0x10,
};

DEFINE_ENUM_FLAG_OPERATORS(ALLOCATOR_FLAGS)
Expand Down
17 changes: 17 additions & 0 deletions src/tests/end2end/D3D12ResourceAllocatorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,23 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferUMA) {
EXPECT_EQ(resourceAllocator->GetInfo().FreeMemoryUsage, kDefaultBufferSize * 2);
}

TEST_F(D3D12ResourceAllocatorTests, CreateBufferDisableCustomHeaps) {
ALLOCATOR_DESC allocatorDesc = CreateBasicAllocatorDesc();
allocatorDesc.Flags |= ALLOCATOR_FLAG_DISABLE_CUSTOM_HEAPS;

ComPtr<ResourceAllocator> resourceAllocator;
ASSERT_SUCCEEDED(ResourceAllocator::CreateAllocator(allocatorDesc, &resourceAllocator));

ComPtr<ResourceAllocation> allocation;
ASSERT_SUCCEEDED(
resourceAllocator->CreateResource({}, CreateBasicBufferDesc(kDefaultBufferSize),
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &allocation));

D3D12_HEAP_PROPERTIES heapProperties = {};
ASSERT_SUCCEEDED(allocation->GetResource()->GetHeapProperties(&heapProperties, nullptr));
EXPECT_NE(heapProperties.Type, D3D12_HEAP_TYPE_CUSTOM);
}

TEST_F(D3D12ResourceAllocatorTests, CreateSmallTexture) {
ComPtr<ResourceAllocator> resourceAllocator;
ASSERT_SUCCEEDED(
Expand Down