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();