From bcbeaf54fe7125f966db883999314b5a3a107219 Mon Sep 17 00:00:00 2001 From: "Bernhart, Bryan" Date: Thu, 19 Jan 2023 16:07:58 -0800 Subject: [PATCH] Disable custom heaps when UMA is not supported. --- include/gpgmm_d3d12.h | 11 ++++++----- src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp | 14 ++++++++++++-- src/tests/end2end/D3D12ResourceAllocatorTests.cpp | 4 ++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/include/gpgmm_d3d12.h b/include/gpgmm_d3d12.h index 497522ead..ee6f247bc 100644 --- a/include/gpgmm_d3d12.h +++ b/include/gpgmm_d3d12.h @@ -684,12 +684,13 @@ namespace gpgmm::d3d12 { */ ALLOCATOR_FLAG_ALWAYS_ON_DEMAND = 0x8, - /** \brief Disables use of D3D12_HEAP_TYPE_CUSTOM. + /** \brief Disables using D3D12_HEAP_TYPE_CUSTOM-equivalent upload heap everywhere on UMA + GPUs. - Used to workaround issues when a custom-equivalent heap is not considered equal to - the corresponding heap type. + Used to workaround issues when custom heaps are not being recongized as expected or driver + bugs related to using a single memory pool. */ - ALLOCATOR_FLAG_DISABLE_CUSTOM_HEAPS = 0x10, + ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY = 0x10, /** \brief Report leaks of resource allocations. @@ -974,7 +975,7 @@ namespace gpgmm::d3d12 { as well as frequent CPU reads would beneifit from D3D12_HEAP_TYPE_READBACK since the CPU properties are always write-combined. - If ALLOCATOR_FLAG_DISABLE_CUSTOM_HEAPS was specified, heap type was + If ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY was specified, heap type was D3D12_HEAP_TYPE_READBACK, or the adapter is not cache-coherent UMA, this flag has no effect. */ ALLOCATION_FLAG_ALWAYS_ATTRIBUTE_HEAPS = 0x20, diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 056a287b4..4851a9da6 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -476,6 +476,16 @@ namespace gpgmm::d3d12 { newDescriptor.SubAllocationAlgorithm = ALLOCATOR_ALGORITHM_SLAB; } + // By default, UMA is allowed to use a single heap type. Unless it is explicitly disabled or + // unsupported by the device. + if (!(allocatorDescriptor.Flags & ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY) && + !caps->IsAdapterCacheCoherentUMA()) { + gpgmm::DebugLog() + << "ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY was not requested but enabled " + "anyway because the device did not support cache-coherent UMA."; + newDescriptor.Flags |= ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY; + } + // Resource heap tier is required but user didn't specify one. if (newDescriptor.ResourceHeapTier == 0) { newDescriptor.ResourceHeapTier = caps->GetMaxResourceHeapTierSupported(); @@ -569,7 +579,7 @@ namespace gpgmm::d3d12 { mFlushEventBuffersOnDestruct(descriptor.RecordOptions.EventScope & EVENT_RECORD_SCOPE_PER_INSTANCE), mUseDetailedTimingEvents(descriptor.RecordOptions.UseDetailedTimingEvents), - mIsCustomHeapsDisabled(descriptor.Flags & ALLOCATOR_FLAG_DISABLE_CUSTOM_HEAPS) { + mIsCustomHeapsDisabled(descriptor.Flags & ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY) { GPGMM_TRACE_EVENT_OBJECT_NEW(this); if (descriptor.Flags & ALLOCATOR_FLAG_NEVER_LEAK_MEMORY) { @@ -938,7 +948,7 @@ namespace gpgmm::d3d12 { // read-back would be inefficent since upload heaps on UMA adapters are usually // write-combined (vs write-back) so leave read back heaps alone. if (!(allocationDescriptor.Flags & ALLOCATION_FLAG_ALWAYS_ATTRIBUTE_HEAPS) && - mCaps->IsAdapterCacheCoherentUMA() && !mIsCustomHeapsDisabled) { + !mIsCustomHeapsDisabled) { if (allocationDescriptor.HeapType != D3D12_HEAP_TYPE_READBACK) { heapType = D3D12_HEAP_TYPE_UPLOAD; } else { diff --git a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp index 0c998e1ea..168eed6dd 100644 --- a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp +++ b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp @@ -714,9 +714,9 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferUMA) { EXPECT_EQ(resourceAllocator->GetStats().FreeMemoryUsage, kBufferOf4MBAllocationSize * 2); } -TEST_F(D3D12ResourceAllocatorTests, CreateBufferDisableCustomHeaps) { +TEST_F(D3D12ResourceAllocatorTests, CreateBufferDisableUMA) { ALLOCATOR_DESC allocatorDesc = CreateBasicAllocatorDesc(); - allocatorDesc.Flags |= ALLOCATOR_FLAG_DISABLE_CUSTOM_HEAPS; + allocatorDesc.Flags |= ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY; ComPtr resourceAllocator; ASSERT_SUCCEEDED(CreateResourceAllocator(allocatorDesc, &resourceAllocator, nullptr));