summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-10-03 05:03:48 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-10-03 05:03:48 +0000
commitae735ab587d70acff30eb263b3690745dcd67d81 (patch)
tree057cb8a580f676c3ef4525e723c151c7db2c6837 /Graphics
parentAdded device features to indicate support of 16-bit types (diff)
downloadDiligentCore-ae735ab587d70acff30eb263b3690745dcd67d81.tar.gz
DiligentCore-ae735ab587d70acff30eb263b3690745dcd67d81.zip
Improved 16-bit feature detection in D3D11 and D3D12
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/interface/GraphicsTypes.h3
-rw-r--r--Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp16
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp46
3 files changed, 51 insertions, 14 deletions
diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
index 24440ca8..69769968 100644
--- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h
+++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
@@ -1585,6 +1585,9 @@ struct DeviceFeatures
/// Indicates if device supports native 16-bit float operations. Note that there are separate features
/// that indicate if device supports loading 16-bit floats from buffers and passing them between shader stages.
+ ///
+ /// \note 16-bit support is quite tricky, the following post should help understand it better:
+ /// https://therealmjp.github.io/posts/shader-fp16/
DEVICE_FEATURE_STATE ShaderFloat16 DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
/// Indicates if device supports reading and writing 16-bit floats and ints from buffers bound
diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
index f87f5068..ffd746fb 100644
--- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
@@ -148,8 +148,22 @@ RenderDeviceD3D11Impl::RenderDeviceD3D11Impl(IReferenceCounters* pRefCo
UNSUPPORTED_FEATURE(VertexPipelineUAVWritesAndAtomics, "Vertex pipeline UAV writes and atomics are");
UNSUPPORTED_FEATURE(MeshShaders, "Mesh shaders are");
+ {
+ bool ShaderFloat16Supported = false;
+
+ D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT d3d11MinPrecisionSupport = {};
+ if (SUCCEEDED(m_pd3d11Device->CheckFeatureSupport(D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT, &d3d11MinPrecisionSupport, sizeof(d3d11MinPrecisionSupport))))
+ {
+ ShaderFloat16Supported =
+ (d3d11MinPrecisionSupport.PixelShaderMinPrecision & D3D11_SHADER_MIN_PRECISION_16_BIT) != 0 &&
+ (d3d11MinPrecisionSupport.AllOtherShaderStagesMinPrecision & D3D11_SHADER_MIN_PRECISION_16_BIT) != 0;
+ }
+ if (EngineAttribs.Features.ShaderFloat16 == DEVICE_FEATURE_STATE_ENABLED && !ShaderFloat16Supported)
+ LOG_ERROR_AND_THROW("16-bit float shader operations are");
+ m_DeviceCaps.Features.ShaderFloat16 = ShaderFloat16Supported ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED;
+ }
+
// Explicit fp16 is only supported in DXC through Shader Model 6.2, so there's no support for FXC or D3D11.
- UNSUPPORTED_FEATURE(ShaderFloat16, "16-bit float shader operations are");
UNSUPPORTED_FEATURE(ResourceBuffer16BitAccess, "16-bit native access to resource buffers is");
UNSUPPORTED_FEATURE(UniformBuffer16BitAccess, "16-bit native access to uniform buffers is");
UNSUPPORTED_FEATURE(ShaderInputOutput16, "16-bit shader input/output is");
diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
index d5fc2bda..0cf5440a 100644
--- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
@@ -251,27 +251,47 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo
m_DeviceCaps.Features.MeshShaders = MeshShadersSupported ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED;
- D3D12_FEATURE_DATA_D3D12_OPTIONS4 d3d12Options4 = {};
- m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &d3d12Options4, sizeof(d3d12Options4));
- if (d3d12Options4.Native16BitShaderOpsSupported)
{
- m_DeviceCaps.Features.ShaderFloat16 = DEVICE_FEATURE_STATE_ENABLED;
- m_DeviceCaps.Features.ResourceBuffer16BitAccess = DEVICE_FEATURE_STATE_ENABLED;
- m_DeviceCaps.Features.UniformBuffer16BitAccess = DEVICE_FEATURE_STATE_ENABLED;
- m_DeviceCaps.Features.ShaderInputOutput16 = DEVICE_FEATURE_STATE_ENABLED;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS d3d12Features = {};
+ if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &d3d12Features, sizeof(d3d12Features))))
+ {
+ if (d3d12Features.MinPrecisionSupport & D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT)
+ {
+ m_DeviceCaps.Features.ShaderFloat16 = DEVICE_FEATURE_STATE_ENABLED;
+ }
+ }
}
- else
+
{
- if (EngineCI.Features.ShaderFloat16 == DEVICE_FEATURE_STATE_ENABLED ||
- EngineCI.Features.ResourceBuffer16BitAccess == DEVICE_FEATURE_STATE_ENABLED ||
- EngineCI.Features.UniformBuffer16BitAccess == DEVICE_FEATURE_STATE_ENABLED ||
- EngineCI.Features.ShaderInputOutput16 == DEVICE_FEATURE_STATE_ENABLED)
+ D3D12_FEATURE_DATA_D3D12_OPTIONS4 d3d12Features4 = {};
+ if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &d3d12Features4, sizeof(d3d12Features4))))
{
- LOG_ERROR_AND_THROW("This device/driver does not natively support 16-bit floats and ints.");
+ if (d3d12Features4.Native16BitShaderOpsSupported)
+ {
+ m_DeviceCaps.Features.ResourceBuffer16BitAccess = DEVICE_FEATURE_STATE_ENABLED;
+ m_DeviceCaps.Features.UniformBuffer16BitAccess = DEVICE_FEATURE_STATE_ENABLED;
+ m_DeviceCaps.Features.ShaderInputOutput16 = DEVICE_FEATURE_STATE_ENABLED;
+ }
}
}
+#define CHECK_REQUIRED_FEATURE(Feature, FeatureName) \
+ do \
+ { \
+ if (EngineCI.Features.Feature == DEVICE_FEATURE_STATE_ENABLED && \
+ m_DeviceCaps.Features.Feature != DEVICE_FEATURE_STATE_ENABLED) \
+ LOG_ERROR_AND_THROW(FeatureName, "not supported by this device"); \
+ } while (false)
+
+ // clang-format off
+ CHECK_REQUIRED_FEATURE(ShaderFloat16, "16-bit float shader operations are");
+ CHECK_REQUIRED_FEATURE(ResourceBuffer16BitAccess, "16-bit resoure buffer access is");
+ CHECK_REQUIRED_FEATURE(UniformBuffer16BitAccess, "16-bit uniform buffer access is");
+ CHECK_REQUIRED_FEATURE(ShaderInputOutput16, "16-bit shader inputs/outputs are");
+ // clang-format on
+#undef CHECK_REQUIRED_FEATURE
+
#if defined(_MSC_VER) && defined(_WIN64)
static_assert(sizeof(DeviceFeatures) == 27, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif