summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
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/GraphicsEngineVulkan
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/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp84
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp59
3 files changed, 94 insertions, 51 deletions
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;