Skip to content

Commit

Permalink
Refactor physical device feature query.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
c0d1f1ed committed Nov 14, 2018
1 parent ae8d464 commit d5f1489
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 60 deletions.
71 changes: 14 additions & 57 deletions src/Vulkan/VkPhysicalDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,63 +310,20 @@ void PhysicalDevice::getProperties(VkPhysicalDeviceSubgroupProperties* propertie

bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const
{
const VkPhysicalDeviceFeatures& availableFeatures = getFeatures();

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

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
Expand Down
8 changes: 5 additions & 3 deletions src/Vulkan/libVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,12 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c

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

0 comments on commit d5f1489

Please sign in to comment.