summaryrefslogtreecommitdiffstats
path: root/Graphics
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
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')
-rw-r--r--Graphics/GraphicsEngine/interface/APIInfo.h2
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceCaps.h13
-rw-r--r--Graphics/GraphicsEngine/interface/GraphicsTypes.h33
-rw-r--r--Graphics/GraphicsEngine/interface/Shader.h11
-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
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h2
-rw-r--r--Graphics/GraphicsEngineD3D12/interface/EngineFactoryD3D12.h82
-rw-r--r--Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp78
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp46
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp27
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/EngineFactoryD3DBase.h98
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.h2
-rw-r--r--Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp17
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp1
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()