| // 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_FALSE, // 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; |
| } |
| |
| template<typename T> |
| static void getPhysicalDeviceHostQueryResetFeatures(T *features) |
| { |
| features->hostQueryReset = VK_TRUE; |
| } |
| |
| template<typename T> |
| static void getPhysicalDeviceImageRobustnessFeaturesEXT(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_FALSE; |
| features->shaderStorageTexelBufferArrayDynamicIndexing = VK_FALSE; |
| features->shaderUniformBufferArrayNonUniformIndexing = VK_FALSE; |
| features->shaderSampledImageArrayNonUniformIndexing = VK_FALSE; |
| features->shaderStorageBufferArrayNonUniformIndexing = VK_FALSE; |
| features->shaderStorageImageArrayNonUniformIndexing = VK_FALSE; |
| features->shaderInputAttachmentArrayNonUniformIndexing = VK_FALSE; |
| features->shaderUniformTexelBufferArrayNonUniformIndexing = VK_FALSE; |
| features->shaderStorageTexelBufferArrayNonUniformIndexing = VK_FALSE; |
| features->descriptorBindingUniformBufferUpdateAfterBind = VK_FALSE; |
| features->descriptorBindingSampledImageUpdateAfterBind = VK_FALSE; |
| features->descriptorBindingStorageImageUpdateAfterBind = VK_FALSE; |
| features->descriptorBindingStorageBufferUpdateAfterBind = VK_FALSE; |
| features->descriptorBindingUniformTexelBufferUpdateAfterBind = VK_FALSE; |
| features->descriptorBindingStorageTexelBufferUpdateAfterBind = VK_FALSE; |
| features->descriptorBindingUpdateUnusedWhilePending = VK_FALSE; |
| features->descriptorBindingPartiallyBound = VK_FALSE; |
| features->descriptorBindingVariableDescriptorCount = VK_FALSE; |
| features->runtimeDescriptorArray = VK_FALSE; |
| } |
| |
| template<typename T> |
| static void getPhysicalDeviceVulkanMemoryModelFeatures(T *features) |
| { |
| features->vulkanMemoryModel = VK_FALSE; |
| features->vulkanMemoryModelDeviceScope = VK_FALSE; |
| features->vulkanMemoryModelAvailabilityVisibilityChains = VK_FALSE; |
| } |
| |
| 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_FALSE; |
| features->bufferDeviceAddressCaptureReplay = VK_FALSE; |
| features->bufferDeviceAddressMultiDevice = VK_FALSE; |
| } |
| |
| template<typename T> |
| static void getPhysicalDeviceVulkan12Features(T *features) |
| { |
| features->samplerMirrorClampToEdge = VK_FALSE; |
| features->drawIndirectCount = VK_FALSE; |
| getPhysicalDevice8BitStorageFeaturesKHR(features); |
| getPhysicalDeviceShaderAtomicInt64Features(features); |
| getPhysicalDeviceShaderFloat16Int8Features(features); |
| features->descriptorIndexing = VK_FALSE; |
| 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; |
| } |
| |
| void PhysicalDevice::getFeatures2(VkPhysicalDeviceFeatures2 *features) const |
| { |
| features->features = getFeatures(); |
| VkBaseOutStructure *curExtension = reinterpret_cast<VkBaseOutStructure *>(features->pNext); |
| while(curExtension != nullptr) |
| { |
| // Need to switch on an integer since Provoking Vertex isn't a part of the Vulkan spec. |
| switch((int)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_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_IMAGE_ROBUSTNESS_FEATURES_EXT: |
| getPhysicalDeviceImageRobustnessFeaturesEXT(reinterpret_cast<VkPhysicalDeviceImageRobustnessFeaturesEXT *>(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_KHR: |
| 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_KHR: |
| 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_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; |
| default: |
| LOG_TRAP("curExtension->pNext->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 |
| 16384, // maxUniformBufferRange |
| (1ul << 27), // maxStorageBufferRange |
| vk::MAX_PUSH_CONSTANT_SIZE, // maxPushConstantsSize |
| 4096, // maxMemoryAllocationCount |
| 4000, // maxSamplerAllocationCount |
| 131072, // bufferImageGranularity |
| 0, // sparseAddressSpaceSize (unsupported) |
| MAX_BOUND_DESCRIPTOR_SETS, // maxBoundDescriptorSets |
| 16, // maxPerStageDescriptorSamplers |
| 14, // maxPerStageDescriptorUniformBuffers |
| 16, // maxPerStageDescriptorStorageBuffers |
| 16, // maxPerStageDescriptorSampledImages |
| 4, // maxPerStageDescriptorStorageImages |
| sw::RENDERTARGETS, // maxPerStageDescriptorInputAttachments |
| 128, // maxPerStageResources |
| 96, // maxDescriptorSetSamplers |
| 72, // maxDescriptorSetUniformBuffers |
| MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS_DYNAMIC, // maxDescriptorSetUniformBuffersDynamic |
| 24, // maxDescriptorSetStorageBuffers |
| MAX_DESCRIPTOR_SET_STORAGE_BUFFERS_DYNAMIC, // maxDescriptorSetStorageBuffersDynamic |
| 96, // maxDescriptorSetSampledImages |
| 24, // maxDescriptorSetStorageImages |
| sw::RENDERTARGETS, // 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::RENDERTARGETS, // maxFragmentOutputAttachments |
| 1, // maxFragmentDualSrcAttachments |
| 28, // maxFragmentCombinedOutputResources |
| 16384, // maxComputeSharedMemorySize |
| { 65535, 65535, 65535 }, // maxComputeWorkGroupCount[3] |
| 256, // maxComputeWorkGroupInvocations |
| { 256, 256, 64 }, // maxComputeWorkGroupSize[3] |
| vk::SUBPIXEL_PRECISION_BITS, // subPixelPrecisionBits |
| 4, // subTexelPrecisionBits |
| 4, // mipmapPrecisionBits |
| UINT32_MAX, // maxDrawIndexedIndexValue |
| UINT32_MAX, // maxDrawIndirectCount |
| vk::MAX_SAMPLER_LOD_BIAS, // maxSamplerLodBias |
| 16, // maxSamplerAnisotropy |
| 16, // 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 |
| 64, // 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::RENDERTARGETS, // 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::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; |
| } |
| |
| void PhysicalDevice::getProperties(VkPhysicalDeviceMaintenance3Properties *properties) const |
| { |
| getMaintenance3Properties(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); |
| } |
| |
| void PhysicalDevice::getProperties(VkPhysicalDeviceSubgroupProperties *properties) const |
| { |
| 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; |
| properties->quadOperationsInAllStages = VK_FALSE; |
| } |
| |
| 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_TEMP_ZIRCON_VMO_BIT_FUCHSIA) |
| { |
| properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA; |
| properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA; |
| properties->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_TEMP_ZIRCON_VMO_BIT_FUCHSIA) |
| { |
| properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA; |
| properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA; |
| properties->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_TEMP_ZIRCON_EVENT_BIT_FUCHSIA) |
| { |
| pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA; |
| pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_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 = REQUIRED_MEMORY_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, 1, 3, 3 }; |
| } |
| |
| void PhysicalDevice::getProperties(VkPhysicalDeviceDriverPropertiesKHR *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 ±∞ 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_FALSE; |
| properties->shaderSignedZeroInfNanPreserveFloat32 = VK_FALSE; |
| properties->shaderSignedZeroInfNanPreserveFloat64 = VK_FALSE; |
| 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(); |
| |
| properties->maxUpdateAfterBindDescriptorsInAllPools = 0; |
| 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 = limits.maxPerStageDescriptorSamplers; |
| properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers = limits.maxPerStageDescriptorUniformBuffers; |
| properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers = limits.maxPerStageDescriptorStorageBuffers; |
| properties->maxPerStageDescriptorUpdateAfterBindSampledImages = limits.maxPerStageDescriptorSampledImages; |
| properties->maxPerStageDescriptorUpdateAfterBindStorageImages = limits.maxPerStageDescriptorStorageImages; |
| properties->maxPerStageDescriptorUpdateAfterBindInputAttachments = limits.maxPerStageDescriptorInputAttachments; |
| properties->maxPerStageUpdateAfterBindResources = limits.maxPerStageResources; |
| properties->maxDescriptorSetUpdateAfterBindSamplers = limits.maxDescriptorSetSamplers; |
| properties->maxDescriptorSetUpdateAfterBindUniformBuffers = limits.maxDescriptorSetUniformBuffers; |
| properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = limits.maxDescriptorSetUniformBuffersDynamic; |
| properties->maxDescriptorSetUpdateAfterBindStorageBuffers = limits.maxDescriptorSetStorageBuffers; |
| properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = limits.maxDescriptorSetStorageBuffersDynamic; |
| properties->maxDescriptorSetUpdateAfterBindSampledImages = limits.maxDescriptorSetSampledImages; |
| properties->maxDescriptorSetUpdateAfterBindStorageImages = limits.maxDescriptorSetStorageImages; |
| 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); |
| } |
| |
| 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); |
| } |
| |
| 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; |
| } |
| |
| 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; |
| } |
| |
| void PhysicalDevice::GetFormatProperties(Format format, VkFormatProperties *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_B4G4R4A4_UNORM_PACK16: |
| case VK_FORMAT_R5G6B5_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: |
| 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) |
| { |
| 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]] |
| case VK_FORMAT_R8G8B8A8_UNORM: |
| case VK_FORMAT_R8G8B8A8_SNORM: |
| case VK_FORMAT_R8G8B8A8_UINT: |
| case VK_FORMAT_R8G8B8A8_SINT: |
| 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_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: |
| // 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_A2B10G10R10_UNORM_PACK32: |
| 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_A2B10G10R10_UINT_PACK32: |
| case VK_FORMAT_R16G16_UINT: |
| case VK_FORMAT_R8G8_UINT: |
| case VK_FORMAT_R16_UINT: |
| case VK_FORMAT_R8_UINT: |
| pFormatProperties->optimalTilingFeatures |= |
| VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; |
| // [[fallthrough]] |
| 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_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_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: |
| 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; |
| } |
| |
| 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_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_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_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_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_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) |
| { |
| pFormatProperties->linearTilingFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | |
| VK_FORMAT_FEATURE_TRANSFER_DST_BIT; |
| |
| if(!format.isCompressed()) |
| { |
| if(pFormatProperties->optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) |
| { |
| pFormatProperties->linearTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; |
| } |
| if(pFormatProperties->optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) |
| { |
| pFormatProperties->linearTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; |
| } |
| } |
| } |
| } |
| |
| 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::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount, |
| VkQueueFamilyProperties2 *pQueueFamilyProperties) const |
| { |
| for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++) |
| { |
| pQueueFamilyProperties[i].queueFamilyProperties = getQueueFamilyProperties(); |
| } |
| } |
| |
| 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 |
| { |
| { |
| 1ull << 31, // size, FIXME(sugoi): This should be configurable based on available RAM |
| VK_MEMORY_HEAP_DEVICE_LOCAL_BIT // flags |
| }, |
| } |
| }; |
| |
| return properties; |
| } |
| |
| } // namespace vk |