summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D11
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-10-17 04:06:08 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-10-17 04:06:08 +0000
commitbc4a29a1fac0276e499bb37bb3c449ebdcacbe92 (patch)
tree50316f6b243300fdf9ef25afe1aad5d619ccfa08 /Graphics/GraphicsEngineD3D11
parentAdded option to install PDB files on Windows (closed https://github.com/Dilig... (diff)
downloadDiligentCore-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/GraphicsEngineD3D11')
-rw-r--r--Graphics/GraphicsEngineD3D11/interface/EngineFactoryD3D11.h80
-rw-r--r--Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp163
-rw-r--r--Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp20
-rw-r--r--Graphics/GraphicsEngineD3D11/src/ShaderD3D11Impl.cpp28
4 files changed, 184 insertions, 107 deletions
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)