summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-10-03 04:14:03 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-10-03 04:14:03 +0000
commit2f344b7eb5527b2449f1ad0dc2a9e42ac2542b76 (patch)
treec913e8d0b7343cab19de6f1643564e30f89b77b9 /Graphics/GraphicsEngineVulkan
parentMetal interface: using id<> instead of void* (diff)
downloadDiligentCore-2f344b7eb5527b2449f1ad0dc2a9e42ac2542b76.tar.gz
DiligentCore-2f344b7eb5527b2449f1ad0dc2a9e42ac2542b76.zip
Added device features to indicate support of 16-bit types
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp156
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp58
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp23
4 files changed, 157 insertions, 84 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
index 215feb1a..848055eb 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
@@ -39,7 +39,9 @@ class VulkanPhysicalDevice
public:
struct ExtensionFeatures
{
- VkPhysicalDeviceMeshShaderFeaturesNV MeshShader = {};
+ VkPhysicalDeviceMeshShaderFeaturesNV MeshShader = {};
+ VkPhysicalDevice16BitStorageFeaturesKHR Storage16Bit = {};
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR ShaderFloat16Int8 = {};
};
public:
diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
index 5261235a..04bc3a1f 100644
--- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
@@ -174,37 +174,49 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
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"); \
- } \
+ auto GetFeatureState = [&](DEVICE_FEATURE_STATE RequestedState, bool IsFeatureSupported, const char* FeatureName) //
+ {
+ switch (RequestedState)
+ {
+ case DEVICE_FEATURE_STATE_DISABLED:
+ return DEVICE_FEATURE_STATE_DISABLED;
+
+ case DEVICE_FEATURE_STATE_ENABLED:
+ {
+ if (IsFeatureSupported)
+ return DEVICE_FEATURE_STATE_ENABLED;
+ else
+ LOG_ERROR_AND_THROW(FeatureName, " not supported by this device");
+ }
+
+ case DEVICE_FEATURE_STATE_OPTIONAL:
+ return IsFeatureSupported ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED;
+
+ default:
+ UNEXPECTED("Unexpected feature state");
+ return DEVICE_FEATURE_STATE_DISABLED;
+ }
+ };
+
+#define ENABLE_FEATURE(vkFeature, State, FeatureName) \
+ do \
+ { \
+ State = \
+ GetFeatureState(State, PhysicalDeviceFeatures.vkFeature != VK_FALSE, FeatureName); \
+ EnabledFeatures.vkFeature = \
+ State == DEVICE_FEATURE_STATE_ENABLED ? VK_TRUE : VK_FALSE; \
} while (false)
+ auto ImageCubeArrayFeature = DEVICE_FEATURE_STATE_OPTIONAL;
+ auto SamplerAnisotropyFeature = DEVICE_FEATURE_STATE_OPTIONAL;
// 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(imageCubeArray, ImageCubeArrayFeature, "Image cube arrays are");
ENABLE_FEATURE(fillModeNonSolid, EngineCI.Features.WireframeFill, "Wireframe fill is");
- ENABLE_FEATURE(samplerAnisotropy, DEVICE_FEATURE_STATE_OPTIONAL, "Anisotropic texture filtering is");
+ ENABLE_FEATURE(samplerAnisotropy, SamplerAnisotropyFeature, "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");
@@ -226,37 +238,103 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
VK_KHR_MAINTENANCE1_EXTENSION_NAME // To allow negative viewport height
};
+ const auto& DeiceExtFeatures = PhysicalDevice->GetExtFeatures();
+
+#define ENABLE_FEATURE(IsFeatureSupported, Feature, FeatureName) \
+ do \
+ { \
+ EngineCI.Features.Feature = \
+ GetFeatureState(EngineCI.Features.Feature, IsFeatureSupported, FeatureName); \
+ } while (false)
+
+
+ auto MeshShaderFeats = DeiceExtFeatures.MeshShader;
+ ENABLE_FEATURE(MeshShaderFeats.taskShader != VK_FALSE && MeshShaderFeats.meshShader != VK_FALSE, MeshShaders, "Mesh shaders are");
+
+ auto ShaderFloat16Int8 = DeiceExtFeatures.ShaderFloat16Int8;
+ ENABLE_FEATURE(ShaderFloat16Int8.shaderFloat16 != VK_FALSE, ShaderFloat16, "16-bit float shader operations are");
+
+ auto Storage16BitFeats = DeiceExtFeatures.Storage16Bit;
+ // clang-format off
+ ENABLE_FEATURE(Storage16BitFeats.storageBuffer16BitAccess != VK_FALSE, ResourceBuffer16BitAccess, "16-bit resoure buffer access is");
+ ENABLE_FEATURE(Storage16BitFeats.uniformAndStorageBuffer16BitAccess != VK_FALSE, UniformBuffer16BitAccess, "16-bit uniform buffer access is");
+ ENABLE_FEATURE(Storage16BitFeats.storageInputOutput16 != VK_FALSE, ShaderInputOutput16, "16-bit shader inputs/outputs are");
+ // clang-format on
+#undef FeatureSupport
+
+
// To enable some device extensions you must enable instance extension VK_KHR_get_physical_device_properties2
// and add feature description to DeviceCreateInfo.pNext.
const auto SupportsFeatures2 = Instance->IsExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
-
- // Enable mesh shader extension.
- bool MeshShadersSupported = false;
- VkPhysicalDeviceMeshShaderFeaturesNV MeshShaderFeats = {};
if (SupportsFeatures2)
{
void** NextExt = const_cast<void**>(&DeviceCreateInfo.pNext);
if (EngineCI.Features.MeshShaders != DEVICE_FEATURE_STATE_DISABLED)
{
- MeshShaderFeats = PhysicalDevice->GetExtFeatures().MeshShader;
- MeshShadersSupported = MeshShaderFeats.taskShader != VK_FALSE && MeshShaderFeats.meshShader != VK_FALSE;
- if (PhysicalDevice->IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME) && MeshShadersSupported)
- {
- DeviceExtensions.push_back(VK_NV_MESH_SHADER_EXTENSION_NAME);
- *NextExt = &MeshShaderFeats;
- NextExt = &MeshShaderFeats.pNext;
- }
+ VERIFY_EXPR(MeshShaderFeats.taskShader != VK_FALSE && MeshShaderFeats.meshShader != VK_FALSE);
+ VERIFY(PhysicalDevice->IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME),
+ "VK_NV_mesh_shader extension must be supported as it has already been checked by VulkanPhysicalDevice and "
+ "both taskShader and meshShader features are TRUE");
+ DeviceExtensions.push_back(VK_NV_MESH_SHADER_EXTENSION_NAME);
+ *NextExt = &MeshShaderFeats;
+ NextExt = &MeshShaderFeats.pNext;
}
+
+ if (EngineCI.Features.ShaderFloat16 != DEVICE_FEATURE_STATE_DISABLED)
+ {
+ VERIFY_EXPR(ShaderFloat16Int8.shaderFloat16 != VK_FALSE);
+ VERIFY(PhysicalDevice->IsExtensionSupported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME),
+ "VK_KHR_shader_float16_int8 extension must be supported as it has already been checked by VulkanPhysicalDevice "
+ "and shaderFloat16 feature is TRUE");
+ DeviceExtensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
+
+ *NextExt = &ShaderFloat16Int8;
+ NextExt = &ShaderFloat16Int8.pNext;
+ }
+
+ // clang-format off
+ if (EngineCI.Features.ResourceBuffer16BitAccess != DEVICE_FEATURE_STATE_DISABLED ||
+ EngineCI.Features.UniformBuffer16BitAccess != DEVICE_FEATURE_STATE_DISABLED ||
+ EngineCI.Features.ShaderInputOutput16 != DEVICE_FEATURE_STATE_DISABLED)
+ // clang-format on
+ {
+ // clang-format off
+ VERIFY_EXPR(EngineCI.Features.ResourceBuffer16BitAccess == DEVICE_FEATURE_STATE_DISABLED || Storage16BitFeats.storageBuffer16BitAccess != VK_FALSE);
+ VERIFY_EXPR(EngineCI.Features.UniformBuffer16BitAccess == DEVICE_FEATURE_STATE_DISABLED || Storage16BitFeats.uniformAndStorageBuffer16BitAccess != VK_FALSE);
+ VERIFY_EXPR(EngineCI.Features.ShaderInputOutput16 == DEVICE_FEATURE_STATE_DISABLED || Storage16BitFeats.storageInputOutput16 != VK_FALSE);
+ // clang-format on
+
+ VERIFY(PhysicalDevice->IsExtensionSupported(VK_KHR_16BIT_STORAGE_EXTENSION_NAME),
+ "VK_KHR_16bit_storage must be supported as it has already been checked by VulkanPhysicalDevice and at least one of "
+ "storageBuffer16BitAccess, uniformAndStorageBuffer16BitAccess, or storagePushConstant16 features is TRUE");
+ DeviceExtensions.push_back(VK_KHR_16BIT_STORAGE_EXTENSION_NAME);
+
+ // VK_KHR_16bit_storage extension requires VK_KHR_storage_buffer_storage_class extension.
+ // All required extensions for each extension in the VkDeviceCreateInfo::ppEnabledExtensionNames
+ // list must also be present in that list.
+ VERIFY(PhysicalDevice->IsExtensionSupported(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME),
+ "VK_KHR_storage_buffer_storage_class must be supported as it has already been checked by VulkanPhysicalDevice and at least one of "
+ "storageBuffer16BitAccess, uniformAndStorageBuffer16BitAccess, or storagePushConstant16 features is TRUE");
+ DeviceExtensions.push_back(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
+
+ if (EngineCI.Features.ResourceBuffer16BitAccess == DEVICE_FEATURE_STATE_DISABLED)
+ Storage16BitFeats.storageBuffer16BitAccess = VK_FALSE;
+ if (EngineCI.Features.UniformBuffer16BitAccess == DEVICE_FEATURE_STATE_DISABLED)
+ Storage16BitFeats.uniformAndStorageBuffer16BitAccess = VK_FALSE;
+ if (EngineCI.Features.ShaderInputOutput16 == DEVICE_FEATURE_STATE_DISABLED)
+ Storage16BitFeats.storageInputOutput16 = VK_FALSE;
+
+ *NextExt = &Storage16BitFeats;
+ NextExt = &Storage16BitFeats.pNext;
+ }
+
*NextExt = nullptr;
}
- if (EngineCI.Features.MeshShaders == DEVICE_FEATURE_STATE_ENABLED && !MeshShadersSupported)
- LOG_ERROR_AND_THROW("Mesh shaders are not supported by this device");
- // The actual state of Features.MeshShaders in device caps is set by RenderDeviceVkImpl
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 23, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 27, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
DeviceCreateInfo.ppEnabledExtensionNames = DeviceExtensions.empty() ? nullptr : DeviceExtensions.data();
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index 2d679e21..204aaa74 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -206,51 +206,27 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
for (Uint32 fmt = 1; fmt < m_TextureFormatsInfo.size(); ++fmt)
m_TextureFormatsInfo[fmt].Supported = true; // We will test every format on a specific hardware device
- auto& Features = m_DeviceCaps.Features;
- const auto& vkExtFeatures = m_PhysicalDevice->GetExtFeatures();
-
- // May be unused if extensions are disabled.
- (void)(vkExtFeatures);
-
- const auto& vkEnabledFeatures = m_LogicalVkDevice->GetEnabledFeatures();
-
- 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(vkEnabledFeatures.fillModeNonSolid);
- Features.MultithreadedResourceCreation = DEVICE_FEATURE_STATE_ENABLED;
- Features.ComputeShaders = DEVICE_FEATURE_STATE_ENABLED;
- Features.GeometryShaders = GetFeatureState(vkEnabledFeatures.geometryShader);
- Features.Tessellation = GetFeatureState(vkEnabledFeatures.tessellationShader);
- Features.BindlessResources = DEVICE_FEATURE_STATE_ENABLED;
- Features.OcclusionQueries = GetFeatureState(vkEnabledFeatures.occlusionQueryPrecise);
- Features.BinaryOcclusionQueries = DEVICE_FEATURE_STATE_ENABLED;
- Features.TimestampQueries = DEVICE_FEATURE_STATE_ENABLED;
- Features.DurationQueries = DEVICE_FEATURE_STATE_ENABLED;
- Features.PipelineStatisticsQueries = GetFeatureState(vkEnabledFeatures.pipelineStatisticsQuery);
- Features.DepthBiasClamp = GetFeatureState(vkEnabledFeatures.depthBiasClamp);
- Features.DepthClamp = GetFeatureState(vkEnabledFeatures.depthClamp);
- Features.IndependentBlend = GetFeatureState(vkEnabledFeatures.independentBlend);
- Features.DualSourceBlend = GetFeatureState(vkEnabledFeatures.dualSrcBlend);
- Features.MultiViewport = GetFeatureState(vkEnabledFeatures.multiViewport);
- Features.TextureCompressionBC = GetFeatureState(vkEnabledFeatures.textureCompressionBC);
- Features.VertexPipelineUAVWritesAndAtomics = GetFeatureState(vkEnabledFeatures.vertexPipelineStoresAndAtomics);
- Features.PixelUAVWritesAndAtomics = GetFeatureState(vkEnabledFeatures.fragmentStoresAndAtomics);
- Features.TextureUAVExtendedFormats = GetFeatureState(vkEnabledFeatures.shaderStorageImageExtendedFormats);
-
- // All devices that support mesh shaders also support task shaders, so it is not necessary to use two separate features.
- Features.MeshShaders = GetFeatureState(EngineCI.Features.MeshShaders != DEVICE_FEATURE_STATE_DISABLED && vkExtFeatures.MeshShader.meshShader != VK_FALSE && vkExtFeatures.MeshShader.taskShader != VK_FALSE);
+ auto& Features = m_DeviceCaps.Features;
+ Features = EngineCI.Features;
+
+ // The following features are always enabled
+ Features.SeparablePrograms = DEVICE_FEATURE_STATE_ENABLED;
+ Features.IndirectRendering = DEVICE_FEATURE_STATE_ENABLED;
+ Features.MultithreadedResourceCreation = DEVICE_FEATURE_STATE_ENABLED;
+ Features.ComputeShaders = DEVICE_FEATURE_STATE_ENABLED;
+ Features.BindlessResources = DEVICE_FEATURE_STATE_ENABLED;
+ Features.BinaryOcclusionQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.TimestampQueries = DEVICE_FEATURE_STATE_ENABLED;
+ Features.DurationQueries = DEVICE_FEATURE_STATE_ENABLED;
#if defined(_MSC_VER) && defined(_WIN64)
- static_assert(sizeof(DeviceFeatures) == 23, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
+ static_assert(sizeof(DeviceFeatures) == 27, "Did you add a new feature to DeviceFeatures? Please handle its satus here.");
#endif
- const auto& vkDeviceLimits = m_PhysicalDevice->GetProperties().limits;
- auto& TexCaps = m_DeviceCaps.TexCaps;
+ const auto& vkDeviceLimits = m_PhysicalDevice->GetProperties().limits;
+ const auto& vkEnabledFeatures = m_LogicalVkDevice->GetEnabledFeatures();
+
+ auto& TexCaps = m_DeviceCaps.TexCaps;
TexCaps.MaxTexture1DDimension = vkDeviceLimits.maxImageDimension1D;
TexCaps.MaxTexture1DArraySlices = vkDeviceLimits.maxImageArrayLayers;
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
index 66cf94c2..9b15f74b 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
@@ -74,13 +74,30 @@ VulkanPhysicalDevice::VulkanPhysicalDevice(VkPhysicalDevice vkDevice,
VkPhysicalDeviceFeatures2 Feats2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
VkPhysicalDeviceProperties2 Props2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
void** NextFeat = &Feats2.pNext;
- (void)NextFeat;
+
+ if (IsExtensionSupported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME))
+ {
+ *NextFeat = &m_ExtFeatures.ShaderFloat16Int8;
+ NextFeat = &m_ExtFeatures.ShaderFloat16Int8.pNext;
+
+ m_ExtFeatures.ShaderFloat16Int8.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
+ }
+
+ // VK_KHR_16bit_storage extension requires VK_KHR_storage_buffer_storage_class extension.
+ if (IsExtensionSupported(VK_KHR_16BIT_STORAGE_EXTENSION_NAME) && IsExtensionSupported(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME))
+ {
+ *NextFeat = &m_ExtFeatures.Storage16Bit;
+ NextFeat = &m_ExtFeatures.Storage16Bit.pNext;
+
+ m_ExtFeatures.Storage16Bit.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
+ }
// Enable mesh shader extension.
if (IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME))
{
- *NextFeat = &m_ExtFeatures.MeshShader;
- NextFeat = &m_ExtFeatures.MeshShader.pNext;
+ *NextFeat = &m_ExtFeatures.MeshShader;
+ NextFeat = &m_ExtFeatures.MeshShader.pNext;
+
m_ExtFeatures.MeshShader.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV;
}