summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-09-13 03:17:35 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-09-13 03:17:35 +0000
commit83acbd6c353255f478164018a357637fb2f11cb5 (patch)
treec685b67b63185cd47d397a0d2dc423c9a8032421 /Graphics
parentFixed shader error log + fixed tests in Win8.1 (diff)
downloadDiligentCore-83acbd6c353255f478164018a357637fb2f11cb5.tar.gz
DiligentCore-83acbd6c353255f478164018a357637fb2f11cb5.zip
Added option to enable/disable device features during initialization (API 240069)
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GLSLTools/include/GLSLSourceBuilder.hpp2
-rw-r--r--Graphics/GraphicsEngine/CMakeLists.txt1
-rw-r--r--Graphics/GraphicsEngine/interface/APIInfo.h2
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceCaps.h264
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h2
-rw-r--r--Graphics/GraphicsEngine/interface/GraphicsTypes.h302
-rw-r--r--Graphics/GraphicsEngine/interface/RenderDevice.h1
-rw-r--r--Graphics/GraphicsEngine/src/APIInfo.cpp2
-rw-r--r--Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp19
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp198
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp40
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp3
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp163
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp84
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp59
19 files changed, 647 insertions, 503 deletions
diff --git a/Graphics/GLSLTools/include/GLSLSourceBuilder.hpp b/Graphics/GLSLTools/include/GLSLSourceBuilder.hpp
index 99710eaf..ffe36a4e 100644
--- a/Graphics/GLSLTools/include/GLSLSourceBuilder.hpp
+++ b/Graphics/GLSLTools/include/GLSLSourceBuilder.hpp
@@ -28,7 +28,7 @@
#pragma once
#include "BasicTypes.h"
-#include "DeviceCaps.h"
+#include "GraphicsTypes.h"
#include "Shader.h"
namespace Diligent
diff --git a/Graphics/GraphicsEngine/CMakeLists.txt b/Graphics/GraphicsEngine/CMakeLists.txt
index 1de30eab..b99138ca 100644
--- a/Graphics/GraphicsEngine/CMakeLists.txt
+++ b/Graphics/GraphicsEngine/CMakeLists.txt
@@ -38,7 +38,6 @@ set(INTERFACE
interface/CommandList.h
interface/Constants.h
interface/DepthStencilState.h
- interface/DeviceCaps.h
interface/DeviceContext.h
interface/DeviceObject.h
interface/EngineFactory.h
diff --git a/Graphics/GraphicsEngine/interface/APIInfo.h b/Graphics/GraphicsEngine/interface/APIInfo.h
index 713faca8..7d297e0c 100644
--- a/Graphics/GraphicsEngine/interface/APIInfo.h
+++ b/Graphics/GraphicsEngine/interface/APIInfo.h
@@ -30,7 +30,7 @@
/// \file
/// Diligent API information
-#define DILIGENT_API_VERSION 240068
+#define DILIGENT_API_VERSION 240069
#include "../../../Primitives/interface/BasicTypes.h"
diff --git a/Graphics/GraphicsEngine/interface/DeviceCaps.h b/Graphics/GraphicsEngine/interface/DeviceCaps.h
deleted file mode 100644
index b5bb866a..00000000
--- a/Graphics/GraphicsEngine/interface/DeviceCaps.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright 2019-2020 Diligent Graphics LLC
- * Copyright 2015-2019 Egor Yusov
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * In no event and under no legal theory, whether in tort (including negligence),
- * contract, or otherwise, unless required by applicable law (such as deliberate
- * and grossly negligent acts) or agreed to in writing, shall any Contributor be
- * liable for any damages, including any direct, indirect, special, incidental,
- * or consequential damages of any character arising as a result of this License or
- * out of the use or inability to use the software (including but not limited to damages
- * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
- * all other commercial damages or losses), even if such Contributor has been advised
- * of the possibility of such damages.
- */
-
-#pragma once
-
-// clang-format off
-
-/// \file
-/// Definition of the device capabilities
-
-#include "GraphicsTypes.h"
-
-DILIGENT_BEGIN_NAMESPACE(Diligent)
-
-/// Device type
-enum RENDER_DEVICE_TYPE
-{
- RENDER_DEVICE_TYPE_UNDEFINED = 0, ///< Undefined device
- RENDER_DEVICE_TYPE_D3D11, ///< D3D11 device
- RENDER_DEVICE_TYPE_D3D12, ///< D3D12 device
- RENDER_DEVICE_TYPE_GL, ///< OpenGL device
- RENDER_DEVICE_TYPE_GLES, ///< OpenGLES device
- RENDER_DEVICE_TYPE_VULKAN, ///< Vulkan device
- RENDER_DEVICE_TYPE_METAL ///< Metal device (not yet implemented)
-};
-
-/// Texture sampler capabilities
-struct SamplerCaps
-{
- /// Indicates if device supports border texture addressing mode
- Bool BorderSamplingModeSupported DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports anisotrpoic filtering
- Bool AnisotropicFilteringSupported DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports MIP load bias
- Bool LODBiasSupported DEFAULT_INITIALIZER(False);
-};
-typedef struct SamplerCaps SamplerCaps;
-
-/// Texture capabilities
-struct TextureCaps
-{
- /// Maximum dimension (width) of a 1D texture, or 0 if 1D textures are not supported.
- Uint32 MaxTexture1DDimension DEFAULT_INITIALIZER(0);
-
- /// Maximum number of slices in a 1D texture array, or 0 if 1D texture arrays are not supported.
- Uint32 MaxTexture1DArraySlices DEFAULT_INITIALIZER(0);
-
- /// Maximum dimension (width or height) of a 2D texture.
- Uint32 MaxTexture2DDimension DEFAULT_INITIALIZER(0);
-
- /// Maximum number of slices in a 2D texture array, or 0 if 2D texture arrays are not supported.
- Uint32 MaxTexture2DArraySlices DEFAULT_INITIALIZER(0);
-
- /// Maximum dimension (width, height, or depth) of a 3D texture, or 0 if 3D textures are not supported.
- Uint32 MaxTexture3DDimension DEFAULT_INITIALIZER(0);
-
- /// Maximum dimension (width or height) of a cubemap face, or 0 if cubemap textures are not supported.
- Uint32 MaxTextureCubeDimension DEFAULT_INITIALIZER(0);
-
- /// Indicates if device supports 2D multisampled textures
- Bool Texture2DMSSupported DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports 2D multisampled texture arrays
- Bool Texture2DMSArraySupported DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports texture views
- Bool TextureViewSupported DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports cubemap arrays
- Bool CubemapArraysSupported DEFAULT_INITIALIZER(False);
-};
-typedef struct TextureCaps TextureCaps;
-
-/// Describes supported device features
-struct DeviceFeatures
-{
- /// Indicates if device supports separable programs
- Bool SeparablePrograms DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports indirect draw commands
- Bool IndirectRendering DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports wireframe fill mode
- Bool WireframeFill DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports multithreaded resource creation
- Bool MultithreadedResourceCreation DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports compute shaders
- Bool ComputeShaders DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports geometry shaders
- Bool GeometryShaders DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports tessellation
- Bool Tessellation DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports mesh and amplification shaders
- Bool MeshShaders DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports bindless resources
- Bool BindlessResources DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports occlusion queries (see Diligent::QUERY_TYPE_OCCLUSION).
- Bool OcclusionQueries DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports binary occlusion queries (see Diligent::QUERY_TYPE_BINARY_OCCLUSION).
- Bool BinaryOcclusionQueries DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports timestamp queries (see Diligent::QUERY_TYPE_TIMESTAMP).
- Bool TimestampQueries DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports pipeline statistics queries (see Diligent::QUERY_TYPE_PIPELINE_STATISTICS).
- Bool PipelineStatisticsQueries DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports duration queries (see Diligent::QUERY_TYPE_DURATION).
- Bool DurationQueries DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports depth bias clamping
- Bool DepthBiasClamp DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports depth clamping
- Bool DepthClamp DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports depth clamping
- Bool IndependentBlend DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports dual-source blend
- Bool DualSourceBlend DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports multiviewport
- Bool MultiViewport DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports all BC-compressed formats
- Bool TextureCompressionBC DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports writes to UAVs as well as atomic operations in vertex,
- /// tessellation, and geometry shader stages.
- Bool VertexPipelineUAVWritesAndAtomics DEFAULT_INITIALIZER(False);
-
- /// Indicates if device supports writes to UAVs as well as atomic operations in pixel
- /// shader stage.
- Bool PixelUAVWritesAndAtomics DEFAULT_INITIALIZER(False);
-
- /// Specifies whether all the extended UAV texture formats are available in shader code.
- Bool TextureUAVExtendedFormats DEFAULT_INITIALIZER(False);
-};
-typedef struct DeviceFeatures DeviceFeatures;
-
-/// Device capabilities
-struct DeviceCaps
-{
- /// Device type. See Diligent::DeviceType.
- enum RENDER_DEVICE_TYPE DevType DEFAULT_INITIALIZER(RENDER_DEVICE_TYPE_UNDEFINED);
-
- /// 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 DEFAULT_INITIALIZER(0);
-
- /// Minor revision of the graphics API supported by the graphics adapter.
- /// Similar to MajorVersion, this value indicates the maximum supported feature level.
- Int32 MinorVersion DEFAULT_INITIALIZER(0);
-
- /// Adapter type. See Diligent::ADAPTER_TYPE.
- ADAPTER_TYPE AdaterType DEFAULT_INITIALIZER(ADAPTER_TYPE_UNKNOWN);
-
- /// Texture sampling capabilities. See Diligent::SamplerCaps.
- SamplerCaps SamCaps;
-
- /// Texture capabilities. See Diligent::TextureCaps.
- TextureCaps TexCaps;
-
- /// Device features. See Diligent::DeviceFeatures.
- DeviceFeatures Features;
-
-#if DILIGENT_CPP_INTERFACE
- bool IsGLDevice()const
- {
- return DevType == RENDER_DEVICE_TYPE_GL || DevType == RENDER_DEVICE_TYPE_GLES;
- }
- bool IsD3DDevice()const
- {
- return DevType == RENDER_DEVICE_TYPE_D3D11 || DevType == RENDER_DEVICE_TYPE_D3D12;
- }
- bool IsVulkanDevice()const
- {
- return DevType == RENDER_DEVICE_TYPE_VULKAN;
- }
-
- struct NDCAttribs
- {
- const float MinZ; // Minimum z value of normalized device coordinate space
- const float ZtoDepthScale; // NDC z to depth scale
- const float YtoVScale; // Scale to transform NDC y coordinate to texture V coordinate
-
- float GetZtoDepthBias() const
- {
- // Returns ZtoDepthBias such that given NDC z coordinate, depth value can be
- // computed as follows:
- // d = z * ZtoDepthScale + ZtoDepthBias
- return -MinZ * ZtoDepthScale;
- }
- };
-
- const NDCAttribs& GetNDCAttribs()const
- {
- if (IsVulkanDevice())
- {
- // Note that Vulkan itself does not invert Y coordinate when transforming
- // normalized device Y to window space. However, we use negative viewport
- // height which achieves the same effect as in D3D, thererfore we need to
- // invert y (see comments in DeviceContextVkImpl::CommitViewports() for details)
- static constexpr const NDCAttribs NDCAttribsVk {0.0f, 1.0f, -0.5f};
- return NDCAttribsVk;
- }
- else if (IsD3DDevice())
- {
- static constexpr const NDCAttribs NDCAttribsD3D {0.0f, 1.0f, -0.5f};
- return NDCAttribsD3D;
- }
- else if (IsGLDevice())
- {
- static constexpr const NDCAttribs NDCAttribsGL {-1.0f, 0.5f, 0.5f};
- return NDCAttribsGL;
- }
- else
- {
- static constexpr const NDCAttribs NDCAttribsDefault {0.0f, 1.0f, 0.5f};
- return NDCAttribsDefault;
- }
- }
-#endif
-};
-typedef struct DeviceCaps DeviceCaps;
-
-DILIGENT_END_NAMESPACE // namespace Diligent
diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h
index 272c2cd5..6320f947 100644
--- a/Graphics/GraphicsEngine/interface/DeviceContext.h
+++ b/Graphics/GraphicsEngine/interface/DeviceContext.h
@@ -34,7 +34,7 @@
#include "../../../Primitives/interface/Object.h"
#include "../../../Primitives/interface/FlagEnum.h"
-#include "DeviceCaps.h"
+#include "GraphicsTypes.h"
#include "Constants.h"
#include "Buffer.h"
#include "InputLayout.h"
diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
index 323a3fd1..c8514a65 100644
--- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h
+++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h
@@ -1453,6 +1453,297 @@ enum QUERY_TYPE
};
+
+/// Device type
+enum RENDER_DEVICE_TYPE
+{
+ RENDER_DEVICE_TYPE_UNDEFINED = 0, ///< Undefined device
+ RENDER_DEVICE_TYPE_D3D11, ///< D3D11 device
+ RENDER_DEVICE_TYPE_D3D12, ///< D3D12 device
+ RENDER_DEVICE_TYPE_GL, ///< OpenGL device
+ RENDER_DEVICE_TYPE_GLES, ///< OpenGLES device
+ RENDER_DEVICE_TYPE_VULKAN, ///< Vulkan device
+ RENDER_DEVICE_TYPE_METAL ///< Metal device (not yet implemented)
+};
+
+
+/// Texture sampler capabilities
+struct SamplerCaps
+{
+ /// Indicates if device supports border texture addressing mode
+ Bool BorderSamplingModeSupported DEFAULT_INITIALIZER(False);
+
+ /// Indicates if device supports anisotrpoic filtering
+ Bool AnisotropicFilteringSupported DEFAULT_INITIALIZER(False);
+
+ /// Indicates if device supports MIP load bias
+ Bool LODBiasSupported DEFAULT_INITIALIZER(False);
+};
+typedef struct SamplerCaps SamplerCaps;
+
+
+/// Texture capabilities
+struct TextureCaps
+{
+ /// Maximum dimension (width) of a 1D texture, or 0 if 1D textures are not supported.
+ Uint32 MaxTexture1DDimension DEFAULT_INITIALIZER(0);
+
+ /// Maximum number of slices in a 1D texture array, or 0 if 1D texture arrays are not supported.
+ Uint32 MaxTexture1DArraySlices DEFAULT_INITIALIZER(0);
+
+ /// Maximum dimension (width or height) of a 2D texture.
+ Uint32 MaxTexture2DDimension DEFAULT_INITIALIZER(0);
+
+ /// Maximum number of slices in a 2D texture array, or 0 if 2D texture arrays are not supported.
+ Uint32 MaxTexture2DArraySlices DEFAULT_INITIALIZER(0);
+
+ /// Maximum dimension (width, height, or depth) of a 3D texture, or 0 if 3D textures are not supported.
+ Uint32 MaxTexture3DDimension DEFAULT_INITIALIZER(0);
+
+ /// Maximum dimension (width or height) of a cubemap face, or 0 if cubemap textures are not supported.
+ Uint32 MaxTextureCubeDimension DEFAULT_INITIALIZER(0);
+
+ /// Indicates if device supports 2D multisampled textures
+ Bool Texture2DMSSupported DEFAULT_INITIALIZER(False);
+
+ /// Indicates if device supports 2D multisampled texture arrays
+ Bool Texture2DMSArraySupported DEFAULT_INITIALIZER(False);
+
+ /// Indicates if device supports texture views
+ Bool TextureViewSupported DEFAULT_INITIALIZER(False);
+
+ /// Indicates if device supports cubemap arrays
+ Bool CubemapArraysSupported DEFAULT_INITIALIZER(False);
+};
+typedef struct TextureCaps TextureCaps;
+
+
+/// Device feature state
+DILIGENT_TYPED_ENUM(DEVICE_FEATURE_STATE, Uint8)
+{
+ /// Device feature is disabled.
+ DEVICE_FEATURE_STATE_DISABLED = 0,
+
+ /// Device feature is enabled.
+
+ /// If a feature is requested to be enabled during the initialization through
+ /// EngineCreateInfo::Feautures, but is not supported by the device/driver/platform,
+ /// the engine will fail to initialize.
+ DEVICE_FEATURE_STATE_ENABLED = 1,
+
+ /// Device feature is optional.
+
+ /// During the initialization the engine will attempt to enable the feature.
+ /// If the feature is not supported by the device/driver/platform,
+ /// the engine will successfully be initialized, but the feature will be disabled.
+ /// The actual feature state can be queried from DeviceCaps structure.
+ DEVICE_FEATURE_STATE_OPTIONAL = 2
+};
+
+
+/// Describes the device features
+struct DeviceFeatures
+{
+ /// Indicates if device supports separable programs
+ DEVICE_FEATURE_STATE SeparablePrograms DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports indirect draw commands
+ DEVICE_FEATURE_STATE IndirectRendering DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports wireframe fill mode
+ DEVICE_FEATURE_STATE WireframeFill DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports multithreaded resource creation
+ DEVICE_FEATURE_STATE MultithreadedResourceCreation DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports compute shaders
+ DEVICE_FEATURE_STATE ComputeShaders DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports geometry shaders
+ DEVICE_FEATURE_STATE GeometryShaders DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports tessellation
+ DEVICE_FEATURE_STATE Tessellation DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports mesh and amplification shaders
+ DEVICE_FEATURE_STATE MeshShaders DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports bindless resources
+ DEVICE_FEATURE_STATE BindlessResources DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports occlusion queries (see Diligent::QUERY_TYPE_OCCLUSION).
+ DEVICE_FEATURE_STATE OcclusionQueries DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports binary occlusion queries (see Diligent::QUERY_TYPE_BINARY_OCCLUSION).
+ DEVICE_FEATURE_STATE BinaryOcclusionQueries DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports timestamp queries (see Diligent::QUERY_TYPE_TIMESTAMP).
+ DEVICE_FEATURE_STATE TimestampQueries DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports pipeline statistics queries (see Diligent::QUERY_TYPE_PIPELINE_STATISTICS).
+ DEVICE_FEATURE_STATE PipelineStatisticsQueries DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports duration queries (see Diligent::QUERY_TYPE_DURATION).
+ DEVICE_FEATURE_STATE DurationQueries DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports depth bias clamping
+ DEVICE_FEATURE_STATE DepthBiasClamp DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports depth clamping
+ DEVICE_FEATURE_STATE DepthClamp DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports depth clamping
+ DEVICE_FEATURE_STATE IndependentBlend DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports dual-source blend
+ DEVICE_FEATURE_STATE DualSourceBlend DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports multiviewport
+ DEVICE_FEATURE_STATE MultiViewport DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports all BC-compressed formats
+ DEVICE_FEATURE_STATE TextureCompressionBC DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports writes to UAVs as well as atomic operations in vertex,
+ /// tessellation, and geometry shader stages.
+ DEVICE_FEATURE_STATE VertexPipelineUAVWritesAndAtomics DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Indicates if device supports writes to UAVs as well as atomic operations in pixel
+ /// shader stage.
+ DEVICE_FEATURE_STATE PixelUAVWritesAndAtomics DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+ /// Specifies whether all the extended UAV texture formats are available in shader code.
+ DEVICE_FEATURE_STATE TextureUAVExtendedFormats DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
+
+#if DILIGENT_CPP_INTERFACE
+ DeviceFeatures() noexcept {}
+
+ explicit DeviceFeatures(DEVICE_FEATURE_STATE State) noexcept :
+ SeparablePrograms {State},
+ IndirectRendering {State},
+ WireframeFill {State},
+ MultithreadedResourceCreation {State},
+ ComputeShaders {State},
+ GeometryShaders {State},
+ Tessellation {State},
+ MeshShaders {State},
+ BindlessResources {State},
+ OcclusionQueries {State},
+ BinaryOcclusionQueries {State},
+ TimestampQueries {State},
+ PipelineStatisticsQueries {State},
+ DurationQueries {State},
+ DepthBiasClamp {State},
+ DepthClamp {State},
+ IndependentBlend {State},
+ DualSourceBlend {State},
+ MultiViewport {State},
+ TextureCompressionBC {State},
+ VertexPipelineUAVWritesAndAtomics {State},
+ PixelUAVWritesAndAtomics {State},
+ TextureUAVExtendedFormats {State}
+ {
+# if defined(_MSC_VER) && defined(_WIN64)
+ static_assert(sizeof(*this) == 23, "Did you add a new feature to DeviceFeatures? Please handle its satus above.");
+# endif
+ }
+#endif
+};
+typedef struct DeviceFeatures DeviceFeatures;
+
+
+/// Device capabilities
+struct DeviceCaps
+{
+ /// Device type. See Diligent::DeviceType.
+ enum RENDER_DEVICE_TYPE DevType DEFAULT_INITIALIZER(RENDER_DEVICE_TYPE_UNDEFINED);
+
+ /// 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 DEFAULT_INITIALIZER(0);
+
+ /// Minor revision of the graphics API supported by the graphics adapter.
+ /// Similar to MajorVersion, this value indicates the maximum supported feature level.
+ Int32 MinorVersion DEFAULT_INITIALIZER(0);
+
+ /// Adapter type. See Diligent::ADAPTER_TYPE.
+ ADAPTER_TYPE AdaterType DEFAULT_INITIALIZER(ADAPTER_TYPE_UNKNOWN);
+
+ /// Texture sampling capabilities. See Diligent::SamplerCaps.
+ SamplerCaps SamCaps;
+
+ /// Texture capabilities. See Diligent::TextureCaps.
+ TextureCaps TexCaps;
+
+ /// Device features. See Diligent::DeviceFeatures.
+
+ /// \note For optional features requested during the initialization, the
+ /// struct will indicate the actual feature state (enabled or disabled).
+ DeviceFeatures Features;
+
+#if DILIGENT_CPP_INTERFACE
+ bool IsGLDevice()const
+ {
+ return DevType == RENDER_DEVICE_TYPE_GL || DevType == RENDER_DEVICE_TYPE_GLES;
+ }
+ bool IsD3DDevice()const
+ {
+ return DevType == RENDER_DEVICE_TYPE_D3D11 || DevType == RENDER_DEVICE_TYPE_D3D12;
+ }
+ bool IsVulkanDevice()const
+ {
+ return DevType == RENDER_DEVICE_TYPE_VULKAN;
+ }
+
+ struct NDCAttribs
+ {
+ const float MinZ; // Minimum z value of normalized device coordinate space
+ const float ZtoDepthScale; // NDC z to depth scale
+ const float YtoVScale; // Scale to transform NDC y coordinate to texture V coordinate
+
+ float GetZtoDepthBias() const
+ {
+ // Returns ZtoDepthBias such that given NDC z coordinate, depth value can be
+ // computed as follows:
+ // d = z * ZtoDepthScale + ZtoDepthBias
+ return -MinZ * ZtoDepthScale;
+ }
+ };
+
+ const NDCAttribs& GetNDCAttribs()const
+ {
+ if (IsVulkanDevice())
+ {
+ // Note that Vulkan itself does not invert Y coordinate when transforming
+ // normalized device Y to window space. However, we use negative viewport
+ // height which achieves the same effect as in D3D, thererfore we need to
+ // invert y (see comments in DeviceContextVkImpl::CommitViewports() for details)
+ static constexpr const NDCAttribs NDCAttribsVk {0.0f, 1.0f, -0.5f};
+ return NDCAttribsVk;
+ }
+ else if (IsD3DDevice())
+ {
+ static constexpr const NDCAttribs NDCAttribsD3D {0.0f, 1.0f, -0.5f};
+ return NDCAttribsD3D;
+ }
+ else if (IsGLDevice())
+ {
+ static constexpr const NDCAttribs NDCAttribsGL {-1.0f, 0.5f, 0.5f};
+ return NDCAttribsGL;
+ }
+ else
+ {
+ static constexpr const NDCAttribs NDCAttribsDefault {0.0f, 1.0f, 0.5f};
+ return NDCAttribsDefault;
+ }
+ }
+#endif
+};
+typedef struct DeviceCaps DeviceCaps;
+
+
/// Engine creation attibutes
struct EngineCreateInfo
{
@@ -1472,6 +1763,17 @@ struct EngineCreateInfo
/// Pointer to the user-specified debug message callback function
DebugMessageCallbackType DebugMessageCallback DEFAULT_INITIALIZER(nullptr);
+
+ /// Requested device features.
+
+ /// \remarks If a feature is requested to be enabled, but is not supported
+ /// by the device/driver/platform, the engine will fail to initialize.
+ ///
+ /// If a feature is requested to be optioanl, the engine will attempt to enable the feature.
+ /// If the feature is not supported by the device/driver/platform,
+ /// the engine will successfully be initialized, but the feature will be disabled.
+ /// The actual feature state can be queried from DeviceCaps structure.
+ DeviceFeatures Features;
};
typedef struct EngineCreateInfo EngineCreateInfo;
diff --git a/Graphics/GraphicsEngine/interface/RenderDevice.h b/Graphics/GraphicsEngine/interface/RenderDevice.h
index ddbc75b2..0cea79eb 100644
--- a/Graphics/GraphicsEngine/interface/RenderDevice.h
+++ b/Graphics/GraphicsEngine/interface/RenderDevice.h
@@ -33,7 +33,6 @@
#include "../../../Primitives/interface/Object.h"
#include "EngineFactory.h"
#include "GraphicsTypes.h"
-#include "DeviceCaps.h"
#include "Constants.h"
#include "Buffer.h"
#include "InputLayout.h"
diff --git a/Graphics/GraphicsEngine/src/APIInfo.cpp b/Graphics/GraphicsEngine/src/APIInfo.cpp
index 55c2e0ba..d0d16ad9 100644
--- a/Graphics/GraphicsEngine/src/APIInfo.cpp
+++ b/Graphics/GraphicsEngine/src/APIInfo.cpp
@@ -30,7 +30,7 @@
#include "Buffer.h"
#include "BufferView.h"
#include "DepthStencilState.h"
-#include "DeviceCaps.h"
+#include "GraphicsTypes.h"
#include "DeviceContext.h"
#include "InputLayout.h"
#include "PipelineState.h"
diff --git a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp
index f041806c..8003615e 100644
--- a/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/RenderDeviceD3D11Impl.hpp
@@ -48,7 +48,7 @@ public:
IEngineFactory* pEngineFactory,
const EngineD3D11CreateInfo& EngineAttribs,
ID3D11Device* pd3d11Device,
- Uint32 NumDeferredContexts);
+ Uint32 NumDeferredContexts) noexcept(false);
virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
/// Implementation of IRenderDevice::CreateBuffer() in Direct3D11 backend.
diff --git a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
index c8c26d80..d5671816 100644
--- a/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/RenderDeviceD3D11Impl.cpp
@@ -143,12 +143,25 @@ RenderDeviceD3D11Impl::RenderDeviceD3D11Impl(IReferenceCounters* pRefCo
}
}
+#define UNSUPPORTED_FEATURE(Feature, Name) \
+ do \
+ { \
+ if (EngineAttribs.Features.Feature == DEVICE_FEATURE_STATE_ENABLED) \
+ LOG_ERROR_AND_THROW(Name " not supported by Direct3D11 device"); \
+ m_DeviceCaps.Features.Feature = DEVICE_FEATURE_STATE_DISABLED; \
+ } while (false)
+
// Direct3D11 only supports shader model 5.0 even if the device feature level is
// above 11.0 (for example, 11.1 or 12.0), so bindless resources are never available.
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro#overview-for-each-feature-level
- m_DeviceCaps.Features.BindlessResources = False;
-
- m_DeviceCaps.Features.VertexPipelineUAVWritesAndAtomics = False;
+ UNSUPPORTED_FEATURE(BindlessResources, "Bindless resources are");
+ UNSUPPORTED_FEATURE(VertexPipelineUAVWritesAndAtomics, "Vertex pipeline UAV writes and atomics are");
+ UNSUPPORTED_FEATURE(MeshShaders, "Mesh shaders are");
+#undef UNSUPPORTED_FEATURE
+
+#if defined(_MSC_VER) && defined(_WIN64)
+ static_assert(sizeof(DeviceFeatures) == 23, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+#endif
auto& TexCaps = m_DeviceCaps.TexCaps;
diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
index 710db2ef..5c077497 100644
--- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
@@ -57,7 +57,7 @@ public:
const EngineD3D12CreateInfo& EngineCI,
ID3D12Device* pD3D12Device,
size_t CommandQueueCount,
- ICommandQueueD3D12** ppCmdQueues);
+ ICommandQueueD3D12** ppCmdQueues) noexcept(false);
~RenderDeviceD3D12Impl();
virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
index 76e8aa07..b91ac760 100644
--- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
@@ -154,113 +154,141 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo
m_pDxCompiler {CreateDXCompiler(DXCompilerTarget::Direct3D12, EngineCI.pDxCompilerPath)}
// clang-format on
{
- m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_D3D12;
- auto FeatureLevel = GetD3DFeatureLevel();
- switch (FeatureLevel)
+ try
{
- 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;
- 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;
- 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.DevType = RENDER_DEVICE_TYPE_D3D12;
+ 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;
+ break;
- if (auto pDXGIAdapter1 = DXGIAdapterFromD3D12Device(pd3d12Device))
- {
- DXGI_ADAPTER_DESC1 AdapterDesc = {};
+ 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;
- auto hr = pDXGIAdapter1->GetDesc1(&AdapterDesc);
- if (SUCCEEDED(hr))
- {
- m_DeviceCaps.AdaterType = (AdapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) ? ADAPTER_TYPE_SOFTWARE : ADAPTER_TYPE_HARDWARE;
- }
- else
- {
- LOG_ERROR_MESSAGE("Failed to get DXGIDevice adapter desc. Adapter type will be unknown.");
+ 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");
}
- }
- // Direct3D12 supports shader model 5.1 on all feature levels (even on 11.0),
- // so bindless resources are always available.
- // https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels#feature-level-support
- m_DeviceCaps.Features.BindlessResources = True;
+ if (auto pDXGIAdapter1 = DXGIAdapterFromD3D12Device(pd3d12Device))
+ {
+ DXGI_ADAPTER_DESC1 AdapterDesc = {};
- m_DeviceCaps.Features.VertexPipelineUAVWritesAndAtomics = True;
+ auto hr = pDXGIAdapter1->GetDesc1(&AdapterDesc);
+ if (SUCCEEDED(hr))
+ {
+ m_DeviceCaps.AdaterType = (AdapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) ? ADAPTER_TYPE_SOFTWARE : ADAPTER_TYPE_HARDWARE;
+ }
+ else
+ {
+ LOG_ERROR_MESSAGE("Failed to get DXGIDevice adapter desc. Adapter type will be unknown.");
+ }
+ }
- // Detect maximum shader model.
- {
- // Direct3D12 supports shader model 5.1 on all feature levels.
+ // Direct3D12 supports shader model 5.1 on all feature levels (even on 11.0),
+ // so bindless resources are always available.
// https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels#feature-level-support
- m_MaxShaderModel = D3D_SHADER_MODEL_5_1;
+ m_DeviceCaps.Features.BindlessResources = DEVICE_FEATURE_STATE_ENABLED;
- // Header may not have constants for D3D_SHADER_MODEL_6_1 and above.
- const D3D_SHADER_MODEL Models[] = //
- {
- static_cast<D3D_SHADER_MODEL>(0x65), // minimum required for mesh shader
- static_cast<D3D_SHADER_MODEL>(0x64),
- static_cast<D3D_SHADER_MODEL>(0x63),
- static_cast<D3D_SHADER_MODEL>(0x62),
- static_cast<D3D_SHADER_MODEL>(0x61),
- D3D_SHADER_MODEL_6_0 //
- };
-
- for (auto Model : Models)
+ m_DeviceCaps.Features.VertexPipelineUAVWritesAndAtomics = DEVICE_FEATURE_STATE_ENABLED;
+
+ // Detect maximum shader model.
{
- D3D12_FEATURE_DATA_SHADER_MODEL ShaderModel = {Model};
- if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &ShaderModel, sizeof(ShaderModel))))
+ // Direct3D12 supports shader model 5.1 on all feature levels.
+ // https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels#feature-level-support
+ m_MaxShaderModel = D3D_SHADER_MODEL_5_1;
+
+ // Header may not have constants for D3D_SHADER_MODEL_6_1 and above.
+ const D3D_SHADER_MODEL Models[] = //
+ {
+ static_cast<D3D_SHADER_MODEL>(0x65), // minimum required for mesh shader
+ static_cast<D3D_SHADER_MODEL>(0x64),
+ static_cast<D3D_SHADER_MODEL>(0x63),
+ static_cast<D3D_SHADER_MODEL>(0x62),
+ static_cast<D3D_SHADER_MODEL>(0x61),
+ D3D_SHADER_MODEL_6_0 //
+ };
+
+ for (auto Model : Models)
{
- m_MaxShaderModel = ShaderModel.HighestShaderModel;
- break;
+ D3D12_FEATURE_DATA_SHADER_MODEL ShaderModel = {Model};
+ if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &ShaderModel, sizeof(ShaderModel))))
+ {
+ m_MaxShaderModel = ShaderModel.HighestShaderModel;
+ break;
+ }
}
+ LOG_INFO_MESSAGE("Max device shader model: ", (m_MaxShaderModel >> 4) & 0xF, '_', m_MaxShaderModel & 0xF);
}
- }
- // Check if mesh shader is supported.
+ // Check if mesh shader is supported.
+ bool MeshShadersSupported = false;
#ifdef D3D12_H_HAS_MESH_SHADER
- {
- D3D12_FEATURE_DATA_D3D12_OPTIONS7 FeatureData = {};
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS7 FeatureData = {};
- bool SupportsMeshShader =
- SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &FeatureData, sizeof(FeatureData))) &&
- FeatureData.MeshShaderTier != D3D12_MESH_SHADER_TIER_NOT_SUPPORTED;
+ MeshShadersSupported =
+ SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &FeatureData, sizeof(FeatureData))) &&
+ FeatureData.MeshShaderTier != D3D12_MESH_SHADER_TIER_NOT_SUPPORTED;
- m_DeviceCaps.Features.MeshShaders = (m_MaxShaderModel >= D3D_SHADER_MODEL_6_5 && SupportsMeshShader);
- }
+ MeshShadersSupported = (m_MaxShaderModel >= D3D_SHADER_MODEL_6_5 && MeshShadersSupported);
+ }
+#else
+ if (EngineCI.Features.MeshShaders == DEVICE_FEATURE_STATE_ENABLED)
+ {
+ LOG_ERROR_AND_THROW("Mesh shaders are requested to be enabled, but the engine was built with the Windows SDK that does "
+ "not support the feature. Please update the SDK to version 10.0.19041.0 or later and rebuild the engine.");
+ }
#endif
- auto& TexCaps = m_DeviceCaps.TexCaps;
+ if (EngineCI.Features.MeshShaders == DEVICE_FEATURE_STATE_ENABLED && !MeshShadersSupported)
+ {
+ LOG_ERROR_AND_THROW("This device/driver does not support mesh shaders. Please make sure that you have compatible GPU and that your "
+ "Winodws is up to date (version 2004 or later is required)");
+ }
+
+ m_DeviceCaps.Features.MeshShaders = MeshShadersSupported ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED;
+
+#if defined(_MSC_VER) && defined(_WIN64)
+ static_assert(sizeof(DeviceFeatures) == 23, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+#endif
- TexCaps.MaxTexture1DDimension = D3D12_REQ_TEXTURE1D_U_DIMENSION;
- TexCaps.MaxTexture1DArraySlices = D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION;
- TexCaps.MaxTexture2DDimension = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
- TexCaps.MaxTexture2DArraySlices = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
- TexCaps.MaxTexture3DDimension = D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
- TexCaps.MaxTextureCubeDimension = D3D12_REQ_TEXTURECUBE_DIMENSION;
- TexCaps.Texture2DMSSupported = True;
- TexCaps.Texture2DMSArraySupported = True;
- TexCaps.TextureViewSupported = True;
- TexCaps.CubemapArraysSupported = True;
+ auto& TexCaps = m_DeviceCaps.TexCaps;
- auto& SamCaps = m_DeviceCaps.SamCaps;
+ TexCaps.MaxTexture1DDimension = D3D12_REQ_TEXTURE1D_U_DIMENSION;
+ TexCaps.MaxTexture1DArraySlices = D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION;
+ TexCaps.MaxTexture2DDimension = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ TexCaps.MaxTexture2DArraySlices = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
+ TexCaps.MaxTexture3DDimension = D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
+ TexCaps.MaxTextureCubeDimension = D3D12_REQ_TEXTURECUBE_DIMENSION;
+ TexCaps.Texture2DMSSupported = True;
+ TexCaps.Texture2DMSArraySupported = True;
+ TexCaps.TextureViewSupported = True;
+ TexCaps.CubemapArraysSupported = True;
- SamCaps.BorderSamplingModeSupported = True;
- SamCaps.AnisotropicFilteringSupported = True;
- SamCaps.LODBiasSupported = True;
+ auto& SamCaps = m_DeviceCaps.SamCaps;
+
+ SamCaps.BorderSamplingModeSupported = True;
+ SamCaps.AnisotropicFilteringSupported = True;
+ SamCaps.LODBiasSupported = True;
+ }
+ catch (...)
+ {
+ m_DynamicMemoryManager.Destroy();
+ throw;
+ }
}
RenderDeviceD3D12Impl::~RenderDeviceD3D12Impl()
diff --git a/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp b/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp
index fc73814d..61e5fb12 100644
--- a/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp
+++ b/Graphics/GraphicsEngineD3DBase/include/RenderDeviceD3DBase.hpp
@@ -157,26 +157,26 @@ public:
auto& Features = this->m_DeviceCaps.Features;
- Features.SeparablePrograms = True;
- Features.IndirectRendering = True;
- Features.WireframeFill = True;
- Features.MultithreadedResourceCreation = True;
- Features.ComputeShaders = True;
- Features.GeometryShaders = True;
- Features.Tessellation = True;
- Features.OcclusionQueries = True;
- Features.BinaryOcclusionQueries = True;
- Features.TimestampQueries = True;
- Features.PipelineStatisticsQueries = True;
- Features.DurationQueries = True;
- Features.DepthBiasClamp = True;
- Features.DepthClamp = True;
- Features.IndependentBlend = True;
- Features.DualSourceBlend = True;
- Features.MultiViewport = True;
- Features.TextureCompressionBC = True;
- Features.PixelUAVWritesAndAtomics = True;
- Features.TextureUAVExtendedFormats = True;
+ Features.SeparablePrograms = DEVICE_FEATURE_STATE_ENABLED;
+ Features.IndirectRendering = DEVICE_FEATURE_STATE_ENABLED;
+ Features.WireframeFill = DEVICE_FEATURE_STATE_ENABLED;
+ Features.MultithreadedResourceCreation = DEVICE_FEATURE_STATE_ENABLED;
+ Features.ComputeShaders = DEVICE_FEATURE_STATE_ENABLED;
+ Features.GeometryShaders = DEVICE_FEATURE_STATE_ENABLED;
+ Features.Tessellation = DEVICE_FEATURE_STATE_ENABLED;
+ Features.OcclusionQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.BinaryOcclusionQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.TimestampQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.PipelineStatisticsQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.DurationQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.DepthBiasClamp = DEVICE_FEATURE_STATE_ENABLED;
+ Features.DepthClamp = DEVICE_FEATURE_STATE_ENABLED;
+ Features.IndependentBlend = DEVICE_FEATURE_STATE_ENABLED;
+ Features.DualSourceBlend = DEVICE_FEATURE_STATE_ENABLED;
+ Features.MultiViewport = DEVICE_FEATURE_STATE_ENABLED;
+ Features.TextureCompressionBC = DEVICE_FEATURE_STATE_ENABLED;
+ Features.PixelUAVWritesAndAtomics = DEVICE_FEATURE_STATE_ENABLED;
+ Features.TextureUAVExtendedFormats = DEVICE_FEATURE_STATE_ENABLED;
}
};
diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp
index dbdb51c8..1dcb37d4 100644
--- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp
@@ -63,7 +63,7 @@ public:
IMemoryAllocator& RawMemAllocator,
IEngineFactory* pEngineFactory,
const EngineGLCreateInfo& InitAttribs,
- const SwapChainDesc* pSCDesc = nullptr);
+ const SwapChainDesc* pSCDesc = nullptr) noexcept(false);
~RenderDeviceGLImpl();
virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override;
@@ -188,7 +188,6 @@ private:
virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final;
bool CheckExtension(const Char* ExtensionString);
void FlagSupportedTexFormats();
- void QueryDeviceCaps();
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp
index 4d4b2916..524250d6 100644
--- a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp
@@ -28,7 +28,7 @@
#include "pch.h"
#include "GLContextWindows.hpp"
-#include "DeviceCaps.h"
+#include "GraphicsTypes.h"
#include "GLTypeConversions.hpp"
#include "GraphicsAccessories.hpp"
diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
index 6d0948ae..0ae5204c 100644
--- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp
@@ -98,7 +98,6 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
}
FlagSupportedTexFormats();
- QueryDeviceCaps();
std::basic_string<GLubyte> glstrVendor = glGetString(GL_VENDOR);
std::string Vendor = StrToLower(std::string(glstrVendor.begin(), glstrVendor.end()));
@@ -139,7 +138,49 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &MaxLayers);
CHECK_GL_ERROR("Failed to get maximum number of texture array layers");
- Features.VertexPipelineUAVWritesAndAtomics = False;
+#define SET_FEATURE_STATE(Feature, IsSupported, FeatureName) \
+ do \
+ { \
+ switch (InitAttribs.Features.Feature) \
+ { \
+ case DEVICE_FEATURE_STATE_ENABLED: \
+ { \
+ if (!(IsSupported)) \
+ LOG_ERROR_AND_THROW(FeatureName, " not supported by this device"); \
+ else \
+ Features.Feature = DEVICE_FEATURE_STATE_ENABLED; \
+ } \
+ break; \
+ case DEVICE_FEATURE_STATE_DISABLED: \
+ case DEVICE_FEATURE_STATE_OPTIONAL: \
+ Features.Feature = (IsSupported) ? \
+ DEVICE_FEATURE_STATE_ENABLED : \
+ DEVICE_FEATURE_STATE_DISABLED; \
+ break; \
+ default: UNEXPECTED("Unexpected feature state"); \
+ } \
+ } while (false)
+
+ SET_FEATURE_STATE(VertexPipelineUAVWritesAndAtomics, false, "Vertex pipeline UAV writes and atomics are");
+ SET_FEATURE_STATE(MeshShaders, false, "Mesh shaders are");
+
+ {
+ bool WireframeFillSupported = (glPolygonMode != nullptr);
+ if (WireframeFillSupported)
+ {
+ // Test glPolygonMode() function to check if it fails
+ // (It does fail on NVidia Shield tablet, but works fine
+ // on Intel hw)
+ VERIFY(glGetError() == GL_NO_ERROR, "Unhandled gl error encountered");
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ if (glGetError() != GL_NO_ERROR)
+ WireframeFillSupported = false;
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ if (glGetError() != GL_NO_ERROR)
+ WireframeFillSupported = false;
+ }
+ SET_FEATURE_STATE(WireframeFill, WireframeFillSupported, "Wireframe fill is");
+ }
if (m_DeviceCaps.DevType == RENDER_DEVICE_TYPE_GL)
{
@@ -148,27 +189,30 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
const bool IsGL42OrAbove = (MajorVersion >= 5) || (MajorVersion == 4 && MinorVersion >= 2);
const bool IsGL41OrAbove = (MajorVersion >= 5) || (MajorVersion == 4 && MinorVersion >= 1);
- Features.SeparablePrograms = True;
- Features.IndirectRendering = True;
- Features.WireframeFill = True;
- Features.MultithreadedResourceCreation = False;
- Features.ComputeShaders = IsGL43OrAbove || CheckExtension("GL_ARB_compute_shader");
- Features.GeometryShaders = MajorVersion >= 4 || CheckExtension("GL_ARB_geometry_shader4");
- Features.Tessellation = MajorVersion >= 4 || CheckExtension("GL_ARB_tessellation_shader");
- Features.BindlessResources = False;
- Features.OcclusionQueries = True; // Present since 3.3
- Features.BinaryOcclusionQueries = True; // Present since 3.3
- Features.TimestampQueries = True; // Present since 3.3
- Features.PipelineStatisticsQueries = True; // Present since 3.3
- Features.DurationQueries = True; // Present since 3.3
- Features.DepthBiasClamp = False; // There is no depth bias clamp in OpenGL
- Features.DepthClamp = MajorVersion >= 4 || CheckExtension("GL_ARB_depth_clamp");
- Features.IndependentBlend = True;
- Features.DualSourceBlend = IsGL41OrAbove || CheckExtension("GL_ARB_blend_func_extended");
- Features.MultiViewport = IsGL41OrAbove || CheckExtension("GL_ARB_viewport_array");
- Features.PixelUAVWritesAndAtomics = IsGL42OrAbove || CheckExtension("GL_ARB_shader_image_load_store");
- Features.TextureUAVExtendedFormats = False;
-
+ Features.SeparablePrograms = DEVICE_FEATURE_STATE_ENABLED;
+ Features.IndirectRendering = DEVICE_FEATURE_STATE_ENABLED;
+ Features.WireframeFill = DEVICE_FEATURE_STATE_ENABLED;
+ // clang-format off
+ SET_FEATURE_STATE(MultithreadedResourceCreation, false, "Multithreaded resource creation is");
+ SET_FEATURE_STATE(ComputeShaders, IsGL43OrAbove || CheckExtension("GL_ARB_compute_shader"), "Compute shaders are");
+ SET_FEATURE_STATE(GeometryShaders, MajorVersion >= 4 || CheckExtension("GL_ARB_geometry_shader4"), "Geometry shaders are");
+ SET_FEATURE_STATE(Tessellation, MajorVersion >= 4 || CheckExtension("GL_ARB_tessellation_shader"), "Tessellation is");
+ SET_FEATURE_STATE(BindlessResources, false, "Bindless resources are");
+ // clang-format on
+ Features.OcclusionQueries = DEVICE_FEATURE_STATE_ENABLED; // Present since 3.3
+ Features.BinaryOcclusionQueries = DEVICE_FEATURE_STATE_ENABLED; // Present since 3.3
+ Features.TimestampQueries = DEVICE_FEATURE_STATE_ENABLED; // Present since 3.3
+ Features.PipelineStatisticsQueries = DEVICE_FEATURE_STATE_ENABLED; // Present since 3.3
+ Features.DurationQueries = DEVICE_FEATURE_STATE_ENABLED; // Present since 3.3
+ // clang-format off
+ SET_FEATURE_STATE(DepthBiasClamp, false, "Depth bias clamp is"); // There is no depth bias clamp in OpenGL
+ SET_FEATURE_STATE(DepthClamp, MajorVersion >= 4 || CheckExtension("GL_ARB_depth_clamp"), "Depth clamp is");
+ SET_FEATURE_STATE(IndependentBlend, true, "Independent blend is");
+ SET_FEATURE_STATE(DualSourceBlend, IsGL41OrAbove || CheckExtension("GL_ARB_blend_func_extended"), "Dual source blend is");
+ SET_FEATURE_STATE(MultiViewport, IsGL41OrAbove || CheckExtension("GL_ARB_viewport_array"), "Multi viewport is");
+ SET_FEATURE_STATE(PixelUAVWritesAndAtomics, IsGL42OrAbove || CheckExtension("GL_ARB_shader_image_load_store"), "Pixel UAV writes and atomics are");
+ SET_FEATURE_STATE(TextureUAVExtendedFormats, false, "Texture UAV extended formats are");
+ // clang-format on
TexCaps.MaxTexture1DDimension = MaxTextureSize;
TexCaps.MaxTexture1DArraySlices = MaxLayers;
@@ -195,32 +239,33 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
bool IsGLES31OrAbove = (MajorVersion >= 4) || (MajorVersion == 3 && MinorVersion >= 1);
bool IsGLES32OrAbove = (MajorVersion >= 4) || (MajorVersion == 3 && MinorVersion >= 2);
- Features.SeparablePrograms = IsGLES31OrAbove || strstr(Extensions, "separate_shader_objects");
- Features.IndirectRendering = IsGLES31OrAbove || strstr(Extensions, "draw_indirect");
- Features.WireframeFill = False;
- Features.MultithreadedResourceCreation = False;
- Features.ComputeShaders = IsGLES31OrAbove || strstr(Extensions, "compute_shader");
- Features.GeometryShaders = IsGLES32OrAbove || strstr(Extensions, "geometry_shader");
- Features.Tessellation = IsGLES32OrAbove || strstr(Extensions, "tessellation_shader");
- Features.BindlessResources = False;
- Features.OcclusionQueries = False;
- Features.BinaryOcclusionQueries = True; // Supported in GLES3.0
+ // clang-format off
+ SET_FEATURE_STATE(SeparablePrograms, IsGLES31OrAbove || strstr(Extensions, "separate_shader_objects"), "Separable programs are");
+ SET_FEATURE_STATE(IndirectRendering, IsGLES31OrAbove || strstr(Extensions, "draw_indirect"), "Indirect rendering is");
+ SET_FEATURE_STATE(WireframeFill, false, "Wireframe fill is");
+ SET_FEATURE_STATE(MultithreadedResourceCreation, false, "Multithreaded resource creation is");
+ SET_FEATURE_STATE(ComputeShaders, IsGLES31OrAbove || strstr(Extensions, "compute_shader"), "Compute shaders are");
+ SET_FEATURE_STATE(GeometryShaders, IsGLES32OrAbove || strstr(Extensions, "geometry_shader"), "Geometry shaders are");
+ SET_FEATURE_STATE(Tessellation, IsGLES32OrAbove || strstr(Extensions, "tessellation_shader"), "Tessellation is");
+ SET_FEATURE_STATE(BindlessResources, false, "Bindless resources are");
+ SET_FEATURE_STATE(OcclusionQueries, false, "Occlusion queries are");
+ SET_FEATURE_STATE(BinaryOcclusionQueries, true, "Binary occlusion queries are"); // Supported in GLES3.0
#if GL_TIMESTAMP
- Features.TimestampQueries = strstr(Extensions, "disjoint_timer_query");
- Features.DurationQueries = Features.TimestampQueries;
+ SET_FEATURE_STATE(TimestampQueries, strstr(Extensions, "disjoint_timer_query"), "Timestamp queries are");
+ SET_FEATURE_STATE(DurationQueries, Features.TimestampQueries, "Duration queries are");
#else
- Features.TimestampQueries = False;
- Features.DurationQueries = False;
+ SET_FEATURE_STATE(TimestampQueries, false, "Timestamp queries are");
+ SET_FEATURE_STATE(DurationQueries, false, "Duration queries are");
#endif
- Features.PipelineStatisticsQueries = False;
- Features.DepthBiasClamp = False; // There is no depth bias clamp in OpenGL
- Features.DepthClamp = strstr(Extensions, "depth_clamp");
- Features.IndependentBlend = IsGLES32OrAbove;
- Features.DualSourceBlend = strstr(Extensions, "blend_func_extended");
- Features.MultiViewport = strstr(Extensions, "viewport_array");
- Features.PixelUAVWritesAndAtomics = IsGLES31OrAbove || strstr(Extensions, "shader_image_load_store");
- Features.TextureUAVExtendedFormats = False;
-
+ SET_FEATURE_STATE(PipelineStatisticsQueries, false, "Pipeline atatistics queries are");
+ SET_FEATURE_STATE(DepthBiasClamp, false, "Depth bias clamp is"); // There is no depth bias clamp in OpenGL
+ SET_FEATURE_STATE(DepthClamp, strstr(Extensions, "depth_clamp"), "Depth clamp is");
+ SET_FEATURE_STATE(IndependentBlend, IsGLES32OrAbove, "Independent blend is");
+ SET_FEATURE_STATE(DualSourceBlend, strstr(Extensions, "blend_func_extended"), "Dual source blend");
+ SET_FEATURE_STATE(MultiViewport, strstr(Extensions, "viewport_array"), "Multi viewport");
+ SET_FEATURE_STATE(PixelUAVWritesAndAtomics, IsGLES31OrAbove || strstr(Extensions, "shader_image_load_store"), "Pixel UAV writes and atomics");
+ SET_FEATURE_STATE(TextureUAVExtendedFormats, false, "Texture UAV extended formats");
+ // clang-format on
TexCaps.MaxTexture1DDimension = 0; // Not supported in GLES 3.2
TexCaps.MaxTexture1DArraySlices = 0; // Not supported in GLES 3.2
@@ -242,7 +287,9 @@ RenderDeviceGLImpl::RenderDeviceGLImpl(IReferenceCounters* pRefCounters,
const bool bBPTC = CheckExtension("GL_ARB_texture_compression_bptc");
const bool bS3TC = CheckExtension("GL_EXT_texture_compression_s3tc");
- Features.TextureCompressionBC = bRGTC && bBPTC && bS3TC;
+ SET_FEATURE_STATE(TextureCompressionBC, bRGTC && bBPTC && bS3TC, "BC texture compression is");
+
+#undef SET_FEATURE_STATE
}
RenderDeviceGLImpl::~RenderDeviceGLImpl()
@@ -945,28 +992,6 @@ void RenderDeviceGLImpl::TestTextureFormat(TEXTURE_FORMAT TexFormat)
}
}
-void RenderDeviceGLImpl::QueryDeviceCaps()
-{
- if (glPolygonMode == nullptr)
- m_DeviceCaps.Features.WireframeFill = false;
-
- if (m_DeviceCaps.Features.WireframeFill)
- {
- // Test glPolygonMode() function to check if it fails
- // (It does fail on NVidia Shield tablet, but works fine
- // on Intel hw)
- VERIFY(glGetError() == GL_NO_ERROR, "Unhandled gl error encountered");
- m_DeviceCaps.Features.WireframeFill = True;
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- if (glGetError() != GL_NO_ERROR)
- m_DeviceCaps.Features.WireframeFill = False;
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- if (glGetError() != GL_NO_ERROR)
- m_DeviceCaps.Features.WireframeFill = False;
- }
-}
-
-
FBOCache& RenderDeviceGLImpl::GetFBOCache(GLContext::NativeGLContextType Context)
{
ThreadingTools::LockHelper FBOCacheLock(m_FBOCacheLockFlag);
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
index 9f18c99c..caf198cd 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
@@ -67,7 +67,7 @@ public:
ICommandQueueVk** pCmdQueues,
std::shared_ptr<VulkanUtilities::VulkanInstance> Instance,
std::unique_ptr<VulkanUtilities::VulkanPhysicalDevice> PhysicalDevice,
- std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> LogicalDevice);
+ std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> LogicalDevice) noexcept(false);
~RenderDeviceVkImpl();
virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
index a2304bfe..4dee23de 100644
--- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
@@ -167,33 +167,58 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
DeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
DeviceCreateInfo.flags = 0; // Reserved for future use
// https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#extended-functionality-device-layer-deprecation
- DeviceCreateInfo.enabledLayerCount = 0; // Deprecated and ignored.
- DeviceCreateInfo.ppEnabledLayerNames = nullptr; // Deprecated and ignored
- DeviceCreateInfo.queueCreateInfoCount = 1;
- DeviceCreateInfo.pQueueCreateInfos = &QueueInfo;
- VkPhysicalDeviceFeatures DeviceFeatures = {};
-
-#define ENABLE_FEATURE(Feature) DeviceFeatures.Feature = PhysicalDeviceFeatures.Feature
- ENABLE_FEATURE(geometryShader);
- ENABLE_FEATURE(tessellationShader);
- ENABLE_FEATURE(pipelineStatisticsQuery);
- ENABLE_FEATURE(occlusionQueryPrecise);
- ENABLE_FEATURE(imageCubeArray);
- ENABLE_FEATURE(fillModeNonSolid);
- ENABLE_FEATURE(samplerAnisotropy);
- ENABLE_FEATURE(depthBiasClamp);
- ENABLE_FEATURE(depthClamp);
- ENABLE_FEATURE(independentBlend);
- ENABLE_FEATURE(dualSrcBlend);
- ENABLE_FEATURE(multiViewport);
- ENABLE_FEATURE(textureCompressionBC);
- ENABLE_FEATURE(vertexPipelineStoresAndAtomics);
- ENABLE_FEATURE(fragmentStoresAndAtomics);
- ENABLE_FEATURE(shaderStorageImageExtendedFormats);
+ DeviceCreateInfo.enabledLayerCount = 0; // Deprecated and ignored.
+ DeviceCreateInfo.ppEnabledLayerNames = nullptr; // Deprecated and ignored
+ DeviceCreateInfo.queueCreateInfoCount = 1;
+ DeviceCreateInfo.pQueueCreateInfos = &QueueInfo;
+ VkPhysicalDeviceFeatures EnabledFeatures = {};
+ EnabledFeatures.fullDrawIndexUint32 = PhysicalDeviceFeatures.fullDrawIndexUint32;
+
+#define ENABLE_FEATURE(Feature, RequestedState, FeatureName) \
+ do \
+ { \
+ switch (RequestedState) \
+ { \
+ case DEVICE_FEATURE_STATE_DISABLED: \
+ EnabledFeatures.Feature = VK_FALSE; \
+ break; \
+ case DEVICE_FEATURE_STATE_ENABLED: \
+ { \
+ if (PhysicalDeviceFeatures.Feature == VK_FALSE) \
+ LOG_ERROR_AND_THROW(FeatureName, " not supported by this device"); \
+ else \
+ EnabledFeatures.Feature = VK_TRUE; \
+ } \
+ break; \
+ case DEVICE_FEATURE_STATE_OPTIONAL: \
+ EnabledFeatures.Feature = PhysicalDeviceFeatures.Feature; \
+ break; \
+ default: UNEXPECTED("Unexpected feature state"); \
+ } \
+ } while (false)
+
+ // clang-format off
+ ENABLE_FEATURE(geometryShader, EngineCI.Features.GeometryShaders, "Geometry shaders are");
+ ENABLE_FEATURE(tessellationShader, EngineCI.Features.Tessellation, "Tessellation is");
+ ENABLE_FEATURE(pipelineStatisticsQuery, EngineCI.Features.PipelineStatisticsQueries, "Pipeline statistics queries are");
+ ENABLE_FEATURE(occlusionQueryPrecise, EngineCI.Features.OcclusionQueries, "Occlusion queries are");
+ ENABLE_FEATURE(imageCubeArray, DEVICE_FEATURE_STATE_OPTIONAL, "Image cube arrays");
+ ENABLE_FEATURE(fillModeNonSolid, EngineCI.Features.WireframeFill, "Wireframe fill is");
+ ENABLE_FEATURE(samplerAnisotropy, DEVICE_FEATURE_STATE_OPTIONAL, "Anisotropic texture filtering is");
+ ENABLE_FEATURE(depthBiasClamp, EngineCI.Features.DepthBiasClamp, "Depth bias clamp is");
+ ENABLE_FEATURE(depthClamp, EngineCI.Features.DepthClamp, "Depth clamp is");
+ ENABLE_FEATURE(independentBlend, EngineCI.Features.IndependentBlend, "Independent blend is");
+ ENABLE_FEATURE(dualSrcBlend, EngineCI.Features.DualSourceBlend, "Dual-source blend is");
+ ENABLE_FEATURE(multiViewport, EngineCI.Features.MultiViewport, "Multiviewport is");
+ ENABLE_FEATURE(textureCompressionBC, EngineCI.Features.TextureCompressionBC, "BC texture compression is");
+ ENABLE_FEATURE(vertexPipelineStoresAndAtomics, EngineCI.Features.VertexPipelineUAVWritesAndAtomics, "Vertex pipeline UAV writes and atomics are");
+ ENABLE_FEATURE(fragmentStoresAndAtomics, EngineCI.Features.PixelUAVWritesAndAtomics, "Pixel UAV writes and atomics are");
+ ENABLE_FEATURE(shaderStorageImageExtendedFormats, EngineCI.Features.TextureUAVExtendedFormats, "Texture UAV extended formats are");
+ // clang-format on
#undef ENABLE_FEATURE
- DeviceCreateInfo.pEnabledFeatures = &DeviceFeatures; // NULL or a pointer to a VkPhysicalDeviceFeatures structure that contains
- // boolean indicators of all the features to be enabled.
+ DeviceCreateInfo.pEnabledFeatures = &EnabledFeatures; // NULL or a pointer to a VkPhysicalDeviceFeatures structure that contains
+ // boolean indicators of all the features to be enabled.
std::vector<const char*> DeviceExtensions =
{
@@ -211,17 +236,26 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
(void)NextExt;
// Enable mesh shader extension.
+ bool MeshShadersSupported = false;
#ifdef VK_NV_mesh_shader
VkPhysicalDeviceMeshShaderFeaturesNV MeshShaderFeats = PhysicalDevice->GetExtFeatures().MeshShader;
if (SupportsFeatures2 && PhysicalDevice->IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME))
{
+ MeshShadersSupported = true;
DeviceExtensions.push_back(VK_NV_MESH_SHADER_EXTENSION_NAME);
*NextExt = &MeshShaderFeats;
NextExt = &MeshShaderFeats.pNext;
}
#endif
+ if (EngineCI.Features.MeshShaders == DEVICE_FEATURE_STATE_ENABLED && !MeshShadersSupported)
+ LOG_ERROR_AND_THROW("Mesh shaders are not supported by this device");
+
+#if defined(_MSC_VER) && defined(_WIN64)
+ static_assert(sizeof(DeviceFeatures) == 23, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+#endif
+
DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data();
DeviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(DeviceExtensions.size());
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index c619dc59..01ef7447 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -166,34 +166,43 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
// May be unused if extensions are disabled.
(void)(vkExtFeatures);
- Features.SeparablePrograms = True;
- Features.IndirectRendering = True;
- Features.WireframeFill = vkDeviceFeatures.fillModeNonSolid != VK_FALSE;
- Features.MultithreadedResourceCreation = True;
- Features.ComputeShaders = True;
- Features.GeometryShaders = vkDeviceFeatures.geometryShader != VK_FALSE;
- Features.Tessellation = vkDeviceFeatures.tessellationShader != VK_FALSE;
- Features.BindlessResources = True;
- Features.OcclusionQueries = vkDeviceFeatures.occlusionQueryPrecise != VK_FALSE;
- Features.BinaryOcclusionQueries = True;
- Features.TimestampQueries = True;
- Features.DurationQueries = True;
- Features.PipelineStatisticsQueries = vkDeviceFeatures.pipelineStatisticsQuery != VK_FALSE;
- Features.DepthBiasClamp = vkDeviceFeatures.depthBiasClamp != VK_FALSE;
- Features.DepthClamp = vkDeviceFeatures.depthClamp != VK_FALSE;
- Features.IndependentBlend = vkDeviceFeatures.independentBlend != VK_FALSE;
- Features.DualSourceBlend = vkDeviceFeatures.dualSrcBlend != VK_FALSE;
- Features.MultiViewport = vkDeviceFeatures.multiViewport != VK_FALSE;
- Features.TextureCompressionBC = vkDeviceFeatures.textureCompressionBC != VK_FALSE;
- Features.VertexPipelineUAVWritesAndAtomics = vkDeviceFeatures.vertexPipelineStoresAndAtomics != VK_FALSE;
- Features.PixelUAVWritesAndAtomics = vkDeviceFeatures.fragmentStoresAndAtomics != VK_FALSE;
- Features.TextureUAVExtendedFormats = vkDeviceFeatures.shaderStorageImageExtendedFormats != VK_FALSE;
+ auto GetFeatureState = [](VkBool32 vkFeatureState) //
+ {
+ return vkFeatureState != VK_FALSE ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED;
+ };
+
+ Features.SeparablePrograms = DEVICE_FEATURE_STATE_ENABLED;
+ Features.IndirectRendering = DEVICE_FEATURE_STATE_ENABLED;
+ Features.WireframeFill = GetFeatureState(vkDeviceFeatures.fillModeNonSolid);
+ Features.MultithreadedResourceCreation = DEVICE_FEATURE_STATE_ENABLED;
+ Features.ComputeShaders = DEVICE_FEATURE_STATE_ENABLED;
+ Features.GeometryShaders = GetFeatureState(vkDeviceFeatures.geometryShader);
+ Features.Tessellation = GetFeatureState(vkDeviceFeatures.tessellationShader);
+ Features.BindlessResources = DEVICE_FEATURE_STATE_ENABLED;
+ Features.OcclusionQueries = GetFeatureState(vkDeviceFeatures.occlusionQueryPrecise);
+ Features.BinaryOcclusionQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.TimestampQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.DurationQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.PipelineStatisticsQueries = GetFeatureState(vkDeviceFeatures.pipelineStatisticsQuery);
+ Features.DepthBiasClamp = GetFeatureState(vkDeviceFeatures.depthBiasClamp);
+ Features.DepthClamp = GetFeatureState(vkDeviceFeatures.depthClamp);
+ Features.IndependentBlend = GetFeatureState(vkDeviceFeatures.independentBlend);
+ Features.DualSourceBlend = GetFeatureState(vkDeviceFeatures.dualSrcBlend);
+ Features.MultiViewport = GetFeatureState(vkDeviceFeatures.multiViewport);
+ Features.TextureCompressionBC = GetFeatureState(vkDeviceFeatures.textureCompressionBC);
+ Features.VertexPipelineUAVWritesAndAtomics = GetFeatureState(vkDeviceFeatures.vertexPipelineStoresAndAtomics);
+ Features.PixelUAVWritesAndAtomics = GetFeatureState(vkDeviceFeatures.fragmentStoresAndAtomics);
+ Features.TextureUAVExtendedFormats = GetFeatureState(vkDeviceFeatures.shaderStorageImageExtendedFormats);
#ifdef VK_NV_mesh_shader
- // All devices that supports mesh shader also supports task shader, so it is not necessary to use two separate features.
- Features.MeshShaders = vkExtFeatures.MeshShader.meshShader != VK_FALSE && vkExtFeatures.MeshShader.taskShader != VK_FALSE;
+ // All devices that support mesh shaders also support task shaders, so it is not necessary to use two separate features.
+ Features.MeshShaders = GetFeatureState(vkExtFeatures.MeshShader.meshShader != VK_FALSE && vkExtFeatures.MeshShader.taskShader != VK_FALSE);
#else
- Features.MeshShaders = False;
+ Features.MeshShaders = DEVICE_FEATURE_STATE_DISABLED;
+#endif
+
+#if defined(_MSC_VER) && defined(_WIN64)
+ static_assert(sizeof(DeviceFeatures) == 23, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
const auto& vkDeviceLimits = m_PhysicalDevice->GetProperties().limits;