Skip to content

Commit d67e526

Browse files
Added DeviceFeaturesVk struct (API256004)
1 parent 02f5802 commit d67e526

File tree

8 files changed

+136
-34
lines changed

8 files changed

+136
-34
lines changed

Graphics/GraphicsEngine/include/RenderDeviceBase.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ namespace Diligent
7272
DeviceFeatures EnableDeviceFeatures(const DeviceFeatures& SupportedFeatures,
7373
const DeviceFeatures& RequestedFeatures) noexcept(false);
7474

75+
DeviceFeaturesVk EnableDeviceFeaturesVk(const DeviceFeaturesVk& SupportedFeatures,
76+
const DeviceFeaturesVk& RequestedFeatures) noexcept(false);
77+
7578
/// Checks sparse texture format support and returns the component type
7679
COMPONENT_TYPE CheckSparseTextureFormatSupport(TEXTURE_FORMAT TexFormat,
7780
RESOURCE_DIMENSION Dimension,

Graphics/GraphicsEngine/interface/APIInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
/// \file
3131
/// Diligent API information
3232

33-
#define DILIGENT_API_VERSION 256003
33+
#define DILIGENT_API_VERSION 256004
3434

3535
#include "../../../Primitives/interface/BasicTypes.h"
3636

Graphics/GraphicsEngine/interface/GraphicsTypes.h

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -3931,9 +3931,57 @@ struct VulkanDescriptorPoolSize
39313931
typedef struct VulkanDescriptorPoolSize VulkanDescriptorPoolSize;
39323932

39333933

3934+
/// Vulkan-specific device features
3935+
struct DeviceFeaturesVk
3936+
{
3937+
/// Indicates whether the device supports VK_KHR_dynamic_rendering extension.
3938+
///
3939+
/// \remarks If the extension is not supported, dynamic render targets are implemented
3940+
/// using framebuffer and render pass caches.
3941+
DEVICE_FEATURE_STATE DynamicRendering DEFAULT_INITIALIZER(DEVICE_FEATURE_STATE_DISABLED);
3942+
3943+
3944+
#if DILIGENT_CPP_INTERFACE
3945+
constexpr DeviceFeaturesVk() noexcept {}
3946+
3947+
#define ENUMERATE_VK_DEVICE_FEATURES(Handler) \
3948+
Handler(DynamicRendering)
3949+
3950+
explicit constexpr DeviceFeaturesVk(DEVICE_FEATURE_STATE State) noexcept
3951+
{
3952+
static_assert(sizeof(*this) == 1, "Did you add a new feature to DeviceFeatures? Please add it to ENUMERATE_DEVICE_FEATURES.");
3953+
#define INIT_FEATURE(Feature) Feature = State;
3954+
ENUMERATE_VK_DEVICE_FEATURES(INIT_FEATURE)
3955+
#undef INIT_FEATURE
3956+
}
3957+
3958+
template <typename FeatType, typename HandlerType>
3959+
static void Enumerate(FeatType& Features, HandlerType&& Handler)
3960+
{
3961+
#define HandleFeature(Feature) \
3962+
if (!Handler(#Feature, Features.Feature)) \
3963+
return;
3964+
3965+
ENUMERATE_VK_DEVICE_FEATURES(HandleFeature)
3966+
3967+
#undef HandleFeature
3968+
}
3969+
3970+
/// Comparison operator tests if two structures are equivalent
3971+
bool operator == (const DeviceFeatures& RHS) const
3972+
{
3973+
return memcmp(this, &RHS, sizeof(DeviceFeatures)) == 0;
3974+
}
3975+
#endif
3976+
};
3977+
typedef struct DeviceFeaturesVk DeviceFeaturesVk;
3978+
39343979
/// Attributes specific to Vulkan engine
39353980
struct EngineVkCreateInfo DILIGENT_DERIVE(EngineCreateInfo)
39363981

3982+
/// Vulkan-specific device features, see Diligent::DeviceFeaturesVk.
3983+
DeviceFeaturesVk FeaturesVk;
3984+
39373985
/// The number of Vulkan instance layers in ppInstanceLayerNames array.
39383986
Uint32 InstanceLayerCount DEFAULT_INITIALIZER(0);
39393987

@@ -4113,7 +4161,8 @@ struct EngineVkCreateInfo DILIGENT_DERIVE(EngineCreateInfo)
41134161
{}
41144162

41154163
explicit EngineVkCreateInfo(const EngineCreateInfo &EngineCI) noexcept :
4116-
EngineCreateInfo{EngineCI}
4164+
EngineCreateInfo{EngineCI},
4165+
FeaturesVk{DEVICE_FEATURE_STATE_OPTIONAL}
41174166
{}
41184167
#endif
41194168
};

Graphics/GraphicsEngine/src/RenderDeviceBase.cpp

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,46 +30,47 @@
3030
namespace Diligent
3131
{
3232

33-
DeviceFeatures EnableDeviceFeatures(const DeviceFeatures& SupportedFeatures,
34-
const DeviceFeatures& RequestedFeatures) noexcept(false)
33+
static DEVICE_FEATURE_STATE GetFeatureState(DEVICE_FEATURE_STATE RequestedState, DEVICE_FEATURE_STATE SupportedState, const char* FeatureName) noexcept(false)
3534
{
36-
auto GetFeatureState = [](DEVICE_FEATURE_STATE RequestedState, DEVICE_FEATURE_STATE SupportedState, const char* FeatureName) //
35+
switch (RequestedState)
3736
{
38-
switch (RequestedState)
37+
case DEVICE_FEATURE_STATE_DISABLED:
38+
return SupportedState == DEVICE_FEATURE_STATE_ENABLED ?
39+
DEVICE_FEATURE_STATE_ENABLED : // the feature is supported by default and can not be disabled
40+
DEVICE_FEATURE_STATE_DISABLED;
41+
42+
case DEVICE_FEATURE_STATE_ENABLED:
3943
{
40-
case DEVICE_FEATURE_STATE_DISABLED:
41-
return SupportedState == DEVICE_FEATURE_STATE_ENABLED ?
42-
DEVICE_FEATURE_STATE_ENABLED : // the feature is supported by default and can not be disabled
43-
DEVICE_FEATURE_STATE_DISABLED;
44-
45-
case DEVICE_FEATURE_STATE_ENABLED:
46-
{
47-
if (SupportedState != DEVICE_FEATURE_STATE_DISABLED)
48-
return DEVICE_FEATURE_STATE_ENABLED;
49-
else
50-
LOG_ERROR_AND_THROW(FeatureName, " not supported by this device");
51-
}
52-
53-
case DEVICE_FEATURE_STATE_OPTIONAL:
54-
return SupportedState != DEVICE_FEATURE_STATE_DISABLED ?
55-
DEVICE_FEATURE_STATE_ENABLED :
56-
DEVICE_FEATURE_STATE_DISABLED;
57-
58-
default:
59-
UNEXPECTED("Unexpected feature state");
60-
return DEVICE_FEATURE_STATE_DISABLED;
44+
if (SupportedState != DEVICE_FEATURE_STATE_DISABLED)
45+
return DEVICE_FEATURE_STATE_ENABLED;
46+
else
47+
LOG_ERROR_AND_THROW(FeatureName, " not supported by this device");
6148
}
62-
};
6349

50+
case DEVICE_FEATURE_STATE_OPTIONAL:
51+
return SupportedState != DEVICE_FEATURE_STATE_DISABLED ?
52+
DEVICE_FEATURE_STATE_ENABLED :
53+
DEVICE_FEATURE_STATE_DISABLED;
54+
55+
default:
56+
UNEXPECTED("Unexpected feature state");
57+
return DEVICE_FEATURE_STATE_DISABLED;
58+
}
59+
};
60+
61+
#define ENABLE_FEATURE(Feature, FeatureName) \
62+
EnabledFeatures.Feature = GetFeatureState(RequestedFeatures.Feature, SupportedFeatures.Feature, FeatureName)
63+
64+
DeviceFeatures EnableDeviceFeatures(const DeviceFeatures& SupportedFeatures,
65+
const DeviceFeatures& RequestedFeatures) noexcept(false)
66+
{
6467
if (SupportedFeatures.SeparablePrograms == DEVICE_FEATURE_STATE_ENABLED &&
6568
RequestedFeatures.SeparablePrograms == DEVICE_FEATURE_STATE_DISABLED)
6669
{
6770
LOG_INFO_MESSAGE("Can not disable SeparablePrograms");
6871
}
6972

7073
DeviceFeatures EnabledFeatures;
71-
#define ENABLE_FEATURE(Feature, FeatureName) \
72-
EnabledFeatures.Feature = GetFeatureState(RequestedFeatures.Feature, SupportedFeatures.Feature, FeatureName)
7374

7475
// clang-format off
7576
ENABLE_FEATURE(SeparablePrograms, "Separable programs are");
@@ -120,13 +121,26 @@ DeviceFeatures EnableDeviceFeatures(const DeviceFeatures& SupportedFeatures,
120121
ENABLE_FEATURE(AsyncShaderCompilation, "Async shader compilation is");
121122
ENABLE_FEATURE(FormattedBuffers, "Formatted buffers are");
122123
// clang-format on
123-
#undef ENABLE_FEATURE
124124

125125
ASSERT_SIZEOF(DeviceFeatures, 47, "Did you add a new feature to DeviceFeatures? Please handle its status here (if necessary).");
126126

127127
return EnabledFeatures;
128128
}
129129

130+
DeviceFeaturesVk EnableDeviceFeaturesVk(const DeviceFeaturesVk& SupportedFeatures,
131+
const DeviceFeaturesVk& RequestedFeatures) noexcept(false)
132+
{
133+
DeviceFeaturesVk EnabledFeatures;
134+
135+
ENABLE_FEATURE(DynamicRendering, "VK_KHR_dynamic_rendering is");
136+
137+
ASSERT_SIZEOF(DeviceFeaturesVk, 1, "Did you add a new feature to DeviceFeaturesVk? Please handle its status here (if necessary).");
138+
139+
return EnabledFeatures;
140+
}
141+
142+
#undef ENABLE_FEATURE
143+
130144
COMPONENT_TYPE CheckSparseTextureFormatSupport(TEXTURE_FORMAT TexFormat,
131145
RESOURCE_DIMENSION Dimension,
132146
Uint32 SampleCount,

Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ DeviceFeatures VkFeaturesToDeviceFeatures(uint32_t
112112
const VulkanUtilities::VulkanPhysicalDevice::ExtensionProperties& ExtProps,
113113
DEVICE_FEATURE_STATE OptionalState = DEVICE_FEATURE_STATE_ENABLED);
114114

115+
DeviceFeaturesVk PhysicalDeviceFeaturesToDeviceFeaturesVk(const VulkanUtilities::VulkanPhysicalDevice::ExtensionFeatures& ExtFeatures,
116+
DEVICE_FEATURE_STATE OptionalState);
117+
115118
SPARSE_TEXTURE_FLAGS VkSparseImageFormatFlagsToSparseTextureFlags(VkSparseImageFormatFlags Flags);
116119

117120
VkImageUsageFlags BindFlagsToVkImageUsage(BIND_FLAGS Flags, bool IsMemoryless, bool FragDensityMapInsteadOfShadingRate);

Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,9 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& En
752752
// Enable device features if they are supported and throw an error if not supported, but required by user.
753753
const GraphicsAdapterInfo AdapterInfo = GetPhysicalDeviceGraphicsAdapterInfo(*PhysicalDevice);
754754
VerifyEngineCreateInfo(EngineCI, AdapterInfo);
755-
const DeviceFeatures EnabledFeatures = EnableDeviceFeatures(AdapterInfo.Features, EngineCI.Features);
755+
const DeviceFeatures EnabledFeatures = EnableDeviceFeatures(AdapterInfo.Features, EngineCI.Features);
756+
const DeviceFeaturesVk AdapterFeaturesVk = PhysicalDeviceFeaturesToDeviceFeaturesVk(PhysicalDevice->GetExtFeatures(), DEVICE_FEATURE_STATE_ENABLED);
757+
const DeviceFeaturesVk EnabledFeaturesVk = EnableDeviceFeaturesVk(AdapterFeaturesVk, EngineCI.FeaturesVk);
756758

757759
std::vector<VkDeviceQueueGlobalPriorityCreateInfoEXT> QueueGlobalPriority;
758760
std::vector<VkDeviceQueueCreateInfo> QueueInfos;
@@ -1233,6 +1235,17 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& En
12331235
NextExt = &EnabledExtFeats.ShaderDrawParameters.pNext;
12341236
}
12351237

1238+
if (EnabledFeaturesVk.DynamicRendering)
1239+
{
1240+
VERIFY_EXPR(PhysicalDevice->IsExtensionSupported(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME));
1241+
DeviceExtensions.push_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
1242+
1243+
EnabledExtFeats.DynamicRendering = DeviceExtFeatures.DynamicRendering;
1244+
1245+
*NextExt = &EnabledExtFeats.DynamicRendering;
1246+
NextExt = &EnabledExtFeats.DynamicRendering.pNext;
1247+
}
1248+
12361249
// Append user-defined features
12371250
*NextExt = EngineCI.pDeviceExtensionFeatures;
12381251
}

Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,6 +2059,25 @@ DeviceFeatures VkFeaturesToDeviceFeatures(uint32_t
20592059
return Features;
20602060
}
20612061

2062+
DeviceFeaturesVk PhysicalDeviceFeaturesToDeviceFeaturesVk(const VulkanUtilities::VulkanPhysicalDevice::ExtensionFeatures& ExtFeatures,
2063+
DEVICE_FEATURE_STATE OptionalState)
2064+
{
2065+
VERIFY_EXPR(OptionalState != DEVICE_FEATURE_STATE_DISABLED);
2066+
2067+
DeviceFeaturesVk FeaturesVk;
2068+
2069+
#define INIT_FEATURE(FeatureName, Supported) \
2070+
FeaturesVk.FeatureName = (Supported) ? OptionalState : DEVICE_FEATURE_STATE_DISABLED
2071+
2072+
INIT_FEATURE(DynamicRendering, ExtFeatures.DynamicRendering.dynamicRendering != VK_FALSE);
2073+
2074+
#undef INIT_FEATURE
2075+
2076+
ASSERT_SIZEOF(DeviceFeaturesVk, 1, "Did you add a new feature to DeviceFeaturesVk? Please handle its status here (if necessary).");
2077+
2078+
return FeaturesVk;
2079+
}
2080+
20622081
SPARSE_TEXTURE_FLAGS VkSparseImageFormatFlagsToSparseTextureFlags(VkSparseImageFormatFlags Flags)
20632082
{
20642083
SPARSE_TEXTURE_FLAGS Result = SPARSE_TEXTURE_FLAG_NONE;

ReleaseHistory.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## Current progress
22

3+
* Added `DeviceFeaturesVk` struct and `EngineVkCreateInfo::FeaturesVk` member (API256004)
34
* Removed `DRAW_FLAG_VERIFY_RENDER_TARGETS` flag (API256003)
45
* The validation uses render target formats hash, which allows detecting format mismatches
56
without overhead.

0 commit comments

Comments
 (0)