| // 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.h" | |
| #include "Pipeline/SpirvShader.hpp" // sw::SIMD::Width | |
| #include <limits> | |
| #include <cstring> | |
| namespace vk | |
| { | |
| PhysicalDevice::PhysicalDevice(const void*, void* mem) | |
| { | |
| } | |
| const VkPhysicalDeviceFeatures& PhysicalDevice::getFeatures() const | |
| { | |
| static const VkPhysicalDeviceFeatures features | |
| { | |
| VK_TRUE, // robustBufferAccess | |
| VK_FALSE, // fullDrawIndexUint32 | |
| VK_FALSE, // imageCubeArray | |
| VK_TRUE, // independentBlend | |
| VK_FALSE, // geometryShader | |
| VK_FALSE, // tessellationShader | |
| VK_FALSE, // sampleRateShading | |
| VK_FALSE, // dualSrcBlend | |
| VK_FALSE, // logicOp | |
| VK_TRUE, // multiDrawIndirect | |
| VK_TRUE, // drawIndirectFirstInstance | |
| VK_FALSE, // depthClamp | |
| VK_FALSE, // depthBiasClamp | |
| VK_TRUE, // fillModeNonSolid | |
| VK_FALSE, // depthBounds | |
| VK_FALSE, // wideLines | |
| VK_FALSE, // largePoints | |
| VK_FALSE, // alphaToOne | |
| VK_FALSE, // multiViewport | |
| VK_FALSE, // samplerAnisotropy | |
| VK_TRUE, // textureCompressionETC2 | |
| VK_FALSE, // textureCompressionASTC_LDR | |
| VK_FALSE, // textureCompressionBC | |
| VK_FALSE, // occlusionQueryPrecise | |
| VK_FALSE, // pipelineStatisticsQuery | |
| VK_TRUE, // vertexPipelineStoresAndAtomics | |
| VK_TRUE, // fragmentStoresAndAtomics | |
| VK_FALSE, // shaderTessellationAndGeometryPointSize | |
| VK_FALSE, // shaderImageGatherExtended | |
| VK_FALSE, // shaderStorageImageExtendedFormats | |
| VK_FALSE, // shaderStorageImageMultisample | |
| VK_FALSE, // shaderStorageImageReadWithoutFormat | |
| VK_FALSE, // shaderStorageImageWriteWithoutFormat | |
| VK_FALSE, // shaderUniformBufferArrayDynamicIndexing | |
| VK_FALSE, // shaderSampledImageArrayDynamicIndexing | |
| VK_FALSE, // shaderStorageBufferArrayDynamicIndexing | |
| VK_FALSE, // shaderStorageImageArrayDynamicIndexing | |
| VK_FALSE, // shaderClipDistance | |
| VK_FALSE, // 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_FALSE, // variableMultisampleRate | |
| VK_FALSE, // inheritedQueries | |
| }; | |
| return features; | |
| } | |
| void PhysicalDevice::getFeatures(VkPhysicalDeviceSamplerYcbcrConversionFeatures* features) const | |
| { | |
| features->samplerYcbcrConversion = VK_TRUE; | |
| } | |
| void PhysicalDevice::getFeatures(VkPhysicalDevice16BitStorageFeatures* features) const | |
| { | |
| features->storageBuffer16BitAccess = VK_FALSE; | |
| features->storageInputOutput16 = VK_FALSE; | |
| features->storagePushConstant16 = VK_FALSE; | |
| features->uniformAndStorageBuffer16BitAccess = VK_FALSE; | |
| } | |
| void PhysicalDevice::getFeatures(VkPhysicalDeviceVariablePointerFeatures* features) const | |
| { | |
| features->variablePointersStorageBuffer = VK_FALSE; | |
| features->variablePointers = VK_FALSE; | |
| } | |
| void PhysicalDevice::getFeatures(VkPhysicalDevice8BitStorageFeaturesKHR* features) const | |
| { | |
| features->storageBuffer8BitAccess = VK_FALSE; | |
| features->uniformAndStorageBuffer8BitAccess = VK_FALSE; | |
| features->storagePushConstant8 = VK_FALSE; | |
| } | |
| void PhysicalDevice::getFeatures(VkPhysicalDeviceMultiviewFeatures* features) const | |
| { | |
| features->multiview = VK_TRUE; | |
| features->multiviewGeometryShader = VK_FALSE; | |
| features->multiviewTessellationShader = VK_FALSE; | |
| } | |
| void PhysicalDevice::getFeatures(VkPhysicalDeviceProtectedMemoryFeatures* features) const | |
| { | |
| features->protectedMemory = VK_FALSE; | |
| } | |
| void PhysicalDevice::getFeatures(VkPhysicalDeviceShaderDrawParameterFeatures* features) const | |
| { | |
| features->shaderDrawParameters = VK_FALSE; | |
| } | |
| VkSampleCountFlags PhysicalDevice::getSampleCounts() const | |
| { | |
| return VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; | |
| } | |
| const VkPhysicalDeviceLimits& PhysicalDevice::getLimits() const | |
| { | |
| 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 | |
| 4, // maxPerStageDescriptorStorageBuffers | |
| 16, // maxPerStageDescriptorSampledImages | |
| 4, // maxPerStageDescriptorStorageImages | |
| 4, // 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 | |
| 4, // 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 | |
| 4, // maxFragmentOutputAttachments | |
| 1, // maxFragmentDualSrcAttachments | |
| 4, // maxFragmentCombinedOutputResources | |
| 16384, // maxComputeSharedMemorySize | |
| { 65535, 65535, 65535 }, // maxComputeWorkGroupCount[3] | |
| 128, // maxComputeWorkGroupInvocations | |
| { 128, 128, 64, }, // maxComputeWorkGroupSize[3] | |
| 4, // subPixelPrecisionBits | |
| 4, // subTexelPrecisionBits | |
| 4, // mipmapPrecisionBits | |
| UINT32_MAX, // maxDrawIndexedIndexValue | |
| UINT32_MAX, // maxDrawIndirectCount | |
| vk::MAX_SAMPLER_LOD_BIAS, // maxSamplerLodBias | |
| 16, // maxSamplerAnisotropy | |
| 16, // maxViewports | |
| { 4096, 4096 }, // maxViewportDimensions[2] | |
| { -8192, 8191 }, // 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 | |
| 4096, // maxFramebufferWidth | |
| 4096, // maxFramebufferHeight | |
| 256, // maxFramebufferLayers | |
| sampleCounts, // framebufferColorSampleCounts | |
| sampleCounts, // framebufferDepthSampleCounts | |
| sampleCounts, // framebufferStencilSampleCounts | |
| sampleCounts, // framebufferNoAttachmentsSampleCounts | |
| 4, // maxColorAttachments | |
| sampleCounts, // sampledImageColorSampleCounts | |
| VK_SAMPLE_COUNT_1_BIT, // sampledImageIntegerSampleCounts | |
| sampleCounts, // sampledImageDepthSampleCounts | |
| sampleCounts, // sampledImageStencilSampleCounts | |
| VK_SAMPLE_COUNT_1_BIT, // storageImageSampleCounts (unsupported) | |
| 1, // maxSampleMaskWords | |
| VK_FALSE, // timestampComputeAndGraphics | |
| 60, // timestampPeriod | |
| 8, // maxClipDistances | |
| 8, // maxCullDistances | |
| 8, // 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 | |
| { | |
| static const VkPhysicalDeviceProperties properties | |
| { | |
| API_VERSION, | |
| DRIVER_VERSION, | |
| VENDOR_ID, | |
| DEVICE_ID, | |
| VK_PHYSICAL_DEVICE_TYPE_CPU, // deviceType | |
| SWIFTSHADER_DEVICE_NAME, // deviceName | |
| SWIFTSHADER_UUID, // pipelineCacheUUID | |
| getLimits(), // limits | |
| {} // sparseProperties | |
| }; | |
| return properties; | |
| } | |
| void PhysicalDevice::getProperties(VkPhysicalDeviceIDProperties* properties) const | |
| { | |
| 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(VkPhysicalDeviceMaintenance3Properties* properties) const | |
| { | |
| properties->maxMemoryAllocationSize = 1u << 31; | |
| properties->maxPerSetDescriptors = 1024; | |
| } | |
| void PhysicalDevice::getProperties(VkPhysicalDeviceMultiviewProperties* properties) const | |
| { | |
| properties->maxMultiviewViewCount = 6; | |
| properties->maxMultiviewInstanceIndex = 1u<<27; | |
| } | |
| void PhysicalDevice::getProperties(VkPhysicalDevicePointClippingProperties* properties) const | |
| { | |
| properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES; | |
| } | |
| void PhysicalDevice::getProperties(VkPhysicalDeviceProtectedMemoryProperties* properties) const | |
| { | |
| properties->protectedNoFault = VK_FALSE; | |
| } | |
| 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_BALLOT_BIT | | |
| VK_SUBGROUP_FEATURE_SHUFFLE_BIT | | |
| VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT; | |
| properties->quadOperationsInAllStages = VK_FALSE; | |
| } | |
| void PhysicalDevice::getProperties(const VkExternalMemoryHandleTypeFlagBits* handleType, VkExternalImageFormatProperties* properties) const | |
| { | |
| properties->externalMemoryProperties.compatibleHandleTypes = 0; | |
| properties->externalMemoryProperties.exportFromImportedHandleTypes = 0; | |
| properties->externalMemoryProperties.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; | |
| } | |
| #endif | |
| void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties) const | |
| { | |
| pExternalBufferProperties->externalMemoryProperties.compatibleHandleTypes = 0; | |
| pExternalBufferProperties->externalMemoryProperties.exportFromImportedHandleTypes = 0; | |
| pExternalBufferProperties->externalMemoryProperties.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 | |
| { | |
| pExternalSemaphoreProperties->compatibleHandleTypes = 0; | |
| pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0; | |
| pExternalSemaphoreProperties->externalSemaphoreFeatures = 0; | |
| } | |
| void PhysicalDevice::getProperties(VkPhysicalDeviceDriverPropertiesKHR* properties) const | |
| { | |
| properties->driverID = VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR; | |
| strcpy(properties->driverName, "SwiftShader driver"); | |
| strcpy(properties->driverInfo, ""); | |
| properties->conformanceVersion = {1, 1, 3, 3}; | |
| } | |
| 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_TRUE) && (supportedFeature[i] != VK_TRUE)) | |
| { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties* pFormatProperties) const | |
| { | |
| 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_R16_SFLOAT: | |
| case VK_FORMAT_R16G16_SFLOAT: | |
| case VK_FORMAT_R16G16B16A16_SFLOAT: | |
| case VK_FORMAT_B10G11R11_UFLOAT_PACK32: | |
| case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: | |
| 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: | |
| pFormatProperties->optimalTilingFeatures |= | |
| VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; | |
| // Fall through | |
| // 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_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_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_S8_UINT: | |
| case VK_FORMAT_D16_UNORM: | |
| case VK_FORMAT_D32_SFLOAT: | |
| case VK_FORMAT_D32_SFLOAT_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_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; | |
| // Fall through | |
| 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: | |
| pFormatProperties->optimalTilingFeatures |= | |
| VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; | |
| // Fall through | |
| case VK_FORMAT_A8B8G8R8_UNORM_PACK32: | |
| case VK_FORMAT_A8B8G8R8_SNORM_PACK32: | |
| case VK_FORMAT_A8B8G8R8_UINT_PACK32: | |
| case VK_FORMAT_A8B8G8R8_SINT_PACK32: | |
| 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_R16_SFLOAT: | |
| case VK_FORMAT_R16G16_SFLOAT: | |
| case VK_FORMAT_R16G16B16A16_SFLOAT: | |
| pFormatProperties->optimalTilingFeatures |= | |
| VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; | |
| // Fall through | |
| 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_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_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: | |
| 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_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_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) | |
| { | |
| 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: | |
| 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; | |
| } | |
| } | |
| 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; | |
| pImageFormatProperties->maxArrayLayers = 1; | |
| pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT; | |
| } | |
| } | |
| uint32_t PhysicalDevice::getQueueFamilyPropertyCount() const | |
| { | |
| return 1; | |
| } | |
| void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount, | |
| VkQueueFamilyProperties* pQueueFamilyProperties) const | |
| { | |
| for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++) | |
| { | |
| pQueueFamilyProperties[i].minImageTransferGranularity.width = 1; | |
| pQueueFamilyProperties[i].minImageTransferGranularity.height = 1; | |
| pQueueFamilyProperties[i].minImageTransferGranularity.depth = 1; | |
| pQueueFamilyProperties[i].queueCount = 1; | |
| pQueueFamilyProperties[i].queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT; | |
| pQueueFamilyProperties[i].timestampValidBits = 0; // No support for time stamps | |
| } | |
| } | |
| const VkPhysicalDeviceMemoryProperties& PhysicalDevice::getMemoryProperties() const | |
| { | |
| 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 |