blob: 049ec97db6ecaffd4cade1d5fa4284f89f380e77 [file] [log] [blame]
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VkPhysicalDevice.hpp"
#include "VkConfig.hpp"
#include "VkStringify.hpp"
#include "Pipeline/SpirvShader.hpp" // sw::SIMD::Width
#include "Reactor/Reactor.hpp"
#include <cstring>
#include <limits>
#ifdef __ANDROID__
# include <android/hardware_buffer.h>
#endif
namespace vk {
PhysicalDevice::PhysicalDevice(const void *, void *mem)
{
}
const VkPhysicalDeviceFeatures &PhysicalDevice::getFeatures() const
{
static const VkPhysicalDeviceFeatures features{
VK_TRUE, // robustBufferAccess
VK_TRUE, // fullDrawIndexUint32
VK_TRUE, // imageCubeArray
VK_TRUE, // independentBlend
VK_FALSE, // geometryShader
VK_FALSE, // tessellationShader
VK_TRUE, // sampleRateShading
VK_FALSE, // dualSrcBlend
VK_FALSE, // logicOp
VK_TRUE, // multiDrawIndirect
VK_TRUE, // drawIndirectFirstInstance
VK_TRUE, // depthClamp
VK_TRUE, // depthBiasClamp
VK_TRUE, // fillModeNonSolid
VK_TRUE, // depthBounds
VK_FALSE, // wideLines
VK_TRUE, // largePoints
VK_FALSE, // alphaToOne
VK_FALSE, // multiViewport
VK_TRUE, // samplerAnisotropy
VK_TRUE, // textureCompressionETC2
#ifdef SWIFTSHADER_ENABLE_ASTC
VK_TRUE, // textureCompressionASTC_LDR
#else
VK_FALSE, // textureCompressionASTC_LDR
#endif
VK_TRUE, // textureCompressionBC
VK_TRUE, // occlusionQueryPrecise
VK_FALSE, // pipelineStatisticsQuery
VK_TRUE, // vertexPipelineStoresAndAtomics
VK_TRUE, // fragmentStoresAndAtomics
VK_FALSE, // shaderTessellationAndGeometryPointSize
VK_FALSE, // shaderImageGatherExtended
VK_TRUE, // shaderStorageImageExtendedFormats
VK_TRUE, // shaderStorageImageMultisample
VK_FALSE, // shaderStorageImageReadWithoutFormat
VK_TRUE, // shaderStorageImageWriteWithoutFormat
VK_TRUE, // shaderUniformBufferArrayDynamicIndexing
VK_TRUE, // shaderSampledImageArrayDynamicIndexing
VK_TRUE, // shaderStorageBufferArrayDynamicIndexing
VK_TRUE, // shaderStorageImageArrayDynamicIndexing
VK_TRUE, // shaderClipDistance
VK_TRUE, // shaderCullDistance
VK_FALSE, // shaderFloat64
VK_FALSE, // shaderInt64
VK_FALSE, // shaderInt16
VK_FALSE, // shaderResourceResidency
VK_FALSE, // shaderResourceMinLod
VK_FALSE, // sparseBinding
VK_FALSE, // sparseResidencyBuffer
VK_FALSE, // sparseResidencyImage2D
VK_FALSE, // sparseResidencyImage3D
VK_FALSE, // sparseResidency2Samples
VK_FALSE, // sparseResidency4Samples
VK_FALSE, // sparseResidency8Samples
VK_FALSE, // sparseResidency16Samples
VK_FALSE, // sparseResidencyAliased
VK_TRUE, // variableMultisampleRate
VK_FALSE, // inheritedQueries
};
return features;
}
template<typename T>
static void getPhysicalDeviceSamplerYcbcrConversionFeatures(T *features)
{
features->samplerYcbcrConversion = VK_TRUE;
}
template<typename T>
static void getPhysicalDevice16BitStorageFeatures(T *features)
{
features->storageBuffer16BitAccess = VK_FALSE;
features->storageInputOutput16 = VK_FALSE;
features->storagePushConstant16 = VK_FALSE;
features->uniformAndStorageBuffer16BitAccess = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceVariablePointersFeatures(T *features)
{
features->variablePointersStorageBuffer = VK_FALSE;
features->variablePointers = VK_FALSE;
}
template<typename T>
static void getPhysicalDevice8BitStorageFeaturesKHR(T *features)
{
features->storageBuffer8BitAccess = VK_FALSE;
features->uniformAndStorageBuffer8BitAccess = VK_FALSE;
features->storagePushConstant8 = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceMultiviewFeatures(T *features)
{
features->multiview = VK_TRUE;
features->multiviewGeometryShader = VK_FALSE;
features->multiviewTessellationShader = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceProtectedMemoryFeatures(T *features)
{
features->protectedMemory = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceShaderDrawParameterFeatures(T *features)
{
features->shaderDrawParameters = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR(T *features)
{
features->separateDepthStencilLayouts = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceLineRasterizationFeaturesEXT(T *features)
{
features->rectangularLines = VK_TRUE;
features->bresenhamLines = VK_TRUE;
features->smoothLines = VK_FALSE;
features->stippledRectangularLines = VK_FALSE;
features->stippledBresenhamLines = VK_FALSE;
features->stippledSmoothLines = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceProvokingVertexFeaturesEXT(T *features)
{
features->provokingVertexLast = VK_TRUE;
features->transformFeedbackPreservesProvokingVertex = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceHostQueryResetFeatures(T *features)
{
features->hostQueryReset = VK_TRUE;
}
template<typename T>
static void getPhysicalDevicePipelineCreationCacheControlFeatures(T *features)
{
features->pipelineCreationCacheControl = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceImageRobustnessFeatures(T *features)
{
features->robustImageAccess = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceShaderDrawParametersFeatures(T *features)
{
features->shaderDrawParameters = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceVulkan11Features(T *features)
{
getPhysicalDevice16BitStorageFeatures(features);
getPhysicalDeviceMultiviewFeatures(features);
getPhysicalDeviceVariablePointersFeatures(features);
getPhysicalDeviceProtectedMemoryFeatures(features);
getPhysicalDeviceSamplerYcbcrConversionFeatures(features);
getPhysicalDeviceShaderDrawParametersFeatures(features);
}
template<typename T>
static void getPhysicalDeviceImagelessFramebufferFeatures(T *features)
{
features->imagelessFramebuffer = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceShaderSubgroupExtendedTypesFeatures(T *features)
{
features->shaderSubgroupExtendedTypes = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceScalarBlockLayoutFeatures(T *features)
{
features->scalarBlockLayout = VK_TRUE;
}
#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
template<typename T>
static void getPhysicalDeviceDeviceMemoryReportFeaturesEXT(T *features)
{
features->deviceMemoryReport = VK_TRUE;
}
#endif // SWIFTSHADER_DEVICE_MEMORY_REPORT
template<typename T>
static void getPhysicalDeviceUniformBufferStandardLayoutFeatures(T *features)
{
features->uniformBufferStandardLayout = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceDescriptorIndexingFeatures(T *features)
{
features->shaderInputAttachmentArrayDynamicIndexing = VK_FALSE;
features->shaderUniformTexelBufferArrayDynamicIndexing = VK_TRUE;
features->shaderStorageTexelBufferArrayDynamicIndexing = VK_TRUE;
features->shaderUniformBufferArrayNonUniformIndexing = VK_TRUE;
features->shaderSampledImageArrayNonUniformIndexing = VK_TRUE;
features->shaderStorageBufferArrayNonUniformIndexing = VK_TRUE;
features->shaderStorageImageArrayNonUniformIndexing = VK_TRUE;
features->shaderInputAttachmentArrayNonUniformIndexing = VK_FALSE;
features->shaderUniformTexelBufferArrayNonUniformIndexing = VK_TRUE;
features->shaderStorageTexelBufferArrayNonUniformIndexing = VK_TRUE;
features->descriptorBindingUniformBufferUpdateAfterBind = VK_FALSE;
features->descriptorBindingSampledImageUpdateAfterBind = VK_TRUE;
features->descriptorBindingStorageImageUpdateAfterBind = VK_TRUE;
features->descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE;
features->descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE;
features->descriptorBindingStorageTexelBufferUpdateAfterBind = VK_TRUE;
features->descriptorBindingUpdateUnusedWhilePending = VK_TRUE;
features->descriptorBindingPartiallyBound = VK_TRUE;
features->descriptorBindingVariableDescriptorCount = VK_TRUE;
features->runtimeDescriptorArray = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceVulkanMemoryModelFeatures(T *features)
{
features->vulkanMemoryModel = VK_TRUE;
features->vulkanMemoryModelDeviceScope = VK_TRUE;
features->vulkanMemoryModelAvailabilityVisibilityChains = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceTimelineSemaphoreFeatures(T *features)
{
features->timelineSemaphore = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceShaderAtomicInt64Features(T *features)
{
features->shaderBufferInt64Atomics = VK_FALSE;
features->shaderSharedInt64Atomics = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceShaderFloat16Int8Features(T *features)
{
features->shaderFloat16 = VK_FALSE;
features->shaderInt8 = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceBufferDeviceAddressFeatures(T *features)
{
features->bufferDeviceAddress = VK_TRUE;
features->bufferDeviceAddressCaptureReplay = VK_FALSE;
features->bufferDeviceAddressMultiDevice = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceDynamicRenderingFeatures(T *features)
{
features->dynamicRendering = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceInlineUniformBlockFeatures(T *features)
{
features->inlineUniformBlock = VK_TRUE;
features->descriptorBindingInlineUniformBlockUpdateAfterBind = VK_TRUE;
}
template<typename T>
static void getPhysicalDevicePrivateDataFeatures(T *features)
{
features->privateData = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceTextureCompressionASTCHDRFeatures(T *features)
{
features->textureCompressionASTC_HDR = VK_FALSE;
}
template<typename T>
static void getPhysicalDeviceShaderDemoteToHelperInvocationFeatures(T *features)
{
features->shaderDemoteToHelperInvocation = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceShaderTerminateInvocationFeatures(T *features)
{
features->shaderTerminateInvocation = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceSubgroupSizeControlFeatures(T *features)
{
features->subgroupSizeControl = VK_TRUE;
features->computeFullSubgroups = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceSynchronization2Features(T *features)
{
features->synchronization2 = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceShaderIntegerDotProductFeatures(T *features)
{
features->shaderIntegerDotProduct = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures(T *features)
{
features->shaderZeroInitializeWorkgroupMemory = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceMaintenance4Features(T *features)
{
features->maintenance4 = VK_TRUE;
}
template<typename T>
static void getPhysicalDevicePrimitiveTopologyListRestartFeatures(T *features)
{
features->primitiveTopologyListRestart = VK_TRUE;
features->primitiveTopologyPatchListRestart = VK_FALSE;
}
template<typename T>
static void getPhysicalDevicePipelineRobustnessFeatures(T *features)
{
features->pipelineRobustness = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceGraphicsPipelineLibraryFeatures(T *features)
{
features->graphicsPipelineLibrary = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceGlobalPriorityQueryFeatures(T *features)
{
features->globalPriorityQuery = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceSwapchainMaintenance1FeaturesKHR(T *features)
{
features->swapchainMaintenance1 = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceVulkan12Features(T *features)
{
features->samplerMirrorClampToEdge = VK_TRUE;
features->drawIndirectCount = VK_FALSE;
getPhysicalDevice8BitStorageFeaturesKHR(features);
getPhysicalDeviceShaderAtomicInt64Features(features);
getPhysicalDeviceShaderFloat16Int8Features(features);
features->descriptorIndexing = VK_TRUE;
getPhysicalDeviceDescriptorIndexingFeatures(features);
features->samplerFilterMinmax = VK_FALSE;
getPhysicalDeviceScalarBlockLayoutFeatures(features);
getPhysicalDeviceImagelessFramebufferFeatures(features);
getPhysicalDeviceUniformBufferStandardLayoutFeatures(features);
getPhysicalDeviceShaderSubgroupExtendedTypesFeatures(features);
getPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR(features);
getPhysicalDeviceHostQueryResetFeatures(features);
getPhysicalDeviceTimelineSemaphoreFeatures(features);
getPhysicalDeviceBufferDeviceAddressFeatures(features);
getPhysicalDeviceVulkanMemoryModelFeatures(features);
features->shaderOutputViewportIndex = VK_FALSE;
features->shaderOutputLayer = VK_FALSE;
features->subgroupBroadcastDynamicId = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceDepthClipEnableFeaturesEXT(T *features)
{
features->depthClipEnable = VK_TRUE;
}
template<typename T>
static void getPhysicalDeviceVulkan13Features(T *features)
{
getPhysicalDeviceImageRobustnessFeatures(features);
getPhysicalDeviceInlineUniformBlockFeatures(features);
getPhysicalDevicePipelineCreationCacheControlFeatures(features);
getPhysicalDevicePrivateDataFeatures(features);
getPhysicalDeviceShaderDemoteToHelperInvocationFeatures(features);
getPhysicalDeviceShaderTerminateInvocationFeatures(features);
getPhysicalDeviceSubgroupSizeControlFeatures(features);
getPhysicalDeviceSynchronization2Features(features);
getPhysicalDeviceTextureCompressionASTCHDRFeatures(features);
getPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures(features);
getPhysicalDeviceDynamicRenderingFeatures(features);
getPhysicalDeviceShaderIntegerDotProductFeatures(features);
getPhysicalDeviceMaintenance4Features(features);
}
static void getPhysicalDeviceCustomBorderColorFeaturesEXT(VkPhysicalDeviceCustomBorderColorFeaturesEXT *features)
{
features->customBorderColors = VK_TRUE;
features->customBorderColorWithoutFormat = VK_TRUE;
}
static void getPhysicalDeviceBlendOperationAdvancedFeaturesEXT(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *features)
{
features->advancedBlendCoherentOperations = VK_FALSE;
}
static void getPhysicalDeviceExtendedDynamicStateFeaturesEXT(VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features)
{
features->extendedDynamicState = VK_TRUE;
}
static void getPhysicalDevice4444FormatsFeaturesEXT(VkPhysicalDevice4444FormatsFeaturesEXT *features)
{
features->formatA4R4G4B4 = VK_TRUE;
features->formatA4B4G4R4 = VK_TRUE;
}
static void getPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT *features)
{
features->rasterizationOrderColorAttachmentAccess = VK_TRUE;
features->rasterizationOrderDepthAttachmentAccess = VK_TRUE;
features->rasterizationOrderStencilAttachmentAccess = VK_TRUE;
}
static void getPhysicalDeviceDepthClipControlFeaturesExt(VkPhysicalDeviceDepthClipControlFeaturesEXT *features)
{
features->depthClipControl = VK_TRUE;
}
void PhysicalDevice::getFeatures2(VkPhysicalDeviceFeatures2 *features) const
{
features->features = getFeatures();
VkBaseOutStructure *curExtension = reinterpret_cast<VkBaseOutStructure *>(features->pNext);
while(curExtension != nullptr)
{
switch(curExtension->sType)
{
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES:
getPhysicalDeviceVulkan11Features(reinterpret_cast<VkPhysicalDeviceVulkan11Features *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:
getPhysicalDeviceVulkan12Features(reinterpret_cast<VkPhysicalDeviceVulkan12Features *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES:
getPhysicalDeviceVulkan13Features(reinterpret_cast<VkPhysicalDeviceVulkan13Features *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:
getPhysicalDeviceMultiviewFeatures(reinterpret_cast<VkPhysicalDeviceMultiviewFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES:
getPhysicalDeviceVariablePointersFeatures(reinterpret_cast<VkPhysicalDeviceVariablePointersFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
getPhysicalDevice16BitStorageFeatures(reinterpret_cast<VkPhysicalDevice16BitStorageFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
getPhysicalDeviceSamplerYcbcrConversionFeatures(reinterpret_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES:
getPhysicalDeviceProtectedMemoryFeatures(reinterpret_cast<VkPhysicalDeviceProtectedMemoryFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES:
getPhysicalDeviceShaderDrawParameterFeatures(reinterpret_cast<VkPhysicalDeviceShaderDrawParameterFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES:
getPhysicalDeviceHostQueryResetFeatures(reinterpret_cast<VkPhysicalDeviceHostQueryResetFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES:
getPhysicalDevicePipelineCreationCacheControlFeatures(reinterpret_cast<VkPhysicalDevicePipelineCreationCacheControlFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES:
getPhysicalDeviceImageRobustnessFeatures(reinterpret_cast<VkPhysicalDeviceImageRobustnessFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
getPhysicalDeviceLineRasterizationFeaturesEXT(reinterpret_cast<VkPhysicalDeviceLineRasterizationFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES:
getPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR(reinterpret_cast<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES:
getPhysicalDevice8BitStorageFeaturesKHR(reinterpret_cast<VkPhysicalDevice8BitStorageFeaturesKHR *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT:
getPhysicalDeviceProvokingVertexFeaturesEXT(reinterpret_cast<VkPhysicalDeviceProvokingVertexFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES:
getPhysicalDeviceImagelessFramebufferFeatures(reinterpret_cast<VkPhysicalDeviceImagelessFramebufferFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES:
getPhysicalDeviceShaderSubgroupExtendedTypesFeatures(reinterpret_cast<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES:
getPhysicalDeviceScalarBlockLayoutFeatures(reinterpret_cast<VkPhysicalDeviceScalarBlockLayoutFeatures *>(curExtension));
break;
#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT:
getPhysicalDeviceDeviceMemoryReportFeaturesEXT(reinterpret_cast<VkPhysicalDeviceDeviceMemoryReportFeaturesEXT *>(curExtension));
break;
#endif // SWIFTSHADER_DEVICE_MEMORY_REPORT
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES:
getPhysicalDeviceUniformBufferStandardLayoutFeatures(reinterpret_cast<VkPhysicalDeviceUniformBufferStandardLayoutFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES:
getPhysicalDeviceVulkanMemoryModelFeatures(reinterpret_cast<VkPhysicalDeviceVulkanMemoryModelFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES:
getPhysicalDeviceTimelineSemaphoreFeatures(reinterpret_cast<VkPhysicalDeviceTimelineSemaphoreFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES:
getPhysicalDeviceShaderAtomicInt64Features(reinterpret_cast<VkPhysicalDeviceShaderAtomicInt64Features *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES:
getPhysicalDeviceShaderFloat16Int8Features(reinterpret_cast<VkPhysicalDeviceShaderFloat16Int8Features *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES:
getPhysicalDeviceBufferDeviceAddressFeatures(reinterpret_cast<VkPhysicalDeviceBufferDeviceAddressFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES:
getPhysicalDeviceDynamicRenderingFeatures(reinterpret_cast<VkPhysicalDeviceDynamicRenderingFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES:
getPhysicalDeviceDescriptorIndexingFeatures(reinterpret_cast<VkPhysicalDeviceDescriptorIndexingFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT:
getPhysicalDeviceDepthClipEnableFeaturesEXT(reinterpret_cast<VkPhysicalDeviceDepthClipEnableFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES:
getPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures(reinterpret_cast<VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT:
getPhysicalDeviceCustomBorderColorFeaturesEXT(reinterpret_cast<VkPhysicalDeviceCustomBorderColorFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT:
getPhysicalDeviceBlendOperationAdvancedFeaturesEXT(reinterpret_cast<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT:
getPhysicalDeviceExtendedDynamicStateFeaturesEXT(reinterpret_cast<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES:
getPhysicalDevicePrivateDataFeatures(reinterpret_cast<VkPhysicalDevicePrivateDataFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES:
getPhysicalDeviceTextureCompressionASTCHDRFeatures(reinterpret_cast<VkPhysicalDeviceTextureCompressionASTCHDRFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES:
getPhysicalDeviceShaderDemoteToHelperInvocationFeatures(reinterpret_cast<VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES:
getPhysicalDeviceShaderTerminateInvocationFeatures(reinterpret_cast<VkPhysicalDeviceShaderTerminateInvocationFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES:
getPhysicalDeviceSubgroupSizeControlFeatures(reinterpret_cast<VkPhysicalDeviceSubgroupSizeControlFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES:
getPhysicalDeviceInlineUniformBlockFeatures(reinterpret_cast<VkPhysicalDeviceInlineUniformBlockFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT:
getPhysicalDevice4444FormatsFeaturesEXT(reinterpret_cast<struct VkPhysicalDevice4444FormatsFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES:
getPhysicalDeviceSynchronization2Features(reinterpret_cast<struct VkPhysicalDeviceSynchronization2Features *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES:
getPhysicalDeviceShaderIntegerDotProductFeatures(reinterpret_cast<struct VkPhysicalDeviceShaderIntegerDotProductFeatures *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES:
getPhysicalDeviceMaintenance4Features(reinterpret_cast<struct VkPhysicalDeviceMaintenance4Features *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT:
getPhysicalDevicePrimitiveTopologyListRestartFeatures(reinterpret_cast<struct VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT:
getPhysicalDevicePipelineRobustnessFeatures(reinterpret_cast<struct VkPhysicalDevicePipelineRobustnessFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT:
getPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT(reinterpret_cast<struct VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR:
getPhysicalDeviceGlobalPriorityQueryFeatures(reinterpret_cast<struct VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT:
getPhysicalDeviceDepthClipControlFeaturesExt(reinterpret_cast<struct VkPhysicalDeviceDepthClipControlFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT:
getPhysicalDeviceGraphicsPipelineLibraryFeatures(reinterpret_cast<struct VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT:
getPhysicalDeviceSwapchainMaintenance1FeaturesKHR(reinterpret_cast<struct VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *>(curExtension));
break;
case VK_STRUCTURE_TYPE_MAX_ENUM: // TODO(b/176893525): This may not be legal. dEQP tests that this value is ignored.
break;
default:
UNSUPPORTED("curExtension->sType: %s", vk::Stringify(curExtension->sType).c_str());
break;
}
curExtension = reinterpret_cast<VkBaseOutStructure *>(curExtension->pNext);
}
}
VkSampleCountFlags PhysicalDevice::getSampleCounts()
{
return VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
}
const VkPhysicalDeviceLimits &PhysicalDevice::getLimits()
{
VkSampleCountFlags sampleCounts = getSampleCounts();
static const VkPhysicalDeviceLimits limits = {
1 << (vk::MAX_IMAGE_LEVELS_1D - 1), // maxImageDimension1D
1 << (vk::MAX_IMAGE_LEVELS_2D - 1), // maxImageDimension2D
1 << (vk::MAX_IMAGE_LEVELS_3D - 1), // maxImageDimension3D
1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1), // maxImageDimensionCube
vk::MAX_IMAGE_ARRAY_LAYERS, // maxImageArrayLayers
65536, // maxTexelBufferElements
65536, // maxUniformBufferRange
vk::MAX_MEMORY_ALLOCATION_SIZE, // maxStorageBufferRange
vk::MAX_PUSH_CONSTANT_SIZE, // maxPushConstantsSize
4096, // maxMemoryAllocationCount
vk::MAX_SAMPLER_ALLOCATION_COUNT, // maxSamplerAllocationCount
4096, // bufferImageGranularity
0, // sparseAddressSpaceSize (unsupported)
MAX_BOUND_DESCRIPTOR_SETS, // maxBoundDescriptorSets
64, // maxPerStageDescriptorSamplers
15, // maxPerStageDescriptorUniformBuffers
30, // maxPerStageDescriptorStorageBuffers
200, // maxPerStageDescriptorSampledImages
16, // maxPerStageDescriptorStorageImages
sw::MAX_COLOR_BUFFERS, // maxPerStageDescriptorInputAttachments
200, // maxPerStageResources
576, // maxDescriptorSetSamplers
90, // maxDescriptorSetUniformBuffers
MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS_DYNAMIC, // maxDescriptorSetUniformBuffersDynamic
96, // maxDescriptorSetStorageBuffers
MAX_DESCRIPTOR_SET_STORAGE_BUFFERS_DYNAMIC, // maxDescriptorSetStorageBuffersDynamic
1800, // maxDescriptorSetSampledImages
144, // maxDescriptorSetStorageImages
sw::MAX_COLOR_BUFFERS, // maxDescriptorSetInputAttachments
16, // maxVertexInputAttributes
vk::MAX_VERTEX_INPUT_BINDINGS, // maxVertexInputBindings
2047, // maxVertexInputAttributeOffset
2048, // maxVertexInputBindingStride
sw::MAX_INTERFACE_COMPONENTS, // maxVertexOutputComponents
0, // maxTessellationGenerationLevel (unsupported)
0, // maxTessellationPatchSize (unsupported)
0, // maxTessellationControlPerVertexInputComponents (unsupported)
0, // maxTessellationControlPerVertexOutputComponents (unsupported)
0, // maxTessellationControlPerPatchOutputComponents (unsupported)
0, // maxTessellationControlTotalOutputComponents (unsupported)
0, // maxTessellationEvaluationInputComponents (unsupported)
0, // maxTessellationEvaluationOutputComponents (unsupported)
0, // maxGeometryShaderInvocations (unsupported)
0, // maxGeometryInputComponents (unsupported)
0, // maxGeometryOutputComponents (unsupported)
0, // maxGeometryOutputVertices (unsupported)
0, // maxGeometryTotalOutputComponents (unsupported)
sw::MAX_INTERFACE_COMPONENTS, // maxFragmentInputComponents
sw::MAX_COLOR_BUFFERS, // maxFragmentOutputAttachments
1, // maxFragmentDualSrcAttachments
28, // maxFragmentCombinedOutputResources
32768, // maxComputeSharedMemorySize
{ 65535, 65535, 65535 }, // maxComputeWorkGroupCount[3]
vk::MAX_COMPUTE_WORKGROUP_INVOCATIONS, // maxComputeWorkGroupInvocations
{ 256, 256, 64 }, // maxComputeWorkGroupSize[3]
vk::SUBPIXEL_PRECISION_BITS, // subPixelPrecisionBits
8, // subTexelPrecisionBits
6, // mipmapPrecisionBits
UINT32_MAX, // maxDrawIndexedIndexValue
UINT32_MAX, // maxDrawIndirectCount
vk::MAX_SAMPLER_LOD_BIAS, // maxSamplerLodBias
16, // maxSamplerAnisotropy
MAX_VIEWPORTS, // maxViewports
{ sw::MAX_VIEWPORT_DIM,
sw::MAX_VIEWPORT_DIM }, // maxViewportDimensions[2]
{ -2 * sw::MAX_VIEWPORT_DIM,
2 * sw::MAX_VIEWPORT_DIM - 1 }, // viewportBoundsRange[2]
0, // viewportSubPixelBits
vk::MIN_MEMORY_MAP_ALIGNMENT, // minMemoryMapAlignment
vk::MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT, // minTexelBufferOffsetAlignment
vk::MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT, // minUniformBufferOffsetAlignment
vk::MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT, // minStorageBufferOffsetAlignment
sw::MIN_TEXEL_OFFSET, // minTexelOffset
sw::MAX_TEXEL_OFFSET, // maxTexelOffset
sw::MIN_TEXEL_OFFSET, // minTexelGatherOffset
sw::MAX_TEXEL_OFFSET, // maxTexelGatherOffset
-0.5, // minInterpolationOffset
0.5, // maxInterpolationOffset
4, // subPixelInterpolationOffsetBits
sw::MAX_FRAMEBUFFER_DIM, // maxFramebufferWidth
sw::MAX_FRAMEBUFFER_DIM, // maxFramebufferHeight
256, // maxFramebufferLayers
sampleCounts, // framebufferColorSampleCounts
sampleCounts, // framebufferDepthSampleCounts
sampleCounts, // framebufferStencilSampleCounts
sampleCounts, // framebufferNoAttachmentsSampleCounts
sw::MAX_COLOR_BUFFERS, // maxColorAttachments
sampleCounts, // sampledImageColorSampleCounts
sampleCounts, // sampledImageIntegerSampleCounts
sampleCounts, // sampledImageDepthSampleCounts
sampleCounts, // sampledImageStencilSampleCounts
sampleCounts, // storageImageSampleCounts
1, // maxSampleMaskWords
VK_TRUE, // timestampComputeAndGraphics
1, // timestampPeriod
sw::MAX_CLIP_DISTANCES, // maxClipDistances
sw::MAX_CULL_DISTANCES, // maxCullDistances
sw::MAX_CLIP_DISTANCES + sw::MAX_CULL_DISTANCES, // maxCombinedClipAndCullDistances
2, // discreteQueuePriorities
{ 1.0, vk::MAX_POINT_SIZE }, // pointSizeRange[2]
{ 1.0, 1.0 }, // lineWidthRange[2] (unsupported)
0.0, // pointSizeGranularity (unsupported)
0.0, // lineWidthGranularity (unsupported)
VK_TRUE, // strictLines
VK_TRUE, // standardSampleLocations
64, // optimalBufferCopyOffsetAlignment
64, // optimalBufferCopyRowPitchAlignment
256, // nonCoherentAtomSize
};
return limits;
}
const VkPhysicalDeviceProperties &PhysicalDevice::getProperties() const
{
auto getProperties = [&]() -> VkPhysicalDeviceProperties {
VkPhysicalDeviceProperties properties = {
API_VERSION,
DRIVER_VERSION,
VENDOR_ID,
DEVICE_ID,
VK_PHYSICAL_DEVICE_TYPE_CPU, // deviceType
"", // deviceName
SWIFTSHADER_UUID, // pipelineCacheUUID
getLimits(), // limits
{} // sparseProperties
};
// Append Reactor JIT backend name and version
snprintf(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE,
"%s (%s)", SWIFTSHADER_DEVICE_NAME, rr::Caps::backendName().c_str());
return properties;
};
static const VkPhysicalDeviceProperties properties = getProperties();
return properties;
}
template<typename T>
static void getIdProperties(T *properties)
{
memset(properties->deviceUUID, 0, VK_UUID_SIZE);
memset(properties->driverUUID, 0, VK_UUID_SIZE);
memset(properties->deviceLUID, 0, VK_LUID_SIZE);
memcpy(properties->deviceUUID, SWIFTSHADER_UUID, VK_UUID_SIZE);
*((uint64_t *)properties->driverUUID) = DRIVER_VERSION;
properties->deviceNodeMask = 0;
properties->deviceLUIDValid = VK_FALSE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceIDProperties *properties) const
{
getIdProperties(properties);
}
template<typename T>
static void getMaintenance3Properties(T *properties)
{
properties->maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE;
properties->maxPerSetDescriptors = 1024;
}
template<typename T>
static void getMaintenance4Properties(T *properties)
{
properties->maxBufferSize = MAX_MEMORY_ALLOCATION_SIZE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceMaintenance3Properties *properties) const
{
getMaintenance3Properties(properties);
}
void PhysicalDevice::getProperties(VkPhysicalDeviceMaintenance4Properties *properties) const
{
getMaintenance4Properties(properties);
}
template<typename T>
static void getMultiviewProperties(T *properties)
{
properties->maxMultiviewViewCount = 6;
properties->maxMultiviewInstanceIndex = 1u << 27;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceMultiviewProperties *properties) const
{
getMultiviewProperties(properties);
}
template<typename T>
static void getPointClippingProperties(T *properties)
{
properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
}
void PhysicalDevice::getProperties(VkPhysicalDevicePointClippingProperties *properties) const
{
getPointClippingProperties(properties);
}
template<typename T>
static void getProtectedMemoryProperties(T *properties)
{
properties->protectedNoFault = VK_FALSE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceProtectedMemoryProperties *properties) const
{
getProtectedMemoryProperties(properties);
}
template<typename T>
static void getSubgroupProperties(T *properties)
{
properties->subgroupSize = sw::SIMD::Width;
properties->supportedStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
properties->supportedOperations =
VK_SUBGROUP_FEATURE_BASIC_BIT |
VK_SUBGROUP_FEATURE_VOTE_BIT |
VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
VK_SUBGROUP_FEATURE_BALLOT_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |
VK_SUBGROUP_FEATURE_QUAD_BIT;
properties->quadOperationsInAllStages = VK_FALSE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceSubgroupProperties *properties) const
{
getSubgroupProperties(properties);
}
void PhysicalDevice::getProperties(VkPhysicalDeviceVulkan11Properties *properties) const
{
getIdProperties(properties);
// We can't use templated functions for Vulkan11 & subgroup properties. The names of the
// variables in VkPhysicalDeviceSubgroupProperties differ from the names in the Vulkan11
// struct.
VkPhysicalDeviceSubgroupProperties subgroupProperties = {};
getProperties(&subgroupProperties);
properties->subgroupSize = subgroupProperties.subgroupSize;
properties->subgroupSupportedStages = subgroupProperties.supportedStages;
properties->subgroupSupportedOperations = subgroupProperties.supportedOperations;
properties->subgroupQuadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages;
getPointClippingProperties(properties);
getMultiviewProperties(properties);
getProtectedMemoryProperties(properties);
getMaintenance3Properties(properties);
}
void PhysicalDevice::getProperties(const VkExternalMemoryHandleTypeFlagBits *handleType, VkExternalImageFormatProperties *properties) const
{
VkExternalMemoryProperties *extMemProperties = &properties->externalMemoryProperties;
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
{
extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
return;
}
#endif
#if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
{
extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
return;
}
#endif
#if VK_USE_PLATFORM_FUCHSIA
if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
{
extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
return;
}
#endif
extMemProperties->compatibleHandleTypes = 0;
extMemProperties->exportFromImportedHandleTypes = 0;
extMemProperties->externalMemoryFeatures = 0;
}
void PhysicalDevice::getProperties(const VkExternalMemoryHandleTypeFlagBits *handleType, VkExternalBufferProperties *properties) const
{
VkExternalMemoryProperties *extMemProperties = &properties->externalMemoryProperties;
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
{
extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
return;
}
#endif
#if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
{
extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
return;
}
#endif
#if VK_USE_PLATFORM_FUCHSIA
if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
{
extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
return;
}
#endif
extMemProperties->compatibleHandleTypes = 0;
extMemProperties->exportFromImportedHandleTypes = 0;
extMemProperties->externalMemoryFeatures = 0;
}
void PhysicalDevice::getProperties(VkSamplerYcbcrConversionImageFormatProperties *properties) const
{
properties->combinedImageSamplerDescriptorCount = 1; // Need only one descriptor for YCbCr sampling.
}
#ifdef __ANDROID__
void PhysicalDevice::getProperties(VkPhysicalDevicePresentationPropertiesANDROID *properties) const
{
properties->sharedImage = VK_FALSE;
}
void PhysicalDevice::getProperties(const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkAndroidHardwareBufferUsageANDROID *ahbProperties) const
{
// Maps VkImageUsageFlags to AHB usage flags using this table from the Vulkan spec
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#memory-external-android-hardware-buffer-usage
// VK_IMAGE_CREATE_PROTECTED_BIT not currently supported.
ASSERT((pImageFormatInfo->flags & VK_IMAGE_CREATE_PROTECTED_BIT) == 0);
// "It must include at least one GPU usage flag (AHARDWAREBUFFER_USAGE_GPU_*), even if none of the corresponding Vulkan usages or flags are requested."
uint64_t ahbUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
// Already covered by the default GPU usage flag above.
//
// if ((vkUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) || (vkUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
// {
// ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
// }
if((pImageFormatInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) || (pImageFormatInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))
{
ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
}
if(pImageFormatInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
{
ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
}
if(pImageFormatInfo->flags & VK_IMAGE_CREATE_PROTECTED_BIT)
{
ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
}
ahbProperties->androidHardwareBufferUsage = ahbUsage;
}
#endif
void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, VkExternalBufferProperties *pExternalBufferProperties) const
{
VkExternalMemoryProperties *properties = &pExternalBufferProperties->externalMemoryProperties;
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD || SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
const VkExternalMemoryHandleTypeFlagBits *handleType = &pExternalBufferInfo->handleType;
#endif
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
{
properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
properties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
return;
}
#endif
#if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
{
properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
properties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
return;
}
#endif
properties->compatibleHandleTypes = 0;
properties->exportFromImportedHandleTypes = 0;
properties->externalMemoryFeatures = 0;
}
void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, VkExternalFenceProperties *pExternalFenceProperties) const
{
pExternalFenceProperties->compatibleHandleTypes = 0;
pExternalFenceProperties->exportFromImportedHandleTypes = 0;
pExternalFenceProperties->externalFenceFeatures = 0;
}
void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties) const
{
for(const auto *nextInfo = reinterpret_cast<const VkBaseInStructure *>(pExternalSemaphoreInfo->pNext);
nextInfo != nullptr; nextInfo = nextInfo->pNext)
{
switch(nextInfo->sType)
{
case VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO:
{
const auto *tlsInfo = reinterpret_cast<const VkSemaphoreTypeCreateInfo *>(nextInfo);
// Timeline Semaphore does not support external semaphore
if(tlsInfo->semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
{
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
return;
}
}
break;
default:
WARN("nextInfo->sType = %s", vk::Stringify(nextInfo->sType).c_str());
break;
}
}
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_OPAQUE_FD
if(pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
{
pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
return;
}
#endif
#if VK_USE_PLATFORM_FUCHSIA
if(pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA)
{
pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA;
pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA;
pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
return;
}
#endif
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceExternalMemoryHostPropertiesEXT *properties) const
{
properties->minImportedHostPointerAlignment = vk::MIN_IMPORTED_HOST_POINTER_ALIGNMENT;
}
template<typename T>
static void getDriverProperties(T *properties)
{
properties->driverID = VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR;
strcpy(properties->driverName, "SwiftShader driver");
strcpy(properties->driverInfo, "");
properties->conformanceVersion = { 1, 3, 3, 1 };
}
void PhysicalDevice::getProperties(VkPhysicalDeviceDriverProperties *properties) const
{
getDriverProperties(properties);
}
void PhysicalDevice::getProperties(VkPhysicalDeviceLineRasterizationPropertiesEXT *properties) const
{
properties->lineSubPixelPrecisionBits = vk::SUBPIXEL_PRECISION_BITS;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceProvokingVertexPropertiesEXT *properties) const
{
properties->provokingVertexModePerPipeline = VK_TRUE;
}
template<typename T>
static void getFloatControlsProperties(T *properties)
{
// The spec states:
// shaderSignedZeroInfNanPreserveFloat32 is a boolean value indicating whether
// sign of a zero, Nans and +/-infinity can be preserved in 32-bit floating-point
// computations. It also indicates whether the SignedZeroInfNanPreserve execution
// mode can be used for 32-bit floating-point types.
//
// There are similar clauses for all the shader* bools present here.
//
// It does not state that an implementation must report its default behavior using
// these variables. At this time SwiftShader does not expose any preserve, denormal,
// or rounding controls.
properties->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
properties->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
properties->shaderSignedZeroInfNanPreserveFloat16 = VK_TRUE;
properties->shaderSignedZeroInfNanPreserveFloat32 = VK_TRUE;
properties->shaderSignedZeroInfNanPreserveFloat64 = VK_TRUE;
properties->shaderDenormPreserveFloat16 = VK_FALSE;
properties->shaderDenormPreserveFloat32 = VK_FALSE;
properties->shaderDenormPreserveFloat64 = VK_FALSE;
properties->shaderDenormFlushToZeroFloat16 = VK_FALSE;
properties->shaderDenormFlushToZeroFloat32 = VK_FALSE;
properties->shaderDenormFlushToZeroFloat64 = VK_FALSE;
properties->shaderRoundingModeRTZFloat16 = VK_FALSE;
properties->shaderRoundingModeRTZFloat32 = VK_FALSE;
properties->shaderRoundingModeRTZFloat64 = VK_FALSE;
properties->shaderRoundingModeRTEFloat16 = VK_FALSE;
properties->shaderRoundingModeRTEFloat32 = VK_FALSE;
properties->shaderRoundingModeRTEFloat64 = VK_FALSE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceFloatControlsProperties *properties) const
{
getFloatControlsProperties(properties);
}
template<typename T>
static void getDescriptorIndexingProperties(T *properties)
{
// "The UpdateAfterBind descriptor limits must each be greater than or equal to
// the corresponding non-UpdateAfterBind limit."
const VkPhysicalDeviceLimits &limits = PhysicalDevice::getLimits();
// Limits from:
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#limits-minmax
// Table 53. Required Limits
properties->maxUpdateAfterBindDescriptorsInAllPools = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->shaderUniformBufferArrayNonUniformIndexingNative = VK_FALSE;
properties->shaderSampledImageArrayNonUniformIndexingNative = VK_FALSE;
properties->shaderStorageBufferArrayNonUniformIndexingNative = VK_FALSE;
properties->shaderStorageImageArrayNonUniformIndexingNative = VK_FALSE;
properties->shaderInputAttachmentArrayNonUniformIndexingNative = VK_FALSE;
properties->robustBufferAccessUpdateAfterBind = VK_FALSE;
properties->quadDivergentImplicitLod = VK_FALSE;
properties->maxPerStageDescriptorUpdateAfterBindSamplers = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers = limits.maxPerStageDescriptorUniformBuffers;
properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxPerStageDescriptorUpdateAfterBindSampledImages = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxPerStageDescriptorUpdateAfterBindStorageImages = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxPerStageDescriptorUpdateAfterBindInputAttachments = limits.maxPerStageDescriptorInputAttachments;
properties->maxPerStageUpdateAfterBindResources = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxDescriptorSetUpdateAfterBindSamplers = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxDescriptorSetUpdateAfterBindUniformBuffers = limits.maxDescriptorSetUniformBuffers;
properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = limits.maxDescriptorSetUniformBuffersDynamic;
properties->maxDescriptorSetUpdateAfterBindStorageBuffers = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = limits.maxDescriptorSetStorageBuffersDynamic;
properties->maxDescriptorSetUpdateAfterBindSampledImages = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxDescriptorSetUpdateAfterBindStorageImages = vk::MAX_UPDATE_AFTER_BIND_DESCRIPTORS;
properties->maxDescriptorSetUpdateAfterBindInputAttachments = limits.maxDescriptorSetInputAttachments;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceDescriptorIndexingProperties *properties) const
{
getDescriptorIndexingProperties(properties);
}
template<typename T>
static void getDepthStencilResolveProperties(T *properties)
{
properties->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | VK_RESOLVE_MODE_NONE;
properties->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | VK_RESOLVE_MODE_NONE;
properties->independentResolveNone = VK_TRUE;
properties->independentResolve = VK_TRUE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceDepthStencilResolveProperties *properties) const
{
getDepthStencilResolveProperties(properties);
}
void PhysicalDevice::getProperties(VkPhysicalDeviceCustomBorderColorPropertiesEXT *properties) const
{
properties->maxCustomBorderColorSamplers = MAX_SAMPLER_ALLOCATION_COUNT;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT *properties) const
{
properties->advancedBlendMaxColorAttachments = sw::MAX_COLOR_BUFFERS;
properties->advancedBlendIndependentBlend = VK_FALSE;
properties->advancedBlendNonPremultipliedSrcColor = VK_FALSE;
properties->advancedBlendNonPremultipliedDstColor = VK_FALSE;
properties->advancedBlendCorrelatedOverlap = VK_FALSE;
properties->advancedBlendAllOperations = VK_FALSE;
}
template<typename T>
static void getSubgroupSizeControlProperties(T *properties)
{
VkPhysicalDeviceSubgroupProperties subgroupProperties = {};
getSubgroupProperties(&subgroupProperties);
properties->minSubgroupSize = subgroupProperties.subgroupSize;
properties->maxSubgroupSize = subgroupProperties.subgroupSize;
properties->maxComputeWorkgroupSubgroups = vk::MAX_COMPUTE_WORKGROUP_INVOCATIONS /
properties->minSubgroupSize;
properties->requiredSubgroupSizeStages = subgroupProperties.supportedStages;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceSubgroupSizeControlProperties *properties) const
{
getSubgroupSizeControlProperties(properties);
}
template<typename T>
static void getInlineUniformBlockProperties(T *properties)
{
properties->maxInlineUniformBlockSize = MAX_INLINE_UNIFORM_BLOCK_SIZE;
properties->maxPerStageDescriptorInlineUniformBlocks = 4;
properties->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = 4;
properties->maxDescriptorSetInlineUniformBlocks = 4;
properties->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = 4;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceInlineUniformBlockProperties *properties) const
{
getInlineUniformBlockProperties(properties);
}
template<typename T>
static void getTexelBufferAlignmentProperties(T *properties)
{
properties->storageTexelBufferOffsetAlignmentBytes = vk::MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT;
properties->storageTexelBufferOffsetSingleTexelAlignment = VK_FALSE;
properties->uniformTexelBufferOffsetAlignmentBytes = vk::MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT;
properties->uniformTexelBufferOffsetSingleTexelAlignment = VK_FALSE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceTexelBufferAlignmentProperties *properties) const
{
getTexelBufferAlignmentProperties(properties);
}
template<typename T>
static void getShaderIntegerDotProductProperties(T *properties)
{
properties->integerDotProduct8BitUnsignedAccelerated = VK_FALSE;
properties->integerDotProduct8BitSignedAccelerated = VK_FALSE;
properties->integerDotProduct8BitMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProduct4x8BitPackedUnsignedAccelerated = VK_FALSE;
properties->integerDotProduct4x8BitPackedSignedAccelerated = VK_FALSE;
properties->integerDotProduct4x8BitPackedMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProduct16BitUnsignedAccelerated = VK_FALSE;
properties->integerDotProduct16BitSignedAccelerated = VK_FALSE;
properties->integerDotProduct16BitMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProduct32BitUnsignedAccelerated = VK_FALSE;
properties->integerDotProduct32BitSignedAccelerated = VK_FALSE;
properties->integerDotProduct32BitMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProduct64BitUnsignedAccelerated = VK_FALSE;
properties->integerDotProduct64BitSignedAccelerated = VK_FALSE;
properties->integerDotProduct64BitMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating8BitUnsignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating8BitSignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating16BitUnsignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating16BitSignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating32BitUnsignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating32BitSignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating64BitUnsignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating64BitSignedAccelerated = VK_FALSE;
properties->integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated = VK_FALSE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceShaderIntegerDotProductProperties *properties) const
{
getShaderIntegerDotProductProperties(properties);
}
template<typename T>
static void getGraphicsPipelineLibraryProperties(T *properties)
{
// Library linking is currently fast in SwiftShader, because all the pipeline creation cost
// is actually paid at draw time.
properties->graphicsPipelineLibraryFastLinking = VK_TRUE;
// TODO: check this
properties->graphicsPipelineLibraryIndependentInterpolationDecoration = VK_FALSE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT *properties) const
{
getGraphicsPipelineLibraryProperties(properties);
}
template<typename T>
static void getSamplerFilterMinmaxProperties(T *properties)
{
properties->filterMinmaxSingleComponentFormats = VK_FALSE;
properties->filterMinmaxImageComponentMapping = VK_FALSE;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceSamplerFilterMinmaxProperties *properties) const
{
getSamplerFilterMinmaxProperties(properties);
}
template<typename T>
static void getTimelineSemaphoreProperties(T *properties)
{
// Our implementation of Timeline Semaphores allows the timeline to advance to any value from any value.
properties->maxTimelineSemaphoreValueDifference = (uint64_t)-1;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceTimelineSemaphoreProperties *properties) const
{
getTimelineSemaphoreProperties(properties);
}
template<typename T>
static void getPipelineRobustnessProperties(T *properties)
{
// Buffer access is not robust by default.
properties->defaultRobustnessStorageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT;
properties->defaultRobustnessUniformBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT;
properties->defaultRobustnessVertexInputs = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT;
// SwiftShader currently provides robustImageAccess robustness unconditionally.
// robustImageAccess2 is not supported.
// TODO(b/162327166): Only provide robustness when requested.
properties->defaultRobustnessImages = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT;
}
void PhysicalDevice::getProperties(VkPhysicalDevicePipelineRobustnessPropertiesEXT *properties) const
{
getPipelineRobustnessProperties(properties);
}
void PhysicalDevice::getProperties(VkPhysicalDeviceVulkan12Properties *properties) const
{
getDriverProperties(properties);
getFloatControlsProperties(properties);
getDescriptorIndexingProperties(properties);
getDepthStencilResolveProperties(properties);
getSamplerFilterMinmaxProperties(properties);
getTimelineSemaphoreProperties(properties);
properties->framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT;
}
void PhysicalDevice::getProperties(VkPhysicalDeviceVulkan13Properties *properties) const
{
getSubgroupSizeControlProperties(properties);
getInlineUniformBlockProperties(properties);
properties->maxInlineUniformTotalSize = properties->maxInlineUniformBlockSize *
properties->maxDescriptorSetInlineUniformBlocks;
getShaderIntegerDotProductProperties(properties);
getTexelBufferAlignmentProperties(properties);
getMaintenance4Properties(properties);
}
bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures &requestedFeatures) const
{
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_FALSE) && (supportedFeature[i] == VK_FALSE))
{
return false;
}
}
return true;
}
// CheckFeature returns false if requested is asking for a feature that is not supported
#define CheckFeature(requested, supported, feature) (requested->feature == VK_FALSE || supported.feature == VK_TRUE)
template<typename T>
T PhysicalDevice::getSupportedFeatures(const T *requested) const
{
VkPhysicalDeviceFeatures2 features;
features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
T supported;
supported.sType = requested->sType;
supported.pNext = nullptr;
features.pNext = &supported;
getFeatures2(&features);
return supported;
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceLineRasterizationFeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, rectangularLines) &&
CheckFeature(requested, supported, bresenhamLines) &&
CheckFeature(requested, supported, smoothLines) &&
CheckFeature(requested, supported, stippledRectangularLines) &&
CheckFeature(requested, supported, stippledBresenhamLines) &&
CheckFeature(requested, supported, stippledSmoothLines);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceProvokingVertexFeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, provokingVertexLast) &&
CheckFeature(requested, supported, transformFeedbackPreservesProvokingVertex);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceVulkan11Features *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, storageBuffer16BitAccess) &&
CheckFeature(requested, supported, uniformAndStorageBuffer16BitAccess) &&
CheckFeature(requested, supported, storagePushConstant16) &&
CheckFeature(requested, supported, storageInputOutput16) &&
CheckFeature(requested, supported, multiview) &&
CheckFeature(requested, supported, multiviewGeometryShader) &&
CheckFeature(requested, supported, multiviewTessellationShader) &&
CheckFeature(requested, supported, variablePointersStorageBuffer) &&
CheckFeature(requested, supported, variablePointers) &&
CheckFeature(requested, supported, protectedMemory) &&
CheckFeature(requested, supported, samplerYcbcrConversion) &&
CheckFeature(requested, supported, shaderDrawParameters);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceVulkan12Features *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, samplerMirrorClampToEdge) &&
CheckFeature(requested, supported, drawIndirectCount) &&
CheckFeature(requested, supported, storageBuffer8BitAccess) &&
CheckFeature(requested, supported, uniformAndStorageBuffer8BitAccess) &&
CheckFeature(requested, supported, storagePushConstant8) &&
CheckFeature(requested, supported, shaderBufferInt64Atomics) &&
CheckFeature(requested, supported, shaderSharedInt64Atomics) &&
CheckFeature(requested, supported, shaderFloat16) &&
CheckFeature(requested, supported, shaderInt8) &&
CheckFeature(requested, supported, descriptorIndexing) &&
CheckFeature(requested, supported, shaderInputAttachmentArrayDynamicIndexing) &&
CheckFeature(requested, supported, shaderUniformTexelBufferArrayDynamicIndexing) &&
CheckFeature(requested, supported, shaderStorageTexelBufferArrayDynamicIndexing) &&
CheckFeature(requested, supported, shaderUniformBufferArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderSampledImageArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderStorageBufferArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderStorageImageArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderInputAttachmentArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderUniformTexelBufferArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderStorageTexelBufferArrayNonUniformIndexing) &&
CheckFeature(requested, supported, descriptorBindingUniformBufferUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingSampledImageUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingStorageImageUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingStorageBufferUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingUniformTexelBufferUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingStorageTexelBufferUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingUpdateUnusedWhilePending) &&
CheckFeature(requested, supported, descriptorBindingPartiallyBound) &&
CheckFeature(requested, supported, descriptorBindingVariableDescriptorCount) &&
CheckFeature(requested, supported, runtimeDescriptorArray) &&
CheckFeature(requested, supported, samplerFilterMinmax) &&
CheckFeature(requested, supported, scalarBlockLayout) &&
CheckFeature(requested, supported, imagelessFramebuffer) &&
CheckFeature(requested, supported, uniformBufferStandardLayout) &&
CheckFeature(requested, supported, shaderSubgroupExtendedTypes) &&
CheckFeature(requested, supported, separateDepthStencilLayouts) &&
CheckFeature(requested, supported, hostQueryReset) &&
CheckFeature(requested, supported, timelineSemaphore) &&
CheckFeature(requested, supported, bufferDeviceAddress) &&
CheckFeature(requested, supported, bufferDeviceAddressCaptureReplay) &&
CheckFeature(requested, supported, bufferDeviceAddressMultiDevice) &&
CheckFeature(requested, supported, vulkanMemoryModel) &&
CheckFeature(requested, supported, vulkanMemoryModelDeviceScope) &&
CheckFeature(requested, supported, vulkanMemoryModelAvailabilityVisibilityChains) &&
CheckFeature(requested, supported, shaderOutputViewportIndex) &&
CheckFeature(requested, supported, shaderOutputLayer) &&
CheckFeature(requested, supported, subgroupBroadcastDynamicId);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceVulkan13Features *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, robustImageAccess) &&
CheckFeature(requested, supported, inlineUniformBlock) &&
CheckFeature(requested, supported, descriptorBindingInlineUniformBlockUpdateAfterBind) &&
CheckFeature(requested, supported, pipelineCreationCacheControl) &&
CheckFeature(requested, supported, privateData) &&
CheckFeature(requested, supported, shaderDemoteToHelperInvocation) &&
CheckFeature(requested, supported, shaderTerminateInvocation) &&
CheckFeature(requested, supported, subgroupSizeControl) &&
CheckFeature(requested, supported, computeFullSubgroups) &&
CheckFeature(requested, supported, synchronization2) &&
CheckFeature(requested, supported, textureCompressionASTC_HDR) &&
CheckFeature(requested, supported, shaderZeroInitializeWorkgroupMemory) &&
CheckFeature(requested, supported, dynamicRendering) &&
CheckFeature(requested, supported, shaderIntegerDotProduct) &&
CheckFeature(requested, supported, maintenance4);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceDepthClipEnableFeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, depthClipEnable);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, advancedBlendCoherentOperations);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceInlineUniformBlockFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, inlineUniformBlock) &&
CheckFeature(requested, supported, descriptorBindingInlineUniformBlockUpdateAfterBind);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceShaderIntegerDotProductFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, shaderIntegerDotProduct);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, extendedDynamicState);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDevicePrivateDataFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, privateData);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceTextureCompressionASTCHDRFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, textureCompressionASTC_HDR);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, shaderDemoteToHelperInvocation);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceShaderTerminateInvocationFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, shaderTerminateInvocation);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceSubgroupSizeControlFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, subgroupSizeControl) &&
CheckFeature(requested, supported, computeFullSubgroups);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, shaderZeroInitializeWorkgroupMemory);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, primitiveTopologyListRestart) &&
CheckFeature(requested, supported, primitiveTopologyPatchListRestart);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, graphicsPipelineLibrary);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, swapchainMaintenance1);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceDescriptorIndexingFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, shaderInputAttachmentArrayDynamicIndexing) &&
CheckFeature(requested, supported, shaderUniformTexelBufferArrayDynamicIndexing) &&
CheckFeature(requested, supported, shaderStorageTexelBufferArrayDynamicIndexing) &&
CheckFeature(requested, supported, shaderUniformBufferArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderSampledImageArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderStorageBufferArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderStorageImageArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderInputAttachmentArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderUniformTexelBufferArrayNonUniformIndexing) &&
CheckFeature(requested, supported, shaderStorageTexelBufferArrayNonUniformIndexing) &&
CheckFeature(requested, supported, descriptorBindingUniformBufferUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingSampledImageUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingStorageImageUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingStorageBufferUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingUniformTexelBufferUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingStorageTexelBufferUpdateAfterBind) &&
CheckFeature(requested, supported, descriptorBindingUpdateUnusedWhilePending) &&
CheckFeature(requested, supported, descriptorBindingPartiallyBound) &&
CheckFeature(requested, supported, descriptorBindingVariableDescriptorCount) &&
CheckFeature(requested, supported, runtimeDescriptorArray);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDevicePipelineRobustnessFeaturesEXT *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, pipelineRobustness);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceProtectedMemoryFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, protectedMemory);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceBufferDeviceAddressFeatures *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, bufferDeviceAddress) &&
CheckFeature(requested, supported, bufferDeviceAddressCaptureReplay) &&
CheckFeature(requested, supported, bufferDeviceAddressMultiDevice);
}
bool PhysicalDevice::hasExtendedFeatures(const VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR *requested) const
{
auto supported = getSupportedFeatures(requested);
return CheckFeature(requested, supported, globalPriorityQuery);
}
#undef CheckFeature
static bool checkFormatUsage(VkImageUsageFlags usage, VkFormatFeatureFlags features)
{
// Check for usage conflict with features
if((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && !(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
{
return false;
}
if((usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
{
return false;
}
if((usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
{
return false;
}
if((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
{
return false;
}
if((usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && !(features & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)))
{
return false;
}
if((usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) && !(features & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT))
{
return false;
}
if((usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) && !(features & VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
{
return false;
}
return true;
}
bool vk::PhysicalDevice::isFormatSupported(vk::Format format, VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageUsageFlags stencilUsage, VkImageCreateFlags flags)
{
VkFormatProperties properties = {};
vk::PhysicalDevice::GetFormatProperties(format, &properties);
if(flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT)
{
for(vk::Format f : format.getCompatibleFormats())
{
VkFormatProperties extendedProperties = {};
vk::PhysicalDevice::GetFormatProperties(f, &extendedProperties);
properties.linearTilingFeatures |= extendedProperties.linearTilingFeatures;
properties.optimalTilingFeatures |= extendedProperties.optimalTilingFeatures;
properties.bufferFeatures |= extendedProperties.bufferFeatures;
}
}
VkFormatFeatureFlags features;
switch(tiling)
{
case VK_IMAGE_TILING_LINEAR:
features = properties.linearTilingFeatures;
break;
case VK_IMAGE_TILING_OPTIMAL:
features = properties.optimalTilingFeatures;
break;
default:
UNSUPPORTED("VkImageTiling %d", int(tiling));
features = 0;
}
if(features == 0)
{
return false;
}
// Reject any usage or separate stencil usage that is not compatible with the specified format.
if(!checkFormatUsage(usage, features))
{
return false;
}
// If stencilUsage is 0 then no separate usage was provided and it takes on the same value as usage,
// which has already been checked. So only check non-zero stencilUsage.
if(stencilUsage != 0 && !checkFormatUsage(stencilUsage, features))
{
return false;
}
auto allRecognizedUsageBits = VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
ASSERT(!(usage & ~(allRecognizedUsageBits)));
if(usage & VK_IMAGE_USAGE_SAMPLED_BIT)
{
if(tiling == VK_IMAGE_TILING_LINEAR)
{
// TODO(b/171299814): Compressed formats and cube maps are not supported for sampling using VK_IMAGE_TILING_LINEAR; otherwise, sampling
// in linear tiling is always supported as long as it can be sampled when using VK_IMAGE_TILING_OPTIMAL.
if(!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ||
vk::Format(format).isCompressed() ||
(flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT))
{
return false;
}
}
else if(!(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
{
return false;
}
}
// "Images created with tiling equal to VK_IMAGE_TILING_LINEAR have further restrictions on their limits and capabilities
// compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL."
if(tiling == VK_IMAGE_TILING_LINEAR)
{
if(type != VK_IMAGE_TYPE_2D)
{
return false;
}
if(vk::Format(format).isDepth() || vk::Format(format).isStencil())
{
return false;
}
}
// "Images created with a format from one of those listed in Formats requiring sampler Y'CBCR conversion for VK_IMAGE_ASPECT_COLOR_BIT image views
// have further restrictions on their limits and capabilities compared to images created with other formats."
if(vk::Format(format).isYcbcrFormat())
{
if(type != VK_IMAGE_TYPE_2D)
{
return false;
}
}
return true;
}
void PhysicalDevice::GetFormatProperties(Format format, VkFormatProperties *pFormatProperties)
{
VkFormatProperties3 formatProperties3 = {};
GetFormatProperties(format, &formatProperties3);
// VkFormatFeatureFlags2KHR is a 64-bit extension of the 32-bit VkFormatFeatureFlags,
// so when querying the legacy flags just return the lower 32-bit portion.
pFormatProperties->linearTilingFeatures = static_cast<VkFormatFeatureFlags>(formatProperties3.linearTilingFeatures);
pFormatProperties->optimalTilingFeatures = static_cast<VkFormatFeatureFlags>(formatProperties3.optimalTilingFeatures);
pFormatProperties->bufferFeatures = static_cast<VkFormatFeatureFlags>(formatProperties3.bufferFeatures);
}
void PhysicalDevice::GetFormatProperties(Format format, VkFormatProperties3 *pFormatProperties)
{
pFormatProperties->linearTilingFeatures = 0; // Unsupported format
pFormatProperties->optimalTilingFeatures = 0; // Unsupported format
pFormatProperties->bufferFeatures = 0; // Unsupported format
switch(format)
{
// Formats which can be sampled *and* filtered
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
case VK_FORMAT_A4B4G4R4_UNORM_PACK16:
case VK_FORMAT_R5G6B5_UNORM_PACK16:
case VK_FORMAT_B5G6R5_UNORM_PACK16:
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_SRGB:
case VK_FORMAT_R8_SNORM:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R8G8_SRGB:
case VK_FORMAT_R8G8_SNORM:
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SNORM:
case VK_FORMAT_R8G8B8A8_SRGB:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16G16_UNORM:
case VK_FORMAT_R16G16_SNORM:
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_R16G16B16A16_UNORM:
case VK_FORMAT_R16G16B16A16_SNORM:
case VK_FORMAT_R16G16B16A16_SFLOAT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC2_SRGB_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC4_UNORM_BLOCK:
case VK_FORMAT_BC4_SNORM_BLOCK:
case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_BLOCK:
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
case VK_FORMAT_EAC_R11_UNORM_BLOCK:
case VK_FORMAT_EAC_R11_SNORM_BLOCK:
case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
#ifdef SWIFTSHADER_ENABLE_ASTC
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
#endif
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
// [[fallthrough]]
// Formats which can be sampled, but don't support filtering
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
case VK_FORMAT_R16_UINT:
case VK_FORMAT_R16_SINT:
case VK_FORMAT_R16G16_UINT:
case VK_FORMAT_R16G16_SINT:
case VK_FORMAT_R16G16B16A16_UINT:
case VK_FORMAT_R16G16B16A16_SINT:
case VK_FORMAT_R32_UINT:
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32G32_UINT:
case VK_FORMAT_R32G32_SINT:
case VK_FORMAT_R32G32B32A32_UINT:
case VK_FORMAT_R32G32B32A32_SINT:
case VK_FORMAT_S8_UINT:
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_BLIT_SRC_BIT |
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
break;
// YCbCr formats:
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
break;
default:
break;
}
switch(format)
{
// Vulkan 1.0 mandatory storage image formats supporting atomic operations
case VK_FORMAT_R32_UINT:
case VK_FORMAT_R32_SINT:
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
pFormatProperties->bufferFeatures |=
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
// [[fallthrough]]
// Vulkan 1.0 mandatory storage image formats
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SNORM:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_R16G16B16A16_UINT:
case VK_FORMAT_R16G16B16A16_SINT:
case VK_FORMAT_R16G16B16A16_SFLOAT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32G32_UINT:
case VK_FORMAT_R32G32_SINT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32A32_UINT:
case VK_FORMAT_R32G32B32A32_SINT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
// Vulkan 1.0 shaderStorageImageExtendedFormats
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16G16B16A16_UNORM:
case VK_FORMAT_R16G16_UNORM:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R16G16B16A16_SNORM:
case VK_FORMAT_R16G16_SNORM:
case VK_FORMAT_R8G8_SNORM:
case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R8_SNORM:
case VK_FORMAT_R16G16_SINT:
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R16_SINT:
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R16G16_UINT:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R16_UINT:
case VK_FORMAT_R8_UINT:
// Additional formats not listed under "Formats without shader storage format"
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_B8G8R8A8_SRGB:
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT |
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
pFormatProperties->bufferFeatures |=
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
break;
default:
break;
}
switch(format)
{
case VK_FORMAT_R5G6B5_UNORM_PACK16:
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
case VK_FORMAT_A4B4G4R4_UNORM_PACK16:
case VK_FORMAT_B5G6R5_UNORM_PACK16:
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SRGB:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_R16G16B16A16_SFLOAT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R16_UINT:
case VK_FORMAT_R16_SINT:
case VK_FORMAT_R16G16_UNORM:
case VK_FORMAT_R16G16_UINT:
case VK_FORMAT_R16G16_SINT:
case VK_FORMAT_R16G16B16A16_UNORM:
case VK_FORMAT_R16G16B16A16_UINT:
case VK_FORMAT_R16G16B16A16_SINT:
case VK_FORMAT_R32_UINT:
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32G32_UINT:
case VK_FORMAT_R32G32_SINT:
case VK_FORMAT_R32G32B32A32_UINT:
case VK_FORMAT_R32G32B32A32_SINT:
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_BLIT_DST_BIT;
break;
case VK_FORMAT_S8_UINT:
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_D32_SFLOAT: // Note: either VK_FORMAT_D32_SFLOAT or VK_FORMAT_X8_D24_UNORM_PACK32 must be supported
case VK_FORMAT_D32_SFLOAT_S8_UINT: // Note: either VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT must be supported
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
break;
default:
break;
}
switch(format)
{
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_D32_SFLOAT: // Note: either VK_FORMAT_D32_SFLOAT or VK_FORMAT_X8_D24_UNORM_PACK32 must be supported
case VK_FORMAT_D32_SFLOAT_S8_UINT: // Note: either VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT must be supported
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
break;
default:
break;
}
if(format.supportsColorAttachmentBlend())
{
pFormatProperties->optimalTilingFeatures |=
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
}
switch(format)
{
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_SNORM:
case VK_FORMAT_R8_USCALED:
case VK_FORMAT_R8_SSCALED:
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R8G8_SNORM:
case VK_FORMAT_R8G8_USCALED:
case VK_FORMAT_R8G8_SSCALED:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SNORM:
case VK_FORMAT_R8G8B8A8_USCALED:
case VK_FORMAT_R8G8B8A8_SSCALED:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
case VK_FORMAT_A2R10G10B10_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
case VK_FORMAT_A2B10G10R10_SINT_PACK32:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R16_USCALED:
case VK_FORMAT_R16_SSCALED:
case VK_FORMAT_R16_UINT:
case VK_FORMAT_R16_SINT:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16G16_UNORM:
case VK_FORMAT_R16G16_SNORM:
case VK_FORMAT_R16G16_USCALED:
case VK_FORMAT_R16G16_SSCALED:
case VK_FORMAT_R16G16_UINT:
case VK_FORMAT_R16G16_SINT:
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_R16G16B16A16_UNORM:
case VK_FORMAT_R16G16B16A16_SNORM:
case VK_FORMAT_R16G16B16A16_USCALED:
case VK_FORMAT_R16G16B16A16_SSCALED:
case VK_FORMAT_R16G16B16A16_UINT:
case VK_FORMAT_R16G16B16A16_SINT:
case VK_FORMAT_R16G16B16A16_SFLOAT:
case VK_FORMAT_R32_UINT:
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32G32_UINT:
case VK_FORMAT_R32G32_SINT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32_UINT:
case VK_FORMAT_R32G32B32_SINT:
case VK_FORMAT_R32G32B32_SFLOAT:
case VK_FORMAT_R32G32B32A32_UINT:
case VK_FORMAT_R32G32B32A32_SINT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
pFormatProperties->bufferFeatures |=
VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
break;
default:
break;
}
switch(format)
{
// Vulkan 1.1 mandatory
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_SNORM:
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R8G8_SNORM:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SNORM:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
case VK_FORMAT_R16_UINT:
case VK_FORMAT_R16_SINT:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16G16_UINT:
case VK_FORMAT_R16G16_SINT:
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_R16G16B16A16_UINT:
case VK_FORMAT_R16G16B16A16_SINT:
case VK_FORMAT_R16G16B16A16_SFLOAT:
case VK_FORMAT_R32_UINT:
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32G32_UINT:
case VK_FORMAT_R32G32_SINT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32A32_UINT:
case VK_FORMAT_R32G32B32A32_SINT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
// Optional
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
pFormatProperties->bufferFeatures |=
VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
break;
default:
break;
}
if(pFormatProperties->optimalTilingFeatures)
{
// "Formats that are required to support VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT must also support
// VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT."
pFormatProperties->linearTilingFeatures |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
if(!format.isCompressed())
{
VkFormatFeatureFlagBits2KHR transferableFeatureBits = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
pFormatProperties->linearTilingFeatures |= (pFormatProperties->optimalTilingFeatures & transferableFeatureBits);
}
}
}
void PhysicalDevice::getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageCreateFlags flags,
VkImageFormatProperties *pImageFormatProperties) const
{
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
pImageFormatProperties->maxArrayLayers = vk::MAX_IMAGE_ARRAY_LAYERS;
pImageFormatProperties->maxExtent.depth = 1;
switch(type)
{
case VK_IMAGE_TYPE_1D:
pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_1D;
pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_1D - 1);
pImageFormatProperties->maxExtent.height = 1;
break;
case VK_IMAGE_TYPE_2D:
if(flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
{
pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_CUBE;
pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1);
pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1);
}
else
{
pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_2D;
pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_2D - 1);
pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_2D - 1);
VkFormatProperties props;
GetFormatProperties(format, &props);
auto features = tiling == VK_IMAGE_TILING_LINEAR ? props.linearTilingFeatures : props.optimalTilingFeatures;
if(features & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
{
// Only renderable formats make sense for multisample
pImageFormatProperties->sampleCounts = getSampleCounts();
}
}
break;
case VK_IMAGE_TYPE_3D:
pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_3D;
pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
pImageFormatProperties->maxExtent.depth = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
pImageFormatProperties->maxArrayLayers = 1; // no 3D + layers
break;
default:
UNREACHABLE("VkImageType: %d", int(type));
break;
}
pImageFormatProperties->maxResourceSize = 1u << 31; // Minimum value for maxResourceSize
// "Images created with tiling equal to VK_IMAGE_TILING_LINEAR have further restrictions on their limits and capabilities
// compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL."
if(tiling == VK_IMAGE_TILING_LINEAR)
{
pImageFormatProperties->maxMipLevels = 1;
pImageFormatProperties->maxArrayLayers = 1;
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
}
// "Images created with a format from one of those listed in Formats requiring sampler Y'CbCr conversion for VK_IMAGE_ASPECT_COLOR_BIT image views
// have further restrictions on their limits and capabilities compared to images created with other formats."
if(format.isYcbcrFormat())
{
pImageFormatProperties->maxMipLevels = 1; // TODO(b/151263485): This is relied on by the sampler to disable mipmapping for Y'CbCr image sampling.
pImageFormatProperties->maxArrayLayers = 1;
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
}
}
uint32_t PhysicalDevice::getQueueFamilyPropertyCount() const
{
return 1;
}
VkQueueFamilyProperties PhysicalDevice::getQueueFamilyProperties() const
{
VkQueueFamilyProperties properties = {};
properties.minImageTransferGranularity.width = 1;
properties.minImageTransferGranularity.height = 1;
properties.minImageTransferGranularity.depth = 1;
properties.queueCount = 1;
properties.queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
properties.timestampValidBits = 64;
return properties;
}
void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,
VkQueueFamilyProperties *pQueueFamilyProperties) const
{
for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++)
{
pQueueFamilyProperties[i] = getQueueFamilyProperties();
}
}
void PhysicalDevice::getQueueFamilyGlobalPriorityProperties(VkQueueFamilyGlobalPriorityPropertiesKHR *pQueueFamilyGlobalPriorityProperties) const
{
pQueueFamilyGlobalPriorityProperties->priorityCount = 1;
pQueueFamilyGlobalPriorityProperties->priorities[0] = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR;
}
bool PhysicalDevice::validateQueueGlobalPriority(VkQueueGlobalPriorityKHR queueGlobalPriority) const
{
VkQueueFamilyGlobalPriorityPropertiesKHR queueFamilyGlobalPriorityProperties;
getQueueFamilyGlobalPriorityProperties(&queueFamilyGlobalPriorityProperties);
for(uint32_t i = 0; i < queueFamilyGlobalPriorityProperties.priorityCount; ++i)
{
if(queueGlobalPriority == queueFamilyGlobalPriorityProperties.priorities[i])
{
return true;
}
}
return false;
}
void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,
VkQueueFamilyProperties2 *pQueueFamilyProperties) const
{
for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++)
{
pQueueFamilyProperties[i].queueFamilyProperties = getQueueFamilyProperties();
VkBaseOutStructure *extInfo = reinterpret_cast<VkBaseOutStructure *>(pQueueFamilyProperties[i].pNext);
while(extInfo)
{
switch(extInfo->sType)
{
case VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR:
getQueueFamilyGlobalPriorityProperties(reinterpret_cast<VkQueueFamilyGlobalPriorityPropertiesKHR *>(extInfo));
break;
default:
UNSUPPORTED("pQueueFamilyProperties->pNext sType = %s", vk::Stringify(extInfo->sType).c_str());
break;
}
extInfo = extInfo->pNext;
}
}
}
const VkPhysicalDeviceMemoryProperties &PhysicalDevice::GetMemoryProperties()
{
static const VkPhysicalDeviceMemoryProperties properties{
1, // memoryTypeCount
{
// vk::MEMORY_TYPE_GENERIC_BIT
{
(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_HOST_CACHED_BIT), // propertyFlags
0 // heapIndex
},
},
1, // memoryHeapCount
{
{
vk::PHYSICAL_DEVICE_HEAP_SIZE, // size
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT // flags
},
}
};
return properties;
}
} // namespace vk