diff --git a/include/gpgmm_d3d12.h b/include/gpgmm_d3d12.h index 1154d5eba..bcbd8c5b8 100644 --- a/include/gpgmm_d3d12.h +++ b/include/gpgmm_d3d12.h @@ -779,7 +779,11 @@ namespace gpgmm::d3d12 { /** \brief Specifies the adapter used by this allocator. - Required parameter. Use EnumAdapters to get the adapter. + The adapter is used to detect for additional device capabilities (by GPU vendor). + If the adapter is left unspecified, the capabiltities will not be detected and disabled by + CheckFeatureSupport. + + Optional parameter. Use EnumAdapters to get the adapter. */ Microsoft::WRL::ComPtr Adapter; diff --git a/src/gpgmm/d3d12/CapsD3D12.cpp b/src/gpgmm/d3d12/CapsD3D12.cpp index ac8066e5b..68026e5c1 100644 --- a/src/gpgmm/d3d12/CapsD3D12.cpp +++ b/src/gpgmm/d3d12/CapsD3D12.cpp @@ -81,8 +81,9 @@ namespace gpgmm::d3d12 { // static HRESULT Caps::CreateCaps(ID3D12Device* device, IDXGIAdapter* adapter, Caps** capsOut) { - DXGI_ADAPTER_DESC adapterDesc; - ReturnIfFailed(adapter->GetDesc(&adapterDesc)); + if (device == nullptr) { + return E_INVALIDARG; + } std::unique_ptr caps(new Caps()); ReturnIfFailed(SetMaxResourceSize(device, &caps->mMaxResourceSize)); @@ -97,12 +98,23 @@ namespace gpgmm::d3d12 { caps->mIsAdapterUMA = arch.UMA; caps->mIsAdapterCacheCoherentUMA = arch.CacheCoherentUMA; - // D3D12 has no feature to detect support and must be set manually. - if (adapterDesc.VendorId == static_cast(GPUVendor::kIntel_VkVendor)) { - caps->mIsResourceAllocationWithinCoherent = true; + if (adapter != nullptr) { + DXGI_ADAPTER_DESC adapterDesc; + ReturnIfFailed(adapter->GetDesc(&adapterDesc)); + + // D3D12 has no feature to detect support and must be set manually. + if (adapterDesc.VendorId == static_cast(GPUVendor::kIntel_VkVendor)) { + caps->mIsResourceAllocationWithinCoherent = true; + } + } else { + gpgmm::WarningLog() + << "DXGIAdapter was left unspecified. Not device capabilities could be detected."; + } + + if (capsOut != nullptr) { + *capsOut = caps.release(); } - *capsOut = caps.release(); return S_OK; } diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 8e6f92dc3..49a615cb0 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -381,23 +381,24 @@ namespace gpgmm::d3d12 { HRESULT ResourceAllocator::CreateResourceAllocator(const ALLOCATOR_DESC& allocatorDescriptor, IResourceAllocator** ppResourceAllocatorOut, IResidencyManager** ppResidencyManagerOut) { - if (allocatorDescriptor.Device == nullptr || allocatorDescriptor.Adapter == nullptr) { + if (allocatorDescriptor.Device == nullptr) { return E_INVALIDARG; } ComPtr residencyManager; if (ppResidencyManagerOut != nullptr) { + RESIDENCY_DESC residencyDesc = {}; + residencyDesc.Device = allocatorDescriptor.Device; + ReturnIfFailed(allocatorDescriptor.Adapter.As(&residencyDesc.Adapter)); + std::unique_ptr caps; { Caps* ptr = nullptr; - ReturnIfFailed(Caps::CreateCaps(allocatorDescriptor.Device.Get(), - allocatorDescriptor.Adapter.Get(), &ptr)); + ReturnIfFailed(Caps::CreateCaps(residencyDesc.Device.Get(), + residencyDesc.Adapter.Get(), &ptr)); caps.reset(ptr); } - RESIDENCY_DESC residencyDesc = {}; - residencyDesc.Device = allocatorDescriptor.Device; - ReturnIfFailed(allocatorDescriptor.Adapter.As(&residencyDesc.Adapter)); residencyDesc.IsUMA = caps->IsAdapterUMA(); residencyDesc.MinLogLevel = allocatorDescriptor.MinLogLevel; residencyDesc.RecordOptions = allocatorDescriptor.RecordOptions; @@ -426,7 +427,7 @@ namespace gpgmm::d3d12 { const ALLOCATOR_DESC& allocatorDescriptor, IResidencyManager* pResidencyManager, IResourceAllocator** ppResourceAllocatorOut) { - if (allocatorDescriptor.Adapter == nullptr || allocatorDescriptor.Device == nullptr) { + if (allocatorDescriptor.Device == nullptr) { return E_INVALIDARG; } @@ -439,7 +440,7 @@ namespace gpgmm::d3d12 { } if (allocatorDescriptor.ResourceHeapTier > caps->GetMaxResourceHeapTierSupported()) { - gpgmm::ErrorLog() << "Resource heap tier exceeds the capabilities of the adapter " + gpgmm::ErrorLog() << "Resource heap tier exceeds the capabilities of the device " "(ResourceHeapTier:" << allocatorDescriptor.ResourceHeapTier << " vs " << caps->GetMaxResourceHeapTierSupported() @@ -449,7 +450,7 @@ namespace gpgmm::d3d12 { if (allocatorDescriptor.ResourceHeapTier < caps->GetMaxResourceHeapTierSupported()) { gpgmm::DebugLog() - << "Resource heap tier requested was lower than what the adapter " + << "Resource heap tier requested was lower than what the device " "supports. This is allowed but not recommended because it prevents " "resources of different categories from sharing the same heap."; } @@ -489,7 +490,7 @@ namespace gpgmm::d3d12 { gpgmm::DebugLog() << "ALLOCATOR_FLAG_ALWAYS_IN_BUDGET was not requested but enabled " - "anyway because the adapter did not support creating non-resident heaps."; + "anyway because the device did not support creating non-resident heaps."; } newDescriptor.MaxResourceHeapSize = @@ -508,7 +509,7 @@ namespace gpgmm::d3d12 { if (newDescriptor.PreferredResourceHeapSize > newDescriptor.MaxResourceHeapSize) { gpgmm::ErrorLog() << "Requested preferred resource heap size exceeded the capabilities " - "of the adapter. This is probably not what the developer intended " + "of the device. This is probably not what the developer intended " "to do. Please consider using a smaller resource heap size."; return E_INVALIDARG; } diff --git a/src/mvi/gpgmm_d3d12.cpp b/src/mvi/gpgmm_d3d12.cpp index 9a108dc88..f138225fc 100644 --- a/src/mvi/gpgmm_d3d12.cpp +++ b/src/mvi/gpgmm_d3d12.cpp @@ -293,7 +293,7 @@ namespace gpgmm::d3d12 { HRESULT ResourceAllocator::CreateResourceAllocator(const ALLOCATOR_DESC& allocatorDescriptor, IResourceAllocator** ppResourceAllocatorOut, IResidencyManager** ppResidencyManagerOut) { - if (allocatorDescriptor.Device == nullptr || allocatorDescriptor.Adapter == nullptr) { + if (allocatorDescriptor.Device == nullptr) { return E_INVALIDARG; } diff --git a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp index 073aa3854..9de329d2a 100644 --- a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp +++ b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp @@ -117,14 +117,15 @@ TEST_F(D3D12ResourceAllocatorTests, CreateResourceAllocator) { EXPECT_EQ(resourceAllocator, nullptr); } - // Creating an allocator without an adapter should always fail. + // Creating an allocator without the adapter should always succeed. + // Should output warning messages that some capabilities were not detected. { ALLOCATOR_DESC desc = CreateBasicAllocatorDesc(); desc.Adapter = nullptr; ComPtr resourceAllocator; - EXPECT_FAILED(CreateResourceAllocator(desc, &resourceAllocator, nullptr)); - EXPECT_EQ(resourceAllocator, nullptr); + EXPECT_SUCCEEDED(CreateResourceAllocator(desc, &resourceAllocator, nullptr)); + EXPECT_NE(resourceAllocator, nullptr); } // Creating a new allocator using the defaults should always succeed.