Refactor physical device feature query. VkPhysicalDeviceFeatures only contains VkBool32 members, and is also described by the spec as a "structure that contains boolean indicators of all the features to be enabled", as well as "For each feature, a value of VK_TRUE specifies that the feature is supported on this physical device, and VK_FALSE specifies that the feature is not supported". Hence we can safely process it as an array of VkBool32. This is also more likely to return false early when a requested feature is not supported. Bug b/117974925 Change-Id: I106ba6abf5f29874cde91fdaafd1dd9560aabfa9 Reviewed-on: https://swiftshader-review.googlesource.com/c/22512 Tested-by: Nicolas Capens <nicolascapens@google.com> Reviewed-by: Corentin Wallez <cwallez@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp index 7dbd4ef..46486bb 100644 --- a/src/Vulkan/VkPhysicalDevice.cpp +++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -310,63 +310,20 @@ bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const { - const VkPhysicalDeviceFeatures& availableFeatures = getFeatures(); + const VkPhysicalDeviceFeatures& supportedFeatures = getFeatures(); + const VkBool32* supportedFeature = reinterpret_cast<const VkBool32*>(&supportedFeatures); + const VkBool32* requestedFeature = reinterpret_cast<const VkBool32*>(&requestedFeatures); + constexpr auto featureCount = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); - return (!requestedFeatures.robustBufferAccess || availableFeatures.robustBufferAccess) && - (!requestedFeatures.fullDrawIndexUint32 || availableFeatures.fullDrawIndexUint32) && - (!requestedFeatures.imageCubeArray || availableFeatures.imageCubeArray) && - (!requestedFeatures.independentBlend || availableFeatures.independentBlend) && - (!requestedFeatures.geometryShader || availableFeatures.geometryShader) && - (!requestedFeatures.tessellationShader || availableFeatures.tessellationShader) && - (!requestedFeatures.sampleRateShading || availableFeatures.sampleRateShading) && - (!requestedFeatures.dualSrcBlend || availableFeatures.dualSrcBlend) && - (!requestedFeatures.logicOp || availableFeatures.logicOp) && - (!requestedFeatures.multiDrawIndirect || availableFeatures.multiDrawIndirect) && - (!requestedFeatures.drawIndirectFirstInstance || availableFeatures.drawIndirectFirstInstance) && - (!requestedFeatures.depthClamp || availableFeatures.depthClamp) && - (!requestedFeatures.depthBiasClamp || availableFeatures.depthBiasClamp) && - (!requestedFeatures.fillModeNonSolid || availableFeatures.fillModeNonSolid) && - (!requestedFeatures.depthBounds || availableFeatures.depthBounds) && - (!requestedFeatures.wideLines || availableFeatures.wideLines) && - (!requestedFeatures.largePoints || availableFeatures.largePoints) && - (!requestedFeatures.alphaToOne || availableFeatures.alphaToOne) && - (!requestedFeatures.multiViewport || availableFeatures.multiViewport) && - (!requestedFeatures.samplerAnisotropy || availableFeatures.samplerAnisotropy) && - (!requestedFeatures.textureCompressionETC2 || availableFeatures.textureCompressionETC2) && - (!requestedFeatures.textureCompressionASTC_LDR || availableFeatures.textureCompressionASTC_LDR) && - (!requestedFeatures.textureCompressionBC || availableFeatures.textureCompressionBC) && - (!requestedFeatures.occlusionQueryPrecise || availableFeatures.occlusionQueryPrecise) && - (!requestedFeatures.pipelineStatisticsQuery || availableFeatures.pipelineStatisticsQuery) && - (!requestedFeatures.vertexPipelineStoresAndAtomics || availableFeatures.vertexPipelineStoresAndAtomics) && - (!requestedFeatures.fragmentStoresAndAtomics || availableFeatures.fragmentStoresAndAtomics) && - (!requestedFeatures.shaderTessellationAndGeometryPointSize || availableFeatures.shaderTessellationAndGeometryPointSize) && - (!requestedFeatures.shaderImageGatherExtended || availableFeatures.shaderImageGatherExtended) && - (!requestedFeatures.shaderStorageImageExtendedFormats || availableFeatures.shaderStorageImageExtendedFormats) && - (!requestedFeatures.shaderStorageImageMultisample || availableFeatures.shaderStorageImageMultisample) && - (!requestedFeatures.shaderStorageImageReadWithoutFormat || availableFeatures.shaderStorageImageReadWithoutFormat) && - (!requestedFeatures.shaderStorageImageWriteWithoutFormat || availableFeatures.shaderStorageImageWriteWithoutFormat) && - (!requestedFeatures.shaderUniformBufferArrayDynamicIndexing || availableFeatures.shaderUniformBufferArrayDynamicIndexing) && - (!requestedFeatures.shaderSampledImageArrayDynamicIndexing || availableFeatures.shaderSampledImageArrayDynamicIndexing) && - (!requestedFeatures.shaderStorageBufferArrayDynamicIndexing || availableFeatures.shaderStorageBufferArrayDynamicIndexing) && - (!requestedFeatures.shaderStorageImageArrayDynamicIndexing || availableFeatures.shaderStorageImageArrayDynamicIndexing) && - (!requestedFeatures.shaderClipDistance || availableFeatures.shaderClipDistance) && - (!requestedFeatures.shaderCullDistance || availableFeatures.shaderCullDistance) && - (!requestedFeatures.shaderFloat64 || availableFeatures.shaderFloat64) && - (!requestedFeatures.shaderInt64 || availableFeatures.shaderInt64) && - (!requestedFeatures.shaderInt16 || availableFeatures.shaderInt16) && - (!requestedFeatures.shaderResourceResidency || availableFeatures.shaderResourceResidency) && - (!requestedFeatures.shaderResourceMinLod || availableFeatures.shaderResourceMinLod) && - (!requestedFeatures.sparseBinding || availableFeatures.sparseBinding) && - (!requestedFeatures.sparseResidencyBuffer || availableFeatures.sparseResidencyBuffer) && - (!requestedFeatures.sparseResidencyImage2D || availableFeatures.sparseResidencyImage2D) && - (!requestedFeatures.sparseResidencyImage3D || availableFeatures.sparseResidencyImage3D) && - (!requestedFeatures.sparseResidency2Samples || availableFeatures.sparseResidency2Samples) && - (!requestedFeatures.sparseResidency4Samples || availableFeatures.sparseResidency4Samples) && - (!requestedFeatures.sparseResidency8Samples || availableFeatures.sparseResidency8Samples) && - (!requestedFeatures.sparseResidency16Samples || availableFeatures.sparseResidency16Samples) && - (!requestedFeatures.sparseResidencyAliased || availableFeatures.sparseResidencyAliased) && - (!requestedFeatures.variableMultisampleRate || availableFeatures.variableMultisampleRate) && - (!requestedFeatures.inheritedQueries || availableFeatures.inheritedQueries); + for(unsigned int i = 0; i < featureCount; i++) + { + if((requestedFeature[i] == VK_TRUE) && (supportedFeature[i] != VK_TRUE)) + { + return false; + } + } + + return true; } void PhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties) const
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp index 92eba8b..035379b 100644 --- a/src/Vulkan/libVulkan.cpp +++ b/src/Vulkan/libVulkan.cpp
@@ -214,10 +214,12 @@ ASSERT(pCreateInfo->queueCreateInfoCount > 0); - if(pCreateInfo->pEnabledFeatures && - !vk::Cast(physicalDevice)->hasFeatures(*(pCreateInfo->pEnabledFeatures))) + if(pCreateInfo->pEnabledFeatures) { - return VK_ERROR_FEATURE_NOT_PRESENT; + if(!vk::Cast(physicalDevice)->hasFeatures(*(pCreateInfo->pEnabledFeatures))) + { + return VK_ERROR_FEATURE_NOT_PRESENT; + } } uint32_t queueFamilyPropertyCount = vk::Cast(physicalDevice)->getQueueFamilyPropertyCount();