Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_formats.c
4565 views
/*1* Copyright © 2019 Red Hat.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "lvp_private.h"24#include "util/format/u_format.h"25#include "util/u_math.h"26#include "vk_util.h"2728static bool lvp_is_filter_minmax_format_supported(VkFormat format)29{30/* From the Vulkan spec 1.1.71:31*32* "The following formats must support the33* VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with34* VK_IMAGE_TILING_OPTIMAL, if they support35* VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT."36*/37/* TODO: enable more formats. */38switch (format) {39case VK_FORMAT_R8_UNORM:40case VK_FORMAT_R8_SNORM:41case VK_FORMAT_R16_UNORM:42case VK_FORMAT_R16_SNORM:43case VK_FORMAT_R16_SFLOAT:44case VK_FORMAT_R32_SFLOAT:45case VK_FORMAT_D16_UNORM:46case VK_FORMAT_X8_D24_UNORM_PACK32:47case VK_FORMAT_D32_SFLOAT:48case VK_FORMAT_D16_UNORM_S8_UINT:49case VK_FORMAT_D24_UNORM_S8_UINT:50case VK_FORMAT_D32_SFLOAT_S8_UINT:51return true;52default:53return false;54}55}5657static void58lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_device,59VkFormat format,60VkFormatProperties *out_properties)61{62enum pipe_format pformat = lvp_vk_format_to_pipe_format(format);63unsigned features = 0, buffer_features = 0;64if (pformat == PIPE_FORMAT_NONE) {65out_properties->linearTilingFeatures = 0;66out_properties->optimalTilingFeatures = 0;67out_properties->bufferFeatures = 0;68return;69}7071if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,72PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_DEPTH_STENCIL)) {73out_properties->linearTilingFeatures = 0;74out_properties->optimalTilingFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |75VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT |76VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;7778if (lvp_is_filter_minmax_format_supported(format))79out_properties->optimalTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;80out_properties->bufferFeatures = 0;81return;82}8384if (util_format_is_compressed(pformat)) {85if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,86PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {87features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;88features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;89features |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;90features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;91}92out_properties->linearTilingFeatures = features;93out_properties->optimalTilingFeatures = features;94out_properties->bufferFeatures = buffer_features;95return;96}9798if (!util_format_is_srgb(pformat) &&99physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,100PIPE_BUFFER, 0, 0, PIPE_BIND_VERTEX_BUFFER)) {101buffer_features |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;102}103104if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,105PIPE_BUFFER, 0, 0, PIPE_BIND_CONSTANT_BUFFER)) {106buffer_features |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;107}108109if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,110PIPE_BUFFER, 0, 0, PIPE_BIND_SHADER_IMAGE)) {111buffer_features |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;112}113114if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,115PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {116features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;117if (!util_format_is_pure_integer(pformat))118features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;119if (lvp_is_filter_minmax_format_supported(format))120features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;121}122123if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,124PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_RENDER_TARGET)) {125features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;126/* SNORM blending on llvmpipe fails CTS - disable for now */127if (!util_format_is_snorm(pformat))128features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;129}130131if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,132PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SHADER_IMAGE)) {133features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;134}135136if (pformat == PIPE_FORMAT_R32_UINT || pformat == PIPE_FORMAT_R32_SINT) {137features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;138buffer_features |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;139}140141if (pformat == PIPE_FORMAT_R11G11B10_FLOAT || pformat == PIPE_FORMAT_R9G9B9E5_FLOAT)142features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;143144if (features && buffer_features != VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)145features |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;146if (pformat == PIPE_FORMAT_B5G6R5_UNORM)147features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;148if ((pformat != PIPE_FORMAT_R9G9B9E5_FLOAT) && util_format_get_nr_components(pformat) != 3 &&149pformat != PIPE_FORMAT_R10G10B10A2_SNORM && pformat != PIPE_FORMAT_B10G10R10A2_SNORM &&150pformat != PIPE_FORMAT_B10G10R10A2_UNORM) {151features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;152}153out_properties->linearTilingFeatures = features;154out_properties->optimalTilingFeatures = features;155out_properties->bufferFeatures = buffer_features;156return;157}158159VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFormatProperties2(160VkPhysicalDevice physicalDevice,161VkFormat format,162VkFormatProperties2* pFormatProperties)163{164LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);165166lvp_physical_device_get_format_properties(physical_device,167format,168&pFormatProperties->formatProperties);169}170static VkResult lvp_get_image_format_properties(struct lvp_physical_device *physical_device,171const VkPhysicalDeviceImageFormatInfo2 *info,172VkImageFormatProperties *pImageFormatProperties)173{174VkFormatProperties format_props;175VkFormatFeatureFlags format_feature_flags;176VkExtent3D maxExtent;177uint32_t maxMipLevels;178uint32_t maxArraySize;179VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;180enum pipe_format pformat = lvp_vk_format_to_pipe_format(info->format);181lvp_physical_device_get_format_properties(physical_device, info->format,182&format_props);183if (info->tiling == VK_IMAGE_TILING_LINEAR) {184format_feature_flags = format_props.linearTilingFeatures;185} else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {186format_feature_flags = format_props.optimalTilingFeatures;187} else {188unreachable("bad VkImageTiling");189}190191if (format_feature_flags == 0)192goto unsupported;193194uint32_t max_2d_ext = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE);195uint32_t max_layers = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);196switch (info->type) {197default:198unreachable("bad vkimage type\n");199case VK_IMAGE_TYPE_1D:200if (util_format_is_compressed(pformat))201goto unsupported;202203maxExtent.width = max_2d_ext;204maxExtent.height = 1;205maxExtent.depth = 1;206maxMipLevels = util_logbase2(max_2d_ext) + 1;207maxArraySize = max_layers;208break;209case VK_IMAGE_TYPE_2D:210maxExtent.width = max_2d_ext;211maxExtent.height = max_2d_ext;212maxExtent.depth = 1;213maxMipLevels = util_logbase2(max_2d_ext) + 1;214maxArraySize = max_layers;215if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&216!(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&217!util_format_is_compressed(pformat) &&218(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)))219sampleCounts |= VK_SAMPLE_COUNT_4_BIT;220break;221case VK_IMAGE_TYPE_3D:222maxExtent.width = max_2d_ext;223maxExtent.height = max_2d_ext;224maxExtent.depth = (1 << physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS));225maxMipLevels = util_logbase2(max_2d_ext) + 1;226maxArraySize = 1;227break;228}229230if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {231if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {232goto unsupported;233}234}235236if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {237if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {238goto unsupported;239}240}241242if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {243if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {244goto unsupported;245}246}247248if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {249if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {250goto unsupported;251}252}253254if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {255if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {256goto unsupported;257}258}259260if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {261if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) {262goto unsupported;263}264}265266if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {267if (!(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |268VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) {269goto unsupported;270}271}272273*pImageFormatProperties = (VkImageFormatProperties) {274.maxExtent = maxExtent,275.maxMipLevels = maxMipLevels,276.maxArrayLayers = maxArraySize,277.sampleCounts = sampleCounts,278279/* FINISHME: Accurately calculate280* VkImageFormatProperties::maxResourceSize.281*/282.maxResourceSize = UINT32_MAX,283};284return VK_SUCCESS;285unsupported:286*pImageFormatProperties = (VkImageFormatProperties) {287.maxExtent = { 0, 0, 0 },288.maxMipLevels = 0,289.maxArrayLayers = 0,290.sampleCounts = 0,291.maxResourceSize = 0,292};293294return VK_ERROR_FORMAT_NOT_SUPPORTED;295}296297VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceImageFormatProperties2(298VkPhysicalDevice physicalDevice,299const VkPhysicalDeviceImageFormatInfo2 *base_info,300VkImageFormatProperties2 *base_props)301{302LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);303const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;304VkExternalImageFormatProperties *external_props = NULL;305VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;306VkResult result;307result = lvp_get_image_format_properties(physical_device, base_info,308&base_props->imageFormatProperties);309if (result != VK_SUCCESS)310return result;311312vk_foreach_struct_const(s, base_info->pNext) {313switch (s->sType) {314case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:315external_info = (const void *) s;316break;317default:318break;319}320}321322/* Extract output structs */323vk_foreach_struct(s, base_props->pNext) {324switch (s->sType) {325case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:326external_props = (void *) s;327break;328case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:329ycbcr_props = (void *) s;330break;331default:332break;333}334}335336if (external_info && external_info->handleType != 0) {337external_props->externalMemoryProperties = (VkExternalMemoryProperties) {338.externalMemoryFeatures = 0,339.exportFromImportedHandleTypes = 0,340.compatibleHandleTypes = 0,341};342}343if (ycbcr_props)344ycbcr_props->combinedImageSamplerDescriptorCount = 0;345return VK_SUCCESS;346}347348VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties(349VkPhysicalDevice physicalDevice,350VkFormat format,351VkImageType type,352uint32_t samples,353VkImageUsageFlags usage,354VkImageTiling tiling,355uint32_t* pNumProperties,356VkSparseImageFormatProperties* pProperties)357{358/* Sparse images are not yet supported. */359*pNumProperties = 0;360}361362VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties2(363VkPhysicalDevice physicalDevice,364const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,365uint32_t *pPropertyCount,366VkSparseImageFormatProperties2 *pProperties)367{368/* Sparse images are not yet supported. */369*pPropertyCount = 0;370}371372VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalBufferProperties(373VkPhysicalDevice physicalDevice,374const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,375VkExternalBufferProperties *pExternalBufferProperties)376{377pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties) {378.externalMemoryFeatures = 0,379.exportFromImportedHandleTypes = 0,380.compatibleHandleTypes = 0,381};382}383384385