From b0b568e32e854a720e97e1085151f54c7e62f047 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 29 Mar 2018 20:05:30 -0700 Subject: Implemented option to specify hardware adapter when initializing the engine in d3d mode --- Graphics/GraphicsEngine/interface/GraphicsTypes.h | 5 +++ .../interface/EngineD3D11Attribs.h | 5 +++ .../src/RenderDeviceFactoryD3D11.cpp | 23 +++++++++++--- .../src/RenderDeviceFactoryD3D12.cpp | 26 +++++++++++++-- .../include/EngineFactoryD3DBase.h | 37 +++++++++++----------- 5 files changed, 71 insertions(+), 25 deletions(-) (limited to 'Graphics') diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 2a223e43..574e4c12 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -1050,6 +1050,11 @@ namespace Diligent /// Attributes specific to D3D12 engine struct EngineD3D12Attribs : public EngineCreationAttribs { + static constexpr Uint32 DefaultAdapterId = 0xFFFFFFFF; + + /// Id of the hardware adapter the engine should be initialized on + Uint32 AdapterId = DefaultAdapterId; + /// Size of the CPU descriptor heap allocations for different heap types. Uint32 CPUDescriptorHeapAllocationSize[4] = { diff --git a/Graphics/GraphicsEngineD3D11/interface/EngineD3D11Attribs.h b/Graphics/GraphicsEngineD3D11/interface/EngineD3D11Attribs.h index 912cb474..bdb2a28b 100644 --- a/Graphics/GraphicsEngineD3D11/interface/EngineD3D11Attribs.h +++ b/Graphics/GraphicsEngineD3D11/interface/EngineD3D11Attribs.h @@ -49,6 +49,11 @@ namespace Diligent /// Attributes of the Direct3D11-based engine implementation struct EngineD3D11Attribs : public EngineCreationAttribs { + static constexpr Uint32 DefaultAdapterId = 0xFFFFFFFF; + + /// Id of the hardware adapter the engine should be initialized on + Uint32 AdapterId = DefaultAdapterId; + /// Debug flags. See Diligent::EngineD3D11DebugFlags for a list of allowed values. /// /// \sa CreateDeviceAndContextsD3D11Type, CreateSwapChainD3D11Type, LoadGraphicsEngineD3D11 diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp index e6a1f711..fc33ddb7 100644 --- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceFactoryD3D11.cpp @@ -102,7 +102,10 @@ inline bool SdkLayersAvailable() /// of deferred contexts is requested, pointers to the /// contexts are written to ppContexts array starting /// at position 1 -void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11( const EngineD3D11Attribs& EngineAttribs, IRenderDevice **ppDevice, IDeviceContext **ppContexts, Uint32 NumDeferredContexts ) +void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11( const EngineD3D11Attribs& EngineAttribs, + IRenderDevice **ppDevice, + IDeviceContext **ppContexts, + Uint32 NumDeferredContexts ) { if (EngineAttribs.DebugMessageCallback != nullptr) SetDebugMessageCallback(EngineAttribs.DebugMessageCallback); @@ -148,10 +151,22 @@ void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11( const EngineD3D11Attr CComPtr pd3d11Device; CComPtr pd3d11Context; + CComPtr hardwareAdapter; + if(EngineAttribs.AdapterId != EngineD3D11Attribs::DefaultAdapterId) + { + auto Adapters = FindCompatibleAdapters(); + if (EngineAttribs.AdapterId < Adapters.size()) + hardwareAdapter = Adapters[EngineAttribs.AdapterId]; + else + { + LOG_ERROR_AND_THROW(EngineAttribs.AdapterId, " is not a valid hardware adapter id. Total number of compatible adapters available on this system: ", Adapters.size()); + } + } + D3D_FEATURE_LEVEL d3dFeatureLevel = D3D_FEATURE_LEVEL_11_0; HRESULT hr = D3D11CreateDevice( - nullptr, // Specify nullptr to use the default adapter. - D3D_DRIVER_TYPE_HARDWARE, // Create a device using the hardware graphics driver. + hardwareAdapter, // Specify nullptr to use the default adapter. + hardwareAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, // Create a device using the hardware graphics driver. 0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE. creationFlags, // Set debug and Direct2D compatibility flags. featureLevels, // List of feature levels this app can support. @@ -168,7 +183,7 @@ void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11( const EngineD3D11Attr // For more information on WARP, see: // http://go.microsoft.com/fwlink/?LinkId=286690 hr = D3D11CreateDevice( - nullptr, + nullptr, D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device. 0, creationFlags, diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp index 8e41f986..fb7cb83b 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceFactoryD3D12.cpp @@ -89,7 +89,6 @@ void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) // actual device yet. if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) { - LOG_INFO_MESSAGE("D3D12-capabale hardware found: ", NarrowString(desc.Description), " (", desc.DedicatedVideoMemory>>20, " MB)"); break; } } @@ -162,8 +161,29 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12( const EngineD3D12Attr CHECK_D3D_RESULT_THROW(hr, "Failed to create DXGI factory") CComPtr hardwareAdapter; - GetHardwareAdapter(factory, &hardwareAdapter); - + if(CreationAttribs.AdapterId == EngineD3D12Attribs::DefaultAdapterId) + { + GetHardwareAdapter(factory, &hardwareAdapter); + if(hardwareAdapter == nullptr) + LOG_ERROR_AND_THROW("No suitable hardware adapter found"); + } + else + { + auto Adapters = FindCompatibleAdapters(); + if(CreationAttribs.AdapterId < Adapters.size()) + hardwareAdapter = Adapters[CreationAttribs.AdapterId]; + else + { + LOG_ERROR_AND_THROW(CreationAttribs.AdapterId, " is not a valid hardware adapter id. Total number of compatible adapters available on this system: ", Adapters.size()); + } + } + + { + DXGI_ADAPTER_DESC1 desc; + hardwareAdapter->GetDesc1(&desc); + LOG_INFO_MESSAGE("D3D12-capabale hardware found: ", NarrowString(desc.Description), " (", desc.DedicatedVideoMemory >> 20, " MB)"); + } + hr = D3D12CreateDevice(hardwareAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(d3d12Device), reinterpret_cast(static_cast(&d3d12Device)) ); if( FAILED(hr)) { diff --git a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h index 3e91851a..86142c8c 100644 --- a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h +++ b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h @@ -147,30 +147,13 @@ public: } } -private: - - template - bool CheckAdapterCompatibility(IDXGIAdapter1 *pDXGIAdapter); - - template<> - bool CheckAdapterCompatibility(IDXGIAdapter1 *pDXGIAdapter) - { - return true; - } - - template<> - bool CheckAdapterCompatibility(IDXGIAdapter1 *pDXGIAdapter) - { - auto hr = D3D12CreateDevice(pDXGIAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr); - return SUCCEEDED(hr); - } std::vector> FindCompatibleAdapters() { std::vector> DXGIAdapters; CComPtr pFactory; - if (FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)&pFactory))) + if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory2), (void**)&pFactory))) { LOG_ERROR_MESSAGE("Failed to create DXGI Factory"); return std::move(DXGIAdapters); @@ -198,6 +181,24 @@ private: return std::move(DXGIAdapters); } + +private: + + template + bool CheckAdapterCompatibility(IDXGIAdapter1 *pDXGIAdapter); + + template<> + bool CheckAdapterCompatibility(IDXGIAdapter1 *pDXGIAdapter) + { + return true; + } + + template<> + bool CheckAdapterCompatibility(IDXGIAdapter1 *pDXGIAdapter) + { + auto hr = D3D12CreateDevice(pDXGIAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr); + return SUCCEEDED(hr); + } }; } -- cgit v1.2.3