diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-10-17 04:06:08 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-10-17 04:06:08 +0000 |
| commit | bc4a29a1fac0276e499bb37bb3c449ebdcacbe92 (patch) | |
| tree | 50316f6b243300fdf9ef25afe1aad5d619ccfa08 /Graphics | |
| parent | Added option to install PDB files on Windows (closed https://github.com/Dilig... (diff) | |
| download | DiligentCore-bc4a29a1fac0276e499bb37bb3c449ebdcacbe92.tar.gz DiligentCore-bc4a29a1fac0276e499bb37bb3c449ebdcacbe92.zip | |
A bunch of updates to specify minimum feature level for D3D11/D3D12 backends and to enable bindless mode (API version 240032)
Diffstat (limited to 'Graphics')
17 files changed, 465 insertions, 238 deletions
diff --git a/Graphics/GraphicsEngine/interface/APIInfo.h b/Graphics/GraphicsEngine/interface/APIInfo.h index aae4bdaa..2d7d66f5 100644 --- a/Graphics/GraphicsEngine/interface/APIInfo.h +++ b/Graphics/GraphicsEngine/interface/APIInfo.h @@ -26,7 +26,7 @@ /// \file /// Diligent API information -#define DILIGENT_API_VERSION 240031 +#define DILIGENT_API_VERSION 240032 #include "../../../Primitives/interface/BasicTypes.h" diff --git a/Graphics/GraphicsEngine/interface/DeviceCaps.h b/Graphics/GraphicsEngine/interface/DeviceCaps.h index 4e20c917..26914169 100644 --- a/Graphics/GraphicsEngine/interface/DeviceCaps.h +++ b/Graphics/GraphicsEngine/interface/DeviceCaps.h @@ -83,12 +83,14 @@ namespace Diligent /// Device type. See Diligent::DeviceType. DeviceType DevType = DeviceType::Undefined; - /// Major API revision. For instance, for D3D11.2 this value would be 11, - /// and for OpenGL4.3 this value would be 4. + /// Major revision of the graphics API supported by the graphics adapter. + /// Note that this value indicates the maximum supported feature level, so, + /// for example, if the device type is D3D11, this value will be 10 when + /// the maximum supported Direct3D feature level of the graphics adapter is 10.0. Int32 MajorVersion = 0; - /// Major API revision. For instance, for D3D11.2 this value would be 2, - /// and for OpenGL4.3 this value would be 3. + /// Minor revision of the graphics API supported by the graphics adapter. + /// Similar to MajorVersion, this value indicates the maximum supported feature level. Int32 MinorVersion = 0; /// Indicates if device supports separable programs @@ -112,6 +114,9 @@ namespace Diligent /// Indicates if device supports tessellation Bool bTessellationSupported = True; + /// Indicates if device supports bindless resources + Bool bBindlessSupported = False; + /// Texture sampling capabilities. See Diligent::SamplerCaps. SamplerCaps SamCaps; diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 61b79064..d7af003b 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -1321,14 +1321,40 @@ namespace Diligent VerifyCommittedResourceRelevance = 0x02 }; + + /// Direct3D11/12 feature level + enum DIRECT3D_FEATURE_LEVEL : Uint8 + { + /// Feature level 10.0 + DIRECT3D_FEATURE_LEVEL_10_0, + + /// Feature level 10.1 + DIRECT3D_FEATURE_LEVEL_10_1, + + /// Feature level 11.0 + DIRECT3D_FEATURE_LEVEL_11_0, + + /// Feature level 11.1 + DIRECT3D_FEATURE_LEVEL_11_1, + + /// Feature level 12.0 + DIRECT3D_FEATURE_LEVEL_12_0, + + /// Feature level 12.1 + DIRECT3D_FEATURE_LEVEL_12_1 + }; + /// Attributes specific to D3D11 engine struct EngineD3D11CreateInfo : public EngineCreateInfo { static constexpr Uint32 DefaultAdapterId = 0xFFFFFFFF; - /// Id of the hardware adapter the engine should be initialized on + /// Id of the hardware adapter the engine should be initialized on. Uint32 AdapterId = DefaultAdapterId; + /// Minimum required Direct3D feature level. + DIRECT3D_FEATURE_LEVEL MinimumFeatureLevel = DIRECT3D_FEATURE_LEVEL_11_0; + /// Debug flags. See Diligent::EngineD3D11DebugFlags for a list of allowed values. /// /// \sa CreateDeviceAndContextsD3D11Type, CreateSwapChainD3D11Type, LoadGraphicsEngineD3D11 @@ -1348,9 +1374,12 @@ namespace Diligent { static constexpr Uint32 DefaultAdapterId = 0xFFFFFFFF; - /// Id of the hardware adapter the engine should be initialized on + /// Id of the hardware adapter the engine should be initialized on. Uint32 AdapterId = DefaultAdapterId; + /// Minimum required Direct3D feature level. + DIRECT3D_FEATURE_LEVEL MinimumFeatureLevel = DIRECT3D_FEATURE_LEVEL_11_0; + /// Enable Direct3D12 debug layer. bool EnableDebugLayer = false; diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h index c88e88fe..d6eca935 100644 --- a/Graphics/GraphicsEngine/interface/Shader.h +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -50,15 +50,6 @@ enum SHADER_TYPE : Uint32 }; DEFINE_FLAG_ENUM_OPERATORS(SHADER_TYPE); -enum SHADER_PROFILE : Uint8 -{ - SHADER_PROFILE_DEFAULT = 0, - SHADER_PROFILE_DX_4_0, - SHADER_PROFILE_DX_5_0, - SHADER_PROFILE_DX_5_1, - SHADER_PROFILE_GL_4_2 -}; - /// Describes shader source code language enum SHADER_SOURCE_LANGUAGE : Uint32 { @@ -77,8 +68,6 @@ struct ShaderDesc : DeviceObjectAttribs { /// Shader type. See Diligent::SHADER_TYPE. SHADER_TYPE ShaderType = SHADER_TYPE_VERTEX; - - SHADER_PROFILE TargetProfile = SHADER_PROFILE_DEFAULT; }; diff --git a/Graphics/GraphicsEngineD3D11/interface/EngineFactoryD3D11.h b/Graphics/GraphicsEngineD3D11/interface/EngineFactoryD3D11.h index 656add65..fb658ebe 100644 --- a/Graphics/GraphicsEngineD3D11/interface/EngineFactoryD3D11.h +++ b/Graphics/GraphicsEngineD3D11/interface/EngineFactoryD3D11.h @@ -44,13 +44,38 @@ namespace Diligent static const INTERFACE_ID IID_EngineFactoryD3D11 = { 0x62663a30, 0xaaf0, 0x4a9a, { 0x97, 0x29, 0x9e, 0xac, 0x6b, 0xf7, 0x89, 0xf2 } }; +/// Engine factory for Direct3D11 rendering backend. class IEngineFactoryD3D11 : public IEngineFactory { public: + /// Creates a render device and device contexts for Direct3D11-based engine implementation. + + /// \param [in] EngineCI - Engine creation info. + /// \param [out] ppDevice - Address of the memory location where pointer to + /// the created device will be written. + /// \param [out] ppContexts - Address of the memory location where pointers to + /// the contexts will be written. Immediate context goes at + /// position 0. If EngineCI.NumDeferredContexts > 0, + /// pointers to deferred contexts are written afterwards. virtual void CreateDeviceAndContextsD3D11(const EngineD3D11CreateInfo& EngineCI, IRenderDevice** ppDevice, IDeviceContext** ppContexts) = 0; + + /// Creates a swap chain for Direct3D11-based engine implementation. + + /// \param [in] pDevice - Pointer to the render device. + /// \param [in] pImmediateContext - Pointer to the immediate device context. + /// \param [in] SCDesc - Swap chain description. + /// \param [in] FSDesc - Fullscreen mode description. + /// \param [in] pNativeWndHandle - Platform-specific native handle of the window + /// the swap chain will be associated with: + /// * On Win32 platform, this should be the window handle (HWND) + /// * On Universal Windows Platform, this should be the reference + /// to the core window (Windows::UI::Core::CoreWindow) + /// + /// \param [out] ppSwapChain - Address of the memory location where pointer to the new + /// swap chain will be written. virtual void CreateSwapChainD3D11( IRenderDevice* pDevice, IDeviceContext* pImmediateContext, const SwapChainDesc& SCDesc, @@ -58,20 +83,61 @@ public: void* pNativeWndHandle, ISwapChain** ppSwapChain) = 0; + + /// Attaches to existing Direct3D11 render device and immediate context. + + /// \param [in] pd3d11NativeDevice - pointer to the native Direct3D11 device. + /// \param [in] pd3d11ImmediateContext - pointer to the native Direct3D11 immediate context. + /// \param [in] EngineCI - Engine creation info. + /// \param [out] ppDevice - Address of the memory location where pointer to + /// the created device will be written. + /// \param [out] ppContexts - Address of the memory location where pointers to + /// the contexts will be written. Immediate context goes at + /// position 0. If EngineCI.NumDeferredContexts > 0, + /// pointers to the deferred contexts are written afterwards. virtual void AttachToD3D11Device(void* pd3d11NativeDevice, void* pd3d11ImmediateContext, const EngineD3D11CreateInfo& EngineCI, IRenderDevice** ppDevice, IDeviceContext** ppContexts) = 0; - virtual void EnumerateHardwareAdapters(Uint32& NumAdapters, - HardwareAdapterAttribs* Adapters) = 0; - virtual void EnumerateDisplayModes(Uint32 AdapterId, - Uint32 OutputId, - TEXTURE_FORMAT Format, - Uint32& NumDisplayModes, - DisplayModeAttribs* DisplayModes) = 0; + /// Enumerates hardware adapters available on this machine. + + /// \param [in] MinFeatureLevel - Minimum required feature level. + /// \param [in,out] NumAdapters - Number of adapters. If Adapters is null, this value + /// will be overwritten with the number of adapters available + /// on this system. If Adapters is not null, this value should + /// contain the maximum number of elements reserved in the array + /// pointed to by Adapters. In the latter case, this value + /// is overwritten with the actual number of elements written to + /// Adapters. + /// \param [out] Adapters - Pointer to the array conataining adapter information. If + /// null is provided, the number of available adapters is + /// written to NumAdapters. + virtual void EnumerateHardwareAdapters(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, + Uint32& NumAdapters, + HardwareAdapterAttribs* Adapters) = 0; + + + /// Enumerates available display modes for the specified output of the specified adapter. + + /// \param [in] MinFeatureLevel - Minimum feature level of the adapter that was given to EnumerateHardwareAdapters(). + /// \param [in] AdapterId - Id of the adapter enumerated by EnumerateHardwareAdapters(). + /// \param [in] OutputId - Adapter output id. + /// \param [in] Format - Display mode format. + /// \param [in, out] NumDisplayModes - Number of display modes. If DisplayModes is null, this + /// value is overwritten with the number of display modes + /// available for this output. If DisplayModes is not null, + /// this value should contain the maximum number of elements + /// to be written to DisplayModes array. It is overwritten with + /// the actual number of display modes written. + virtual void EnumerateDisplayModes(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, + Uint32 AdapterId, + Uint32 OutputId, + TEXTURE_FORMAT Format, + Uint32& NumDisplayModes, + DisplayModeAttribs* DisplayModes) = 0; }; #if ENGINE_DLL diff --git a/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp index d763cb20..cab8ae25 100644 --- a/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp @@ -54,9 +54,9 @@ public: TBase(IID_EngineFactoryD3D11) {} - void CreateDeviceAndContextsD3D11(const EngineD3D11CreateInfo& EngineCI, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts)override final; + void CreateDeviceAndContextsD3D11(const EngineD3D11CreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts)override final; void CreateSwapChainD3D11(IRenderDevice* pDevice, IDeviceContext* pImmediateContext, @@ -94,18 +94,10 @@ inline bool SdkLayersAvailable() } #endif -/// Creates render device and device contexts for Direct3D11-based engine implementation - -/// \param [in] EngineCI - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to -/// the created device will be written -/// \param [out] ppContexts - Address of the memory location where pointers to -/// the contexts will be written. Immediate context goes at -/// position 0. If EngineCI.NumDeferredContexts > 0, -/// pointers to the deferred contexts are written afterwards. -void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11(const EngineD3D11CreateInfo& EngineCI, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts) + +void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11(const EngineD3D11CreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts) { if (EngineCI.DebugMessageCallback != nullptr) SetDebugMessageCallback(EngineCI.DebugMessageCallback); @@ -114,6 +106,9 @@ void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11(const EngineD3D11Creat if( !ppDevice || !ppContexts ) return; + if (EngineCI.MinimumFeatureLevel >= DIRECT3D_FEATURE_LEVEL_12_0) + LOG_ERROR_AND_THROW("DIRECT3D_FEATURE_LEVEL_12_0 and above is not supported by Direct3D11 backend"); + *ppDevice = nullptr; memset(ppContexts, 0, sizeof(*ppContexts) * (1 + EngineCI.NumDeferredContexts)); @@ -130,89 +125,77 @@ void EngineFactoryD3D11Impl::CreateDeviceAndContextsD3D11(const EngineD3D11Creat } #endif - // This array defines the set of DirectX hardware feature levels this app will support. - // Note the ordering should be preserved. - // Don't forget to declare your application's minimum required feature level in its - // description. All applications are assumed to support 9.1 unless otherwise stated. - D3D_FEATURE_LEVEL featureLevels[] = - { -#if PLATFORM_UNIVERSAL_WINDOWS - D3D_FEATURE_LEVEL_11_1, -#endif - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1 - }; - - // Create the Direct3D 11 API device object and a corresponding context. - CComPtr<ID3D11Device> pd3d11Device; - CComPtr<ID3D11DeviceContext> pd3d11Context; - - CComPtr<IDXGIAdapter1> hardwareAdapter; + CComPtr<IDXGIAdapter1> SpecificAdapter; if (EngineCI.AdapterId != EngineD3D11CreateInfo::DefaultAdapterId) { - auto Adapters = FindCompatibleAdapters(); + auto Adapters = FindCompatibleAdapters(EngineCI.MinimumFeatureLevel); if (EngineCI.AdapterId < Adapters.size()) - hardwareAdapter = Adapters[EngineCI.AdapterId]; + SpecificAdapter = Adapters[EngineCI.AdapterId]; else { LOG_ERROR_AND_THROW(EngineCI.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( - hardwareAdapter, // Specify nullptr to use the default adapter. - hardwareAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, // If no adapter specified, request 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. - ARRAYSIZE(featureLevels), // Size of the list above. - D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. - &pd3d11Device, // Returns the Direct3D device created. - &d3dFeatureLevel, // Returns feature level of device created. - &pd3d11Context // Returns the device immediate context. - ); + // Create the Direct3D 11 API device object and a corresponding context. + CComPtr<ID3D11Device> pd3d11Device; + CComPtr<ID3D11DeviceContext> pd3d11Context; - if (FAILED(hr)) - { - // If the initialization fails, fall back to the WARP device. - // For more information on WARP, see: - // http://go.microsoft.com/fwlink/?LinkId=286690 - hr = D3D11CreateDevice( - nullptr, - D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device. - 0, - creationFlags, - featureLevels, - ARRAYSIZE(featureLevels), - D3D11_SDK_VERSION, - &pd3d11Device, - &d3dFeatureLevel, - &pd3d11Context - ); - LOG_ERROR("Failed to create D3D11 native device and immediate context"); - return; - } + for (int adapterType = 0; adapterType < 2 && !pd3d11Device; ++adapterType) + { + IDXGIAdapter* adapter = nullptr; + D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_UNKNOWN; + switch(adapterType) + { + case 0: + adapter = SpecificAdapter; + driverType = SpecificAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE; + break; + + case 1: + driverType = D3D_DRIVER_TYPE_WARP; + break; + + default: + UNEXPECTED("Unexpected adapter type"); + } + + // This page https://docs.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-d3d11createdevice says the following: + // If you provide a D3D_FEATURE_LEVEL array that contains D3D_FEATURE_LEVEL_11_1 on a computer that doesn't have the Direct3D 11.1 + // runtime installed, this function immediately fails with E_INVALIDARG. + // To avoid failure in this case we will try one feature level at a time + constexpr auto MaxFeatureLevel = DIRECT3D_FEATURE_LEVEL_11_1; + for (auto FeatureLevel = MaxFeatureLevel; FeatureLevel >= EngineCI.MinimumFeatureLevel; FeatureLevel = static_cast<DIRECT3D_FEATURE_LEVEL>(Uint8{FeatureLevel}-1)) + { + auto d3dFeatureLevel = GetD3DFeatureLevel(FeatureLevel); + auto hr = D3D11CreateDevice( + adapter, // Specify nullptr to use the default adapter. + driverType, // If no adapter specified, request hardware graphics driver. + 0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE. + creationFlags, // Set debug and Direct2D compatibility flags. + &d3dFeatureLevel, // List of feature levels this app can support. + 1, // Size of the list above. + D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. + &pd3d11Device, // Returns the Direct3D device created. + nullptr, // Returns feature level of device created. + &pd3d11Context // Returns the device immediate context. + ); + + if (SUCCEEDED(hr)) + { + VERIFY_EXPR(pd3d11Device && pd3d11Context); + break; + } + } + } + + if (!pd3d11Device) + LOG_ERROR_AND_THROW("Failed to create d3d11 device and immediate context"); AttachToD3D11Device(pd3d11Device, pd3d11Context, EngineCI, ppDevice, ppContexts); } -/// Attaches to existing D3D11 render device and immediate context - -/// \param [in] pd3d11NativeDevice - pointer to native D3D11 device -/// \param [in] pd3d11ImmediateContext - pointer to native D3D11 immediate context -/// \param [in] EngineCI - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to -/// the created device will be written -/// \param [out] ppContexts - Address of the memory location where pointers to -/// the contexts will be written. Immediate context goes at -/// position 0. If EngineCI.NumDeferredContexts > 0, -/// pointers to the deferred contexts are written afterwards. void EngineFactoryD3D11Impl::AttachToD3D11Device(void* pd3d11NativeDevice, void* pd3d11ImmediateContext, const EngineD3D11CreateInfo& EngineCI, @@ -279,20 +262,6 @@ void EngineFactoryD3D11Impl::AttachToD3D11Device(void* pd } -/// Creates a swap chain for Direct3D11-based engine implementation - -/// \param [in] pDevice - Pointer to the render device -/// \param [in] pImmediateContext - Pointer to the immediate device context -/// \param [in] SCDesc - Swap chain description -/// \param [in] FSDesc - Fullscreen mode description -/// \param [in] pNativeWndHandle - Platform-specific native handle of the window -/// the swap chain will be associated with: -/// * On Win32 platform, this should be window handle (HWND) -/// * On Universal Windows Platform, this should be reference to the -/// core window (Windows::UI::Core::CoreWindow) -/// -/// \param [out] ppSwapChain - Address of the memory location where pointer to the new -/// swap chain will be written void EngineFactoryD3D11Impl::CreateSwapChainD3D11(IRenderDevice* pDevice, IDeviceContext* pImmediateContext, const SwapChainDesc& SCDesc, diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp index f04162c5..3a845241 100644 --- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp @@ -69,8 +69,24 @@ RenderDeviceD3D11Impl :: RenderDeviceD3D11Impl(IReferenceCounters* pRef m_pd3d11Device {pd3d11Device } { m_DeviceCaps.DevType = DeviceType::D3D11; - m_DeviceCaps.MajorVersion = 11; - m_DeviceCaps.MinorVersion = 0; + auto FeatureLevel = m_pd3d11Device->GetFeatureLevel(); + switch (FeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_11_1: + m_DeviceCaps.MajorVersion = 11; + m_DeviceCaps.MinorVersion = FeatureLevel == D3D_FEATURE_LEVEL_11_1 ? 1 : 0; + break; + + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_10_1: + m_DeviceCaps.MajorVersion = 10; + m_DeviceCaps.MinorVersion = FeatureLevel == D3D_FEATURE_LEVEL_10_1 ? 1 : 0; + break; + + default: + UNEXPECTED("Unexpected D3D feature level"); + } m_DeviceCaps.bSeparableProgramSupported = True; m_DeviceCaps.bMultithreadedResourceCreationSupported = True; } diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp index 9454cf21..46adc289 100644 --- a/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp @@ -30,6 +30,32 @@ namespace Diligent { +static const char* GetD3D11ShaderModel(ID3D11Device* pd3d11Device) +{ + auto d3dDeviceFeatureLevel = pd3d11Device->GetFeatureLevel(); + switch(d3dDeviceFeatureLevel) + { + // ID3D11Device::Create*Shader methods support DXBC only up to 5.0 version +#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >=_WIN32_WINNT_WIN10) + case D3D_FEATURE_LEVEL_12_1: + case D3D_FEATURE_LEVEL_12_0: +#endif + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return "5_0"; + + case D3D_FEATURE_LEVEL_10_1: + return "4_1"; + + case D3D_FEATURE_LEVEL_10_0: + return "4_0"; + + default: + UNEXPECTED("Unexpected D3D feature level ", static_cast<Uint32>(d3dDeviceFeatureLevel)); + return "4_0"; + } +} + ShaderD3D11Impl::ShaderD3D11Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D11Impl* pRenderDeviceD3D11, const ShaderCreateInfo& ShaderCI) : @@ -39,7 +65,7 @@ ShaderD3D11Impl::ShaderD3D11Impl(IReferenceCounters* pRefCounters, pRenderDeviceD3D11, ShaderCI.Desc }, - ShaderD3DBase{ShaderCI} + ShaderD3DBase{ShaderCI, GetD3D11ShaderModel(pRenderDeviceD3D11->GetD3D11Device())} { auto *pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device(); switch (ShaderCI.Desc.ShaderType) diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h index 0756f454..b10ba472 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h @@ -104,6 +104,8 @@ public: const GenerateMipsHelper& GetMipsGenerator()const {return m_MipsGenerator;} + D3D_FEATURE_LEVEL GetD3DFeatureLevel()const; + private: virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat )override final; void FreeCommandContext(PooledCommandContext&& Ctx); diff --git a/Graphics/GraphicsEngineD3D12/interface/EngineFactoryD3D12.h b/Graphics/GraphicsEngineD3D12/interface/EngineFactoryD3D12.h index 8b1022d1..5e9f9cba 100644 --- a/Graphics/GraphicsEngineD3D12/interface/EngineFactoryD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/EngineFactoryD3D12.h @@ -44,13 +44,36 @@ namespace Diligent static const INTERFACE_ID IID_EngineFactoryD3D12 = { 0x72bd38b0, 0x684a, 0x4889, { 0x9c, 0x68, 0xa, 0x80, 0xec, 0x80, 0x2d, 0xde } }; +/// Engine factory for Direct3D12 rendering backend class IEngineFactoryD3D12 : public IEngineFactory { public: + /// Creates a render device and device contexts for Direct3D12-based engine implementation. + + /// \param [in] EngineCI - Engine creation info. + /// \param [out] ppDevice - Address of the memory location where pointer to + /// the created device will be written. + /// \param [out] ppContexts - Address of the memory location where pointers to + /// the contexts will be written. Immediate context goes at + /// position 0. If EngineCI.NumDeferredContexts > 0, + /// pointers to the deferred contexts are written afterwards. virtual void CreateDeviceAndContextsD3D12(const EngineD3D12CreateInfo& EngineCI, IRenderDevice** ppDevice, IDeviceContext** ppContexts) = 0; + + /// Attaches to existing Direct3D12 device. + + /// \param [in] pd3d12NativeDevice - Pointer to the native Direct3D12 device. + /// \param [in] CommandQueueCount - Number of command queues. + /// \param [in] ppCommandQueues - Pointer to the array of command queues. + /// \param [in] EngineCI - Engine creation info. + /// \param [out] ppDevice - Address of the memory location where pointer to + /// the created device will be written + /// \param [out] ppContexts - Address of the memory location where pointers to + /// the contexts will be written. Immediate context goes at + /// position 0. If EngineCI.NumDeferredContexts > 0, + /// pointers to the deferred contexts are written afterwards. virtual void AttachToD3D12Device(void* pd3d12NativeDevice, size_t CommandQueueCount, class ICommandQueueD3D12** ppCommandQueues, @@ -58,6 +81,21 @@ public: IRenderDevice** ppDevice, IDeviceContext** ppContexts) = 0; + + /// Creates a swap chain for Direct3D12-based engine implementation. + + /// \param [in] pDevice - Pointer to the render device. + /// \param [in] pImmediateContext - Pointer to the immediate device context. + /// \param [in] SCDesc - Swap chain description. + /// \param [in] FSDesc - Fullscreen mode description. + /// \param [in] pNativeWndHandle - Platform-specific native handle of the window + /// the swap chain will be associated with: + /// * On Win32 platform, this should be the window handle (HWND) + /// * On Universal Windows Platform, this should be the reference + /// to the core window (Windows::UI::Core::CoreWindow) + /// + /// \param [out] ppSwapChain - Address of the memory location where pointer to the new + /// swap chain will be written virtual void CreateSwapChainD3D12( IRenderDevice* pDevice, IDeviceContext* pImmediateContext, const SwapChainDesc& SwapChainDesc, @@ -65,15 +103,43 @@ public: void* pNativeWndHandle, ISwapChain** ppSwapChain ) = 0; - virtual void EnumerateHardwareAdapters(Uint32& NumAdapters, - HardwareAdapterAttribs* Adapters) = 0; - - virtual void EnumerateDisplayModes(Uint32 AdapterId, - Uint32 OutputId, - TEXTURE_FORMAT Format, - Uint32& NumDisplayModes, - DisplayModeAttribs* DisplayModes) = 0; + /// Enumerates hardware adapters available on this machine. + + /// \param [in] MinFeatureLevel - Minimum required feature level. + /// \param [in,out] NumAdapters - Number of adapters. If Adapters is null, this value + /// will be overwritten with the number of adapters available + /// on this system. If Adapters is not null, this value should + /// contain maximum number of elements reserved in the array + /// pointed to by Adapters. In the latter case, this value + /// is overwritten with the actual number of elements written to + /// Adapters. + /// \param [out] Adapters - Pointer to the array conataining adapter information. If + /// null is provided, the number of available adapters is written to + /// NumAdapters + virtual void EnumerateHardwareAdapters(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, + Uint32& NumAdapters, + HardwareAdapterAttribs* Adapters) = 0; + + + /// Enumerates available display modes for the specified output of the specified adapter. + + /// \param [in] MinFeatureLevel - Minimum feature level of the adapter that was given to EnumerateHardwareAdapters(). + /// \param [in] AdapterId - Id of the adapter enumerated by EnumerateHardwareAdapters(). + /// \param [in] OutputId - Adapter output id. + /// \param [in] Format - Display mode format. + /// \param [in, out] NumDisplayModes - Number of display modes. If DisplayModes is null, this + /// value is overwritten with the number of display modes + /// available for this output. If DisplayModes is not null, + /// this value should contain the maximum number of elements + /// to be written to DisplayModes array. It is overwritten with + /// the actual number of display modes written. + virtual void EnumerateDisplayModes(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, + Uint32 AdapterId, + Uint32 OutputId, + TEXTURE_FORMAT Format, + Uint32& NumDisplayModes, + DisplayModeAttribs* DisplayModes) = 0; }; diff --git a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp index 6ccfc25e..0c91b8c9 100644 --- a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp @@ -57,9 +57,9 @@ public: TBase{IID_EngineFactoryD3D12} {} - void CreateDeviceAndContextsD3D12(const EngineD3D12CreateInfo& EngineCI, - IRenderDevice** ppDevice, - IDeviceContext** ppContexts)override final; + void CreateDeviceAndContextsD3D12(const EngineD3D12CreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts)override final; void AttachToD3D12Device(void* pd3d12NativeDevice, size_t CommandQueueCount, @@ -76,7 +76,7 @@ public: ISwapChain** ppSwapChain )override final; }; -static void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter) +static void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter, D3D_FEATURE_LEVEL FeatureLevel) { CComPtr<IDXGIAdapter1> adapter; *ppAdapter = nullptr; @@ -94,7 +94,7 @@ static void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapte // Check to see if the adapter supports Direct3D 12, but don't create the // actual device yet. - if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) + if (SUCCEEDED(D3D12CreateDevice(adapter, FeatureLevel, _uuidof(ID3D12Device), nullptr))) { break; } @@ -103,17 +103,8 @@ static void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapte *ppAdapter = adapter.Detach(); } -/// Creates render device and device contexts for Direct3D12-based engine implementation - -/// \param [in] EngineCI - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to -/// the created device will be written -/// \param [out] ppContexts - Address of the memory location where pointers to -/// the contexts will be written. Immediate context goes at -/// position 0. If EngineCI.NumDeferredContexts > 0, -/// pointers to the deferred contexts are written afterwards. -void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12CreateInfo& EngineCI, - IRenderDevice** ppDevice, +void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12CreateInfo& EngineCI, + IRenderDevice** ppDevice, IDeviceContext** ppContexts) { if (EngineCI.DebugMessageCallback != nullptr) @@ -123,7 +114,7 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12Creat if( !ppDevice || !ppContexts ) return; - for(Uint32 Type=D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; Type < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++Type) + for (Uint32 Type=D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; Type < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++Type) { auto CPUHeapAllocSize = EngineCI.CPUDescriptorHeapAllocationSize[Type]; Uint32 MaxSize = 1 << 20; @@ -165,13 +156,13 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12Creat CComPtr<IDXGIAdapter1> hardwareAdapter; if(EngineCI.AdapterId == EngineD3D12CreateInfo::DefaultAdapterId) { - GetHardwareAdapter(factory, &hardwareAdapter); + GetHardwareAdapter(factory, &hardwareAdapter, GetD3DFeatureLevel(EngineCI.MinimumFeatureLevel)); if(hardwareAdapter == nullptr) LOG_ERROR_AND_THROW("No suitable hardware adapter found"); } else { - auto Adapters = FindCompatibleAdapters(); + auto Adapters = FindCompatibleAdapters(EngineCI.MinimumFeatureLevel); if(EngineCI.AdapterId < Adapters.size()) hardwareAdapter = Adapters[EngineCI.AdapterId]; else @@ -186,7 +177,17 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12Creat 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<void**>(static_cast<ID3D12Device**>(&d3d12Device)) ); + constexpr auto MaxFeatureLevel = DIRECT3D_FEATURE_LEVEL_12_1; + for (auto FeatureLevel = MaxFeatureLevel; FeatureLevel >= EngineCI.MinimumFeatureLevel; FeatureLevel = static_cast<DIRECT3D_FEATURE_LEVEL>(Uint8{FeatureLevel}-1)) + { + auto d3dFeatureLevel = GetD3DFeatureLevel(FeatureLevel); + hr = D3D12CreateDevice(hardwareAdapter, d3dFeatureLevel, __uuidof(d3d12Device), reinterpret_cast<void**>(static_cast<ID3D12Device**>(&d3d12Device)) ); + if (SUCCEEDED(hr)) + { + VERIFY_EXPR(d3d12Device); + break; + } + } if( FAILED(hr)) { LOG_WARNING_MESSAGE("Failed to create hardware device. Attempting to create WARP device"); @@ -195,7 +196,16 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12Creat hr = factory->EnumWarpAdapter( __uuidof(warpAdapter), reinterpret_cast<void**>(static_cast<IDXGIAdapter**>(&warpAdapter)) ); CHECK_D3D_RESULT_THROW(hr, "Failed to enum warp adapter"); - hr = D3D12CreateDevice( warpAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(d3d12Device), reinterpret_cast<void**>(static_cast<ID3D12Device**>(&d3d12Device)) ); + for (auto FeatureLevel = MaxFeatureLevel; FeatureLevel >= EngineCI.MinimumFeatureLevel; FeatureLevel = static_cast<DIRECT3D_FEATURE_LEVEL>(Uint8{FeatureLevel}-1)) + { + auto d3dFeatureLevel = GetD3DFeatureLevel(FeatureLevel); + hr = D3D12CreateDevice( warpAdapter, d3dFeatureLevel, __uuidof(d3d12Device), reinterpret_cast<void**>(static_cast<ID3D12Device**>(&d3d12Device)) ); + if (SUCCEEDED(hr)) + { + VERIFY_EXPR(d3d12Device); + break; + } + } CHECK_D3D_RESULT_THROW(hr, "Failed to crate warp device"); } @@ -277,18 +287,7 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12Creat } -/// Attaches to existing D3D12 device -/// \param [in] pd3d12NativeDevice - pointer to native D3D12 device -/// \param [in] CommandQueueCount - Number of command queues -/// \param [in] ppCommandQueues - pointer to the array of command queues -/// \param [in] EngineCI - Engine creation attributes. -/// \param [out] ppDevice - Address of the memory location where pointer to -/// the created device will be written -/// \param [out] ppContexts - Address of the memory location where pointers to -/// the contexts will be written. Immediate context goes at -/// position 0. If EngineCI.NumDeferredContexts > 0, -/// pointers to the deferred contexts are written afterwards. void EngineFactoryD3D12Impl::AttachToD3D12Device(void* pd3d12NativeDevice, size_t CommandQueueCount, ICommandQueueD3D12** ppCommandQueues, @@ -349,20 +348,7 @@ void EngineFactoryD3D12Impl::AttachToD3D12Device(void* pd } } -/// Creates a swap chain for Direct3D12-based engine implementation - -/// \param [in] pDevice - Pointer to the render device -/// \param [in] pImmediateContext - Pointer to the immediate device context -/// \param [in] SCDesc - Swap chain description -/// \param [in] FSDesc - Fullscreen mode description -/// \param [in] pNativeWndHandle - Platform-specific native handle of the window -/// the swap chain will be associated with: -/// * On Win32 platform, this should be window handle (HWND) -/// * On Universal Windows Platform, this should be reference to the -/// core window (Windows::UI::Core::CoreWindow) -/// -/// \param [out] ppSwapChain - Address of the memory location where pointer to the new -/// swap chain will be written + void EngineFactoryD3D12Impl::CreateSwapChainD3D12(IRenderDevice* pDevice, IDeviceContext* pImmediateContext, const SwapChainDesc& SCDesc, diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 3100da7b..27f37dc0 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -37,6 +37,24 @@ namespace Diligent { +D3D_FEATURE_LEVEL RenderDeviceD3D12Impl :: GetD3DFeatureLevel() const +{ + D3D_FEATURE_LEVEL FeatureLevels[] = + { + D3D_FEATURE_LEVEL_12_1, + D3D_FEATURE_LEVEL_12_0, + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0 + }; + D3D12_FEATURE_DATA_FEATURE_LEVELS FeatureLevelsData = {}; + FeatureLevelsData.pFeatureLevelsRequested = FeatureLevels; + FeatureLevelsData.NumFeatureLevels = _countof(FeatureLevels); + m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &FeatureLevelsData, sizeof(FeatureLevelsData)); + return FeatureLevelsData.MaxSupportedFeatureLevel; +} + RenderDeviceD3D12Impl :: RenderDeviceD3D12Impl(IReferenceCounters* pRefCounters, IMemoryAllocator& RawMemAllocator, IEngineFactory* pEngineFactory, @@ -85,8 +103,32 @@ RenderDeviceD3D12Impl :: RenderDeviceD3D12Impl(IReferenceCounters* pRe m_MipsGenerator {pd3d12Device} { m_DeviceCaps.DevType = DeviceType::D3D12; - m_DeviceCaps.MajorVersion = 12; - m_DeviceCaps.MinorVersion = 0; + auto FeatureLevel = GetD3DFeatureLevel(); + switch (FeatureLevel) + { + case D3D_FEATURE_LEVEL_12_0: + case D3D_FEATURE_LEVEL_12_1: + m_DeviceCaps.MajorVersion = 12; + m_DeviceCaps.MinorVersion = FeatureLevel == D3D_FEATURE_LEVEL_12_1 ? 1 : 0; + m_DeviceCaps.bBindlessSupported = true; + break; + + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_11_1: + m_DeviceCaps.MajorVersion = 11; + m_DeviceCaps.MinorVersion = FeatureLevel == D3D_FEATURE_LEVEL_11_1 ? 1 : 0; + m_DeviceCaps.bBindlessSupported = FeatureLevel == D3D_FEATURE_LEVEL_11_1; + break; + + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_10_1: + m_DeviceCaps.MajorVersion = 10; + m_DeviceCaps.MinorVersion = FeatureLevel == D3D_FEATURE_LEVEL_10_1 ? 1 : 0; + break; + + default: + UNEXPECTED("Unexpected D3D feature level"); + } m_DeviceCaps.bSeparableProgramSupported = True; m_DeviceCaps.bMultithreadedResourceCreationSupported = True; } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp index 509ef10b..c189bf3e 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp @@ -32,6 +32,31 @@ namespace Diligent { +static const char* GetD3D12ShaderModel(RenderDeviceD3D12Impl* pDevice) +{ + auto d3dDeviceFeatureLevel = pDevice->GetD3DFeatureLevel(); + switch(d3dDeviceFeatureLevel) + { + case D3D_FEATURE_LEVEL_12_1: + case D3D_FEATURE_LEVEL_12_0: + case D3D_FEATURE_LEVEL_11_1: + return "5_1"; + + case D3D_FEATURE_LEVEL_11_0: + return "5_0"; + + case D3D_FEATURE_LEVEL_10_1: + return "4_1"; + + case D3D_FEATURE_LEVEL_10_0: + return "4_0"; + + default: + UNEXPECTED("Unexpected D3D feature level ", static_cast<Uint32>(d3dDeviceFeatureLevel)); + return "4_0"; + } +} + ShaderD3D12Impl::ShaderD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pRenderDeviceD3D12, const ShaderCreateInfo& ShaderCI) : @@ -41,7 +66,7 @@ ShaderD3D12Impl::ShaderD3D12Impl(IReferenceCounters* pRefCounters, pRenderDeviceD3D12, ShaderCI.Desc }, - ShaderD3DBase{ShaderCI} + ShaderD3DBase{ShaderCI, GetD3D12ShaderModel(pRenderDeviceD3D12)} { // Load shader resources auto& Allocator = GetRawAllocator(); diff --git a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h index 8b9f50cb..fac7683c 100644 --- a/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h +++ b/Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h @@ -42,22 +42,12 @@ public: TEngineFactoryBase(FactoryIID) {} - /// Enumerates hardware adapters available on this machine - - /// \param [in,out] NumAdapters - Number of adapters. If Adapters is null, this value - /// will be overwritten with the number of adapters available - /// on this system. If Adapters is not null, this value should - /// contain maximum number of elements reserved in the array - /// pointed to by Adapters. In the latter case, this value - /// is overwritten with the actual number of elements written to - /// Adapters. - /// \param [out] Adapters - Pointer to the array conataining adapter information. If - /// null is provided, the number of available adapters is written to - /// NumAdapters - virtual void EnumerateHardwareAdapters(Uint32 &NumAdapters, - HardwareAdapterAttribs *Adapters)override final + + virtual void EnumerateHardwareAdapters(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, + Uint32& NumAdapters, + HardwareAdapterAttribs* Adapters)override final { - auto DXGIAdapters = FindCompatibleAdapters(); + auto DXGIAdapters = FindCompatibleAdapters(MinFeatureLevel); if (Adapters == nullptr) NumAdapters = static_cast<Uint32>(DXGIAdapters.size()); @@ -89,24 +79,15 @@ public: } } - /// Enumerates available display modes for the specified output of the specified adapter - - /// \param [in] AdapterId - Id of the adapter enumerated by EnumerateHardwareAdapters(). - /// \param [in] OutputId - Adapter output id - /// \param [in] Format - Display mode format - /// \param [in, out] NumDisplayModes - Number of display modes. If DisplayModes is null, this - /// value is overwritten with the number of display modes - /// available for this output. If DisplayModes is not null, - /// this value should contain the maximum number of elements - /// to be written to DisplayModes array. It is overwritten with - /// the actual number of display modes written. - virtual void EnumerateDisplayModes(Uint32 AdapterId, - Uint32 OutputId, - TEXTURE_FORMAT Format, - Uint32 &NumDisplayModes, - DisplayModeAttribs *DisplayModes)override final + + virtual void EnumerateDisplayModes(DIRECT3D_FEATURE_LEVEL MinFeatureLevel, + Uint32 AdapterId, + Uint32 OutputId, + TEXTURE_FORMAT Format, + Uint32& NumDisplayModes, + DisplayModeAttribs* DisplayModes)override final { - auto DXGIAdapters = FindCompatibleAdapters(); + auto DXGIAdapters = FindCompatibleAdapters(MinFeatureLevel); if(AdapterId >= DXGIAdapters.size()) { LOG_ERROR("Incorrect adapter id ", AdapterId); @@ -156,7 +137,7 @@ public: } - std::vector<CComPtr<IDXGIAdapter1>> FindCompatibleAdapters() + std::vector<CComPtr<IDXGIAdapter1>> FindCompatibleAdapters(DIRECT3D_FEATURE_LEVEL MinFeatureLevel) { std::vector<CComPtr<IDXGIAdapter1>> DXGIAdapters; @@ -167,6 +148,7 @@ public: return std::move(DXGIAdapters); } + auto d3dFeatureLevel = GetD3DFeatureLevel(MinFeatureLevel); CComPtr<IDXGIAdapter1> pDXIAdapter; UINT adapter = 0; for (; pFactory->EnumAdapters1(adapter, &pDXIAdapter) != DXGI_ERROR_NOT_FOUND; ++adapter, pDXIAdapter.Release()) @@ -179,8 +161,7 @@ public: continue; } - bool IsCompatibleAdapter = CheckAdapterCompatibility<DevType>(pDXIAdapter); - + bool IsCompatibleAdapter = CheckAdapterCompatibility<DevType>(pDXIAdapter, d3dFeatureLevel); if (IsCompatibleAdapter) { DXGIAdapters.emplace_back(std::move(pDXIAdapter)); @@ -190,21 +171,58 @@ public: return std::move(DXGIAdapters); } + +protected: + + static D3D_FEATURE_LEVEL GetD3DFeatureLevel(DIRECT3D_FEATURE_LEVEL FeatureLevel) + { + switch(FeatureLevel) + { + case DIRECT3D_FEATURE_LEVEL_10_0: return D3D_FEATURE_LEVEL_10_0; + case DIRECT3D_FEATURE_LEVEL_10_1: return D3D_FEATURE_LEVEL_10_1; + case DIRECT3D_FEATURE_LEVEL_11_0: return D3D_FEATURE_LEVEL_11_0; + case DIRECT3D_FEATURE_LEVEL_11_1: return D3D_FEATURE_LEVEL_11_1; +#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >=_WIN32_WINNT_WIN10) + case DIRECT3D_FEATURE_LEVEL_12_0: return D3D_FEATURE_LEVEL_12_0; + case DIRECT3D_FEATURE_LEVEL_12_1: return D3D_FEATURE_LEVEL_12_1; +#endif + + default: + UNEXPECTED("Unknown DIRECT3D_FEATURE_LEVEL ", static_cast<Uint32>(FeatureLevel)); + return D3D_FEATURE_LEVEL_11_0; + } + } + private: template<DeviceType DevType> - bool CheckAdapterCompatibility(IDXGIAdapter1 *pDXGIAdapter); + bool CheckAdapterCompatibility(IDXGIAdapter1* pDXGIAdapter, + D3D_FEATURE_LEVEL FeatureLevels); template<> - bool CheckAdapterCompatibility<DeviceType::D3D11>(IDXGIAdapter1 *pDXGIAdapter) + bool CheckAdapterCompatibility<DeviceType::D3D11>(IDXGIAdapter1* pDXGIAdapter, + D3D_FEATURE_LEVEL FeatureLevel) { - return true; + auto hr = D3D11CreateDevice( + nullptr, + D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device. + 0, + 0, // Flags. + &FeatureLevel, // Feature levels. + 1, // Number of feature levels + D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. + nullptr, // No need to keep the D3D device reference. + nullptr, // Feature level of the created adapter. + nullptr // No need to keep the D3D device context reference. + ); + return SUCCEEDED(hr); } template<> - bool CheckAdapterCompatibility<DeviceType::D3D12>(IDXGIAdapter1 *pDXGIAdapter) + bool CheckAdapterCompatibility<DeviceType::D3D12>(IDXGIAdapter1* pDXGIAdapter, + D3D_FEATURE_LEVEL FeatureLevel) { - auto hr = D3D12CreateDevice(pDXGIAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr); + auto hr = D3D12CreateDevice(pDXGIAdapter, FeatureLevel, _uuidof(ID3D12Device), nullptr); return SUCCEEDED(hr); } }; diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h index 3a80d5ac..c8c4de8f 100644 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h @@ -36,7 +36,7 @@ namespace Diligent class ShaderD3DBase { public: - ShaderD3DBase(const ShaderCreateInfo& ShaderCI); + ShaderD3DBase(const ShaderCreateInfo& ShaderCI, const char* ShaderModel); protected: CComPtr<ID3DBlob> m_pShaderByteCode; diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp index 7ac4fb9d..02281be7 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp @@ -121,19 +121,7 @@ static HRESULT CompileShader(const char* Source, return hr; } -const char* DXShaderProfileToString(SHADER_PROFILE DXProfile) -{ - switch(DXProfile) - { - case SHADER_PROFILE_DX_4_0: return "4_0"; - case SHADER_PROFILE_DX_5_0: return "5_0"; - case SHADER_PROFILE_DX_5_1: return "5_1"; - //default: UNEXPECTED("Unknown DirectX shader profile" ); return ""; - default: return "5_0"; - } -} - -ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI) +ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI, const char* ShaderModel) { if (ShaderCI.Source || ShaderCI.FilePath) { @@ -153,8 +141,7 @@ ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI) default: UNEXPECTED( "Unknown shader type" ); } strShaderProfile += "_"; - auto *pProfileSuffix = DXShaderProfileToString(ShaderCI.Desc.TargetProfile); - strShaderProfile += pProfileSuffix; + strShaderProfile += ShaderModel; String ShaderSource(g_HLSLDefinitions); if (ShaderCI.Source) diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 232a8167..221a1bea 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -149,6 +149,7 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters* m_DeviceCaps.bGeometryShadersSupported = EngineCI.EnabledFeatures.geometryShader; m_DeviceCaps.bTessellationSupported = EngineCI.EnabledFeatures.tessellationShader; + m_DeviceCaps.bBindlessSupported = True; } RenderDeviceVkImpl::~RenderDeviceVkImpl() |
