17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2021 Collabora Ltd. 37ec681f3Smrg * 47ec681f3Smrg * Derived from tu_formats.c which is: 57ec681f3Smrg * Copyright © 2016 Red Hat. 67ec681f3Smrg * Copyright © 2016 Bas Nieuwenhuizen 77ec681f3Smrg * 87ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 97ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 107ec681f3Smrg * to deal in the Software without restriction, including without limitation 117ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 127ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 137ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 147ec681f3Smrg * 157ec681f3Smrg * The above copyright notice and this permission notice (including the next 167ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 177ec681f3Smrg * Software. 187ec681f3Smrg * 197ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 207ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 217ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 227ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 237ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 247ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 257ec681f3Smrg * DEALINGS IN THE SOFTWARE. 267ec681f3Smrg */ 277ec681f3Smrg 287ec681f3Smrg#include "panvk_private.h" 297ec681f3Smrg 307ec681f3Smrg#include "util/format_r11g11b10f.h" 317ec681f3Smrg#include "util/format_srgb.h" 327ec681f3Smrg#include "util/half_float.h" 337ec681f3Smrg#include "vulkan/util/vk_format.h" 347ec681f3Smrg#include "vk_format.h" 357ec681f3Smrg#include "vk_util.h" 367ec681f3Smrg#include "panfrost/lib/pan_texture.h" 377ec681f3Smrg 387ec681f3Smrgstatic void 397ec681f3Smrgget_format_properties(struct panvk_physical_device *physical_device, 407ec681f3Smrg VkFormat format, 417ec681f3Smrg VkFormatProperties *out_properties) 427ec681f3Smrg{ 437ec681f3Smrg struct panfrost_device *pdev = &physical_device->pdev; 447ec681f3Smrg VkFormatFeatureFlags tex = 0, buffer = 0; 457ec681f3Smrg enum pipe_format pfmt = vk_format_to_pipe_format(format); 467ec681f3Smrg const struct panfrost_format fmt = pdev->formats[pfmt]; 477ec681f3Smrg 487ec681f3Smrg if (!pfmt || !fmt.hw) 497ec681f3Smrg goto end; 507ec681f3Smrg 517ec681f3Smrg /* 3byte formats are not supported by the buffer <-> image copy helpers. */ 527ec681f3Smrg if (util_format_get_blocksize(pfmt) == 3) 537ec681f3Smrg goto end; 547ec681f3Smrg 557ec681f3Smrg /* We don't support compressed formats yet: this is causing trouble when 567ec681f3Smrg * doing a vkCmdCopyImage() between a compressed and a non-compressed format 577ec681f3Smrg * on a tiled/AFBC resource. 587ec681f3Smrg */ 597ec681f3Smrg if (util_format_is_compressed(pfmt)) 607ec681f3Smrg goto end; 617ec681f3Smrg 627ec681f3Smrg buffer |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | 637ec681f3Smrg VK_FORMAT_FEATURE_TRANSFER_DST_BIT; 647ec681f3Smrg 657ec681f3Smrg if (fmt.bind & PIPE_BIND_VERTEX_BUFFER) 667ec681f3Smrg buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT; 677ec681f3Smrg 687ec681f3Smrg if (fmt.bind & PIPE_BIND_SAMPLER_VIEW) { 697ec681f3Smrg tex |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | 707ec681f3Smrg VK_FORMAT_FEATURE_TRANSFER_DST_BIT | 717ec681f3Smrg VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | 727ec681f3Smrg VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT | 737ec681f3Smrg VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT; 747ec681f3Smrg 757ec681f3Smrg /* Integer formats only support nearest filtering */ 767ec681f3Smrg if (!util_format_is_scaled(pfmt) && 777ec681f3Smrg !util_format_is_pure_integer(pfmt)) 787ec681f3Smrg tex |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 797ec681f3Smrg 807ec681f3Smrg buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; 817ec681f3Smrg 827ec681f3Smrg tex |= VK_FORMAT_FEATURE_BLIT_SRC_BIT; 837ec681f3Smrg } 847ec681f3Smrg 857ec681f3Smrg if (fmt.bind & PIPE_BIND_RENDER_TARGET) { 867ec681f3Smrg tex |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 877ec681f3Smrg VK_FORMAT_FEATURE_BLIT_DST_BIT; 887ec681f3Smrg 897ec681f3Smrg tex |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; 907ec681f3Smrg buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT; 917ec681f3Smrg 927ec681f3Smrg /* Can always blend via blend shaders */ 937ec681f3Smrg tex |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; 947ec681f3Smrg } 957ec681f3Smrg 967ec681f3Smrg if (fmt.bind & PIPE_BIND_DEPTH_STENCIL) 977ec681f3Smrg tex |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; 987ec681f3Smrg 997ec681f3Smrgend: 1007ec681f3Smrg out_properties->linearTilingFeatures = tex; 1017ec681f3Smrg out_properties->optimalTilingFeatures = tex; 1027ec681f3Smrg out_properties->bufferFeatures = buffer; 1037ec681f3Smrg} 1047ec681f3Smrg 1057ec681f3Smrgvoid 1067ec681f3Smrgpanvk_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, 1077ec681f3Smrg VkFormat format, 1087ec681f3Smrg VkFormatProperties *pFormatProperties) 1097ec681f3Smrg{ 1107ec681f3Smrg VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); 1117ec681f3Smrg 1127ec681f3Smrg get_format_properties(physical_device, format, pFormatProperties); 1137ec681f3Smrg} 1147ec681f3Smrg 1157ec681f3Smrgvoid 1167ec681f3Smrgpanvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, 1177ec681f3Smrg VkFormat format, 1187ec681f3Smrg VkFormatProperties2 *pFormatProperties) 1197ec681f3Smrg{ 1207ec681f3Smrg VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); 1217ec681f3Smrg 1227ec681f3Smrg get_format_properties(physical_device, format, 1237ec681f3Smrg &pFormatProperties->formatProperties); 1247ec681f3Smrg 1257ec681f3Smrg VkDrmFormatModifierPropertiesListEXT *list = 1267ec681f3Smrg vk_find_struct(pFormatProperties->pNext, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT); 1277ec681f3Smrg if (list) { 1287ec681f3Smrg VK_OUTARRAY_MAKE(out, list->pDrmFormatModifierProperties, 1297ec681f3Smrg &list->drmFormatModifierCount); 1307ec681f3Smrg 1317ec681f3Smrg vk_outarray_append(&out, mod_props) { 1327ec681f3Smrg mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; 1337ec681f3Smrg mod_props->drmFormatModifierPlaneCount = 1; 1347ec681f3Smrg } 1357ec681f3Smrg } 1367ec681f3Smrg} 1377ec681f3Smrg 1387ec681f3Smrgstatic VkResult 1397ec681f3Smrgget_image_format_properties(struct panvk_physical_device *physical_device, 1407ec681f3Smrg const VkPhysicalDeviceImageFormatInfo2 *info, 1417ec681f3Smrg VkImageFormatProperties *pImageFormatProperties, 1427ec681f3Smrg VkFormatFeatureFlags *p_feature_flags) 1437ec681f3Smrg{ 1447ec681f3Smrg VkFormatProperties format_props; 1457ec681f3Smrg VkFormatFeatureFlags format_feature_flags; 1467ec681f3Smrg VkExtent3D maxExtent; 1477ec681f3Smrg uint32_t maxMipLevels; 1487ec681f3Smrg uint32_t maxArraySize; 1497ec681f3Smrg VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1507ec681f3Smrg enum pipe_format format = vk_format_to_pipe_format(info->format); 1517ec681f3Smrg 1527ec681f3Smrg get_format_properties(physical_device, info->format, &format_props); 1537ec681f3Smrg 1547ec681f3Smrg switch (info->tiling) { 1557ec681f3Smrg case VK_IMAGE_TILING_LINEAR: 1567ec681f3Smrg format_feature_flags = format_props.linearTilingFeatures; 1577ec681f3Smrg break; 1587ec681f3Smrg 1597ec681f3Smrg case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: 1607ec681f3Smrg /* The only difference between optimal and linear is currently whether 1617ec681f3Smrg * depth/stencil attachments are allowed on depth/stencil formats. 1627ec681f3Smrg * There's no reason to allow importing depth/stencil textures, so just 1637ec681f3Smrg * disallow it and then this annoying edge case goes away. 1647ec681f3Smrg * 1657ec681f3Smrg * TODO: If anyone cares, we could enable this by looking at the 1667ec681f3Smrg * modifier and checking if it's LINEAR or not. 1677ec681f3Smrg */ 1687ec681f3Smrg if (util_format_is_depth_or_stencil(format)) 1697ec681f3Smrg goto unsupported; 1707ec681f3Smrg 1717ec681f3Smrg assert(format_props.optimalTilingFeatures == format_props.linearTilingFeatures); 1727ec681f3Smrg /* fallthrough */ 1737ec681f3Smrg case VK_IMAGE_TILING_OPTIMAL: 1747ec681f3Smrg format_feature_flags = format_props.optimalTilingFeatures; 1757ec681f3Smrg break; 1767ec681f3Smrg default: 1777ec681f3Smrg unreachable("bad VkPhysicalDeviceImageFormatInfo2"); 1787ec681f3Smrg } 1797ec681f3Smrg 1807ec681f3Smrg if (format_feature_flags == 0) 1817ec681f3Smrg goto unsupported; 1827ec681f3Smrg 1837ec681f3Smrg if (info->type != VK_IMAGE_TYPE_2D && 1847ec681f3Smrg util_format_is_depth_or_stencil(format)) 1857ec681f3Smrg goto unsupported; 1867ec681f3Smrg 1877ec681f3Smrg switch (info->type) { 1887ec681f3Smrg default: 1897ec681f3Smrg unreachable("bad vkimage type"); 1907ec681f3Smrg case VK_IMAGE_TYPE_1D: 1917ec681f3Smrg maxExtent.width = 16384; 1927ec681f3Smrg maxExtent.height = 1; 1937ec681f3Smrg maxExtent.depth = 1; 1947ec681f3Smrg maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1957ec681f3Smrg maxArraySize = 2048; 1967ec681f3Smrg break; 1977ec681f3Smrg case VK_IMAGE_TYPE_2D: 1987ec681f3Smrg maxExtent.width = 16384; 1997ec681f3Smrg maxExtent.height = 16384; 2007ec681f3Smrg maxExtent.depth = 1; 2017ec681f3Smrg maxMipLevels = 15; /* log2(maxWidth) + 1 */ 2027ec681f3Smrg maxArraySize = 2048; 2037ec681f3Smrg break; 2047ec681f3Smrg case VK_IMAGE_TYPE_3D: 2057ec681f3Smrg maxExtent.width = 2048; 2067ec681f3Smrg maxExtent.height = 2048; 2077ec681f3Smrg maxExtent.depth = 2048; 2087ec681f3Smrg maxMipLevels = 12; /* log2(maxWidth) + 1 */ 2097ec681f3Smrg maxArraySize = 1; 2107ec681f3Smrg break; 2117ec681f3Smrg } 2127ec681f3Smrg 2137ec681f3Smrg if (info->tiling == VK_IMAGE_TILING_OPTIMAL && 2147ec681f3Smrg info->type == VK_IMAGE_TYPE_2D && 2157ec681f3Smrg (format_feature_flags & 2167ec681f3Smrg (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 2177ec681f3Smrg VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) && 2187ec681f3Smrg !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 2197ec681f3Smrg !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) { 2207ec681f3Smrg sampleCounts |= VK_SAMPLE_COUNT_4_BIT; 2217ec681f3Smrg } 2227ec681f3Smrg 2237ec681f3Smrg if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) { 2247ec681f3Smrg if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 2257ec681f3Smrg goto unsupported; 2267ec681f3Smrg } 2277ec681f3Smrg } 2287ec681f3Smrg 2297ec681f3Smrg if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) { 2307ec681f3Smrg if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) { 2317ec681f3Smrg goto unsupported; 2327ec681f3Smrg } 2337ec681f3Smrg } 2347ec681f3Smrg 2357ec681f3Smrg if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 2367ec681f3Smrg if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { 2377ec681f3Smrg goto unsupported; 2387ec681f3Smrg } 2397ec681f3Smrg } 2407ec681f3Smrg 2417ec681f3Smrg if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 2427ec681f3Smrg if (!(format_feature_flags & 2437ec681f3Smrg VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 2447ec681f3Smrg goto unsupported; 2457ec681f3Smrg } 2467ec681f3Smrg } 2477ec681f3Smrg 2487ec681f3Smrg *pImageFormatProperties = (VkImageFormatProperties) { 2497ec681f3Smrg .maxExtent = maxExtent, 2507ec681f3Smrg .maxMipLevels = maxMipLevels, 2517ec681f3Smrg .maxArrayLayers = maxArraySize, 2527ec681f3Smrg .sampleCounts = sampleCounts, 2537ec681f3Smrg 2547ec681f3Smrg /* FINISHME: Accurately calculate 2557ec681f3Smrg * VkImageFormatProperties::maxResourceSize. 2567ec681f3Smrg */ 2577ec681f3Smrg .maxResourceSize = UINT32_MAX, 2587ec681f3Smrg }; 2597ec681f3Smrg 2607ec681f3Smrg if (p_feature_flags) 2617ec681f3Smrg *p_feature_flags = format_feature_flags; 2627ec681f3Smrg 2637ec681f3Smrg return VK_SUCCESS; 2647ec681f3Smrgunsupported: 2657ec681f3Smrg *pImageFormatProperties = (VkImageFormatProperties) { 2667ec681f3Smrg .maxExtent = { 0, 0, 0 }, 2677ec681f3Smrg .maxMipLevels = 0, 2687ec681f3Smrg .maxArrayLayers = 0, 2697ec681f3Smrg .sampleCounts = 0, 2707ec681f3Smrg .maxResourceSize = 0, 2717ec681f3Smrg }; 2727ec681f3Smrg 2737ec681f3Smrg return VK_ERROR_FORMAT_NOT_SUPPORTED; 2747ec681f3Smrg} 2757ec681f3Smrg 2767ec681f3Smrg 2777ec681f3SmrgVkResult 2787ec681f3Smrgpanvk_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, 2797ec681f3Smrg VkFormat format, 2807ec681f3Smrg VkImageType type, 2817ec681f3Smrg VkImageTiling tiling, 2827ec681f3Smrg VkImageUsageFlags usage, 2837ec681f3Smrg VkImageCreateFlags createFlags, 2847ec681f3Smrg VkImageFormatProperties *pImageFormatProperties) 2857ec681f3Smrg{ 2867ec681f3Smrg VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); 2877ec681f3Smrg 2887ec681f3Smrg const VkPhysicalDeviceImageFormatInfo2 info = { 2897ec681f3Smrg .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, 2907ec681f3Smrg .pNext = NULL, 2917ec681f3Smrg .format = format, 2927ec681f3Smrg .type = type, 2937ec681f3Smrg .tiling = tiling, 2947ec681f3Smrg .usage = usage, 2957ec681f3Smrg .flags = createFlags, 2967ec681f3Smrg }; 2977ec681f3Smrg 2987ec681f3Smrg return get_image_format_properties(physical_device, &info, 2997ec681f3Smrg pImageFormatProperties, NULL); 3007ec681f3Smrg} 3017ec681f3Smrg 3027ec681f3Smrgstatic VkResult 3037ec681f3Smrgpanvk_get_external_image_format_properties(const struct panvk_physical_device *physical_device, 3047ec681f3Smrg const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, 3057ec681f3Smrg VkExternalMemoryHandleTypeFlagBits handleType, 3067ec681f3Smrg VkExternalMemoryProperties *external_properties) 3077ec681f3Smrg{ 3087ec681f3Smrg VkExternalMemoryFeatureFlagBits flags = 0; 3097ec681f3Smrg VkExternalMemoryHandleTypeFlags export_flags = 0; 3107ec681f3Smrg VkExternalMemoryHandleTypeFlags compat_flags = 0; 3117ec681f3Smrg 3127ec681f3Smrg /* From the Vulkan 1.1.98 spec: 3137ec681f3Smrg * 3147ec681f3Smrg * If handleType is not compatible with the format, type, tiling, 3157ec681f3Smrg * usage, and flags specified in VkPhysicalDeviceImageFormatInfo2, 3167ec681f3Smrg * then vkGetPhysicalDeviceImageFormatProperties2 returns 3177ec681f3Smrg * VK_ERROR_FORMAT_NOT_SUPPORTED. 3187ec681f3Smrg */ 3197ec681f3Smrg switch (handleType) { 3207ec681f3Smrg case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 3217ec681f3Smrg case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 3227ec681f3Smrg switch (pImageFormatInfo->type) { 3237ec681f3Smrg case VK_IMAGE_TYPE_2D: 3247ec681f3Smrg flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT | 3257ec681f3Smrg VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 3267ec681f3Smrg VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 3277ec681f3Smrg compat_flags = export_flags = 3287ec681f3Smrg VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 3297ec681f3Smrg VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 3307ec681f3Smrg break; 3317ec681f3Smrg default: 3327ec681f3Smrg return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 3337ec681f3Smrg "VkExternalMemoryTypeFlagBits(0x%x) unsupported for VkImageType(%d)", 3347ec681f3Smrg handleType, pImageFormatInfo->type); 3357ec681f3Smrg } 3367ec681f3Smrg break; 3377ec681f3Smrg case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 3387ec681f3Smrg flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 3397ec681f3Smrg compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; 3407ec681f3Smrg break; 3417ec681f3Smrg default: 3427ec681f3Smrg return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 3437ec681f3Smrg "VkExternalMemoryTypeFlagBits(0x%x) unsupported", 3447ec681f3Smrg handleType); 3457ec681f3Smrg } 3467ec681f3Smrg 3477ec681f3Smrg *external_properties = (VkExternalMemoryProperties) { 3487ec681f3Smrg .externalMemoryFeatures = flags, 3497ec681f3Smrg .exportFromImportedHandleTypes = export_flags, 3507ec681f3Smrg .compatibleHandleTypes = compat_flags, 3517ec681f3Smrg }; 3527ec681f3Smrg 3537ec681f3Smrg return VK_SUCCESS; 3547ec681f3Smrg} 3557ec681f3Smrg 3567ec681f3SmrgVkResult 3577ec681f3Smrgpanvk_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, 3587ec681f3Smrg const VkPhysicalDeviceImageFormatInfo2 *base_info, 3597ec681f3Smrg VkImageFormatProperties2 *base_props) 3607ec681f3Smrg{ 3617ec681f3Smrg VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); 3627ec681f3Smrg const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL; 3637ec681f3Smrg const VkPhysicalDeviceImageViewImageFormatInfoEXT *image_view_info = NULL; 3647ec681f3Smrg VkExternalImageFormatProperties *external_props = NULL; 3657ec681f3Smrg VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL; 3667ec681f3Smrg VkFormatFeatureFlags format_feature_flags; 3677ec681f3Smrg VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL; 3687ec681f3Smrg VkResult result; 3697ec681f3Smrg 3707ec681f3Smrg result = get_image_format_properties(physical_device, base_info, 3717ec681f3Smrg &base_props->imageFormatProperties, 3727ec681f3Smrg &format_feature_flags); 3737ec681f3Smrg if (result != VK_SUCCESS) 3747ec681f3Smrg return result; 3757ec681f3Smrg 3767ec681f3Smrg /* Extract input structs */ 3777ec681f3Smrg vk_foreach_struct_const(s, base_info->pNext) 3787ec681f3Smrg { 3797ec681f3Smrg switch (s->sType) { 3807ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: 3817ec681f3Smrg external_info = (const void *) s; 3827ec681f3Smrg break; 3837ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT: 3847ec681f3Smrg image_view_info = (const void *) s; 3857ec681f3Smrg break; 3867ec681f3Smrg default: 3877ec681f3Smrg break; 3887ec681f3Smrg } 3897ec681f3Smrg } 3907ec681f3Smrg 3917ec681f3Smrg /* Extract output structs */ 3927ec681f3Smrg vk_foreach_struct(s, base_props->pNext) 3937ec681f3Smrg { 3947ec681f3Smrg switch (s->sType) { 3957ec681f3Smrg case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES: 3967ec681f3Smrg external_props = (void *) s; 3977ec681f3Smrg break; 3987ec681f3Smrg case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT: 3997ec681f3Smrg cubic_props = (void *) s; 4007ec681f3Smrg break; 4017ec681f3Smrg case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES: 4027ec681f3Smrg ycbcr_props = (void *) s; 4037ec681f3Smrg break; 4047ec681f3Smrg default: 4057ec681f3Smrg break; 4067ec681f3Smrg } 4077ec681f3Smrg } 4087ec681f3Smrg 4097ec681f3Smrg /* From the Vulkan 1.0.42 spec: 4107ec681f3Smrg * 4117ec681f3Smrg * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will 4127ec681f3Smrg * behave as if VkPhysicalDeviceExternalImageFormatInfo was not 4137ec681f3Smrg * present and VkExternalImageFormatProperties will be ignored. 4147ec681f3Smrg */ 4157ec681f3Smrg if (external_info && external_info->handleType != 0) { 4167ec681f3Smrg result = panvk_get_external_image_format_properties(physical_device, 4177ec681f3Smrg base_info, 4187ec681f3Smrg external_info->handleType, 4197ec681f3Smrg &external_props->externalMemoryProperties); 4207ec681f3Smrg if (result != VK_SUCCESS) 4217ec681f3Smrg goto fail; 4227ec681f3Smrg } 4237ec681f3Smrg 4247ec681f3Smrg if (cubic_props) { 4257ec681f3Smrg /* note: blob only allows cubic filtering for 2D and 2D array views 4267ec681f3Smrg * its likely we can enable it for 1D and CUBE, needs testing however 4277ec681f3Smrg */ 4287ec681f3Smrg if ((image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D || 4297ec681f3Smrg image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) && 4307ec681f3Smrg (format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) { 4317ec681f3Smrg cubic_props->filterCubic = true; 4327ec681f3Smrg cubic_props->filterCubicMinmax = true; 4337ec681f3Smrg } else { 4347ec681f3Smrg cubic_props->filterCubic = false; 4357ec681f3Smrg cubic_props->filterCubicMinmax = false; 4367ec681f3Smrg } 4377ec681f3Smrg } 4387ec681f3Smrg 4397ec681f3Smrg if (ycbcr_props) 4407ec681f3Smrg ycbcr_props->combinedImageSamplerDescriptorCount = 1; 4417ec681f3Smrg 4427ec681f3Smrg return VK_SUCCESS; 4437ec681f3Smrg 4447ec681f3Smrgfail: 4457ec681f3Smrg if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) { 4467ec681f3Smrg /* From the Vulkan 1.0.42 spec: 4477ec681f3Smrg * 4487ec681f3Smrg * If the combination of parameters to 4497ec681f3Smrg * vkGetPhysicalDeviceImageFormatProperties2 is not supported by 4507ec681f3Smrg * the implementation for use in vkCreateImage, then all members of 4517ec681f3Smrg * imageFormatProperties will be filled with zero. 4527ec681f3Smrg */ 4537ec681f3Smrg base_props->imageFormatProperties = (VkImageFormatProperties) {}; 4547ec681f3Smrg } 4557ec681f3Smrg 4567ec681f3Smrg return result; 4577ec681f3Smrg} 4587ec681f3Smrg 4597ec681f3Smrgvoid 4607ec681f3Smrgpanvk_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, 4617ec681f3Smrg VkFormat format, 4627ec681f3Smrg VkImageType type, 4637ec681f3Smrg uint32_t samples, 4647ec681f3Smrg VkImageUsageFlags usage, 4657ec681f3Smrg VkImageTiling tiling, 4667ec681f3Smrg uint32_t *pNumProperties, 4677ec681f3Smrg VkSparseImageFormatProperties *pProperties) 4687ec681f3Smrg{ 4697ec681f3Smrg panvk_stub(); 4707ec681f3Smrg} 4717ec681f3Smrg 4727ec681f3Smrgvoid 4737ec681f3Smrgpanvk_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice, 4747ec681f3Smrg const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, 4757ec681f3Smrg uint32_t *pPropertyCount, 4767ec681f3Smrg VkSparseImageFormatProperties2 *pProperties) 4777ec681f3Smrg{ 4787ec681f3Smrg panvk_stub(); 4797ec681f3Smrg} 4807ec681f3Smrg 4817ec681f3Smrgvoid 4827ec681f3Smrgpanvk_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice, 4837ec681f3Smrg const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, 4847ec681f3Smrg VkExternalBufferProperties *pExternalBufferProperties) 4857ec681f3Smrg{ 4867ec681f3Smrg panvk_stub(); 4877ec681f3Smrg} 488