diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-09-13 03:17:35 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-09-13 03:17:35 +0000 |
| commit | 83acbd6c353255f478164018a357637fb2f11cb5 (patch) | |
| tree | c685b67b63185cd47d397a0d2dc423c9a8032421 /Graphics/GraphicsEngineVulkan | |
| parent | Fixed shader error log + fixed tests in Win8.1 (diff) | |
| download | DiligentCore-83acbd6c353255f478164018a357637fb2f11cb5.tar.gz DiligentCore-83acbd6c353255f478164018a357637fb2f11cb5.zip | |
Added option to enable/disable device features during initialization (API 240069)
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
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; |
