1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Derived from tu_formats.c which is: 5bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 6bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 10bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 11bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 13bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 16bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 17bf215546Sopenharmony_ci * Software. 18bf215546Sopenharmony_ci * 19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "panvk_private.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "util/format_r11g11b10f.h" 31bf215546Sopenharmony_ci#include "util/format_srgb.h" 32bf215546Sopenharmony_ci#include "util/half_float.h" 33bf215546Sopenharmony_ci#include "vulkan/util/vk_format.h" 34bf215546Sopenharmony_ci#include "vk_format.h" 35bf215546Sopenharmony_ci#include "vk_util.h" 36bf215546Sopenharmony_ci#include "panfrost/lib/pan_texture.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_cistatic void 39bf215546Sopenharmony_ciget_format_properties(struct panvk_physical_device *physical_device, 40bf215546Sopenharmony_ci VkFormat format, 41bf215546Sopenharmony_ci VkFormatProperties *out_properties) 42bf215546Sopenharmony_ci{ 43bf215546Sopenharmony_ci struct panfrost_device *pdev = &physical_device->pdev; 44bf215546Sopenharmony_ci VkFormatFeatureFlags tex = 0, buffer = 0; 45bf215546Sopenharmony_ci enum pipe_format pfmt = vk_format_to_pipe_format(format); 46bf215546Sopenharmony_ci const struct panfrost_format fmt = pdev->formats[pfmt]; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci if (!pfmt || !fmt.hw) 49bf215546Sopenharmony_ci goto end; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci /* 3byte formats are not supported by the buffer <-> image copy helpers. */ 52bf215546Sopenharmony_ci if (util_format_get_blocksize(pfmt) == 3) 53bf215546Sopenharmony_ci goto end; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci /* We don't support compressed formats yet: this is causing trouble when 56bf215546Sopenharmony_ci * doing a vkCmdCopyImage() between a compressed and a non-compressed format 57bf215546Sopenharmony_ci * on a tiled/AFBC resource. 58bf215546Sopenharmony_ci */ 59bf215546Sopenharmony_ci if (util_format_is_compressed(pfmt)) 60bf215546Sopenharmony_ci goto end; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | 63bf215546Sopenharmony_ci VK_FORMAT_FEATURE_TRANSFER_DST_BIT; 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci if (fmt.bind & PIPE_BIND_VERTEX_BUFFER) 66bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT; 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci if (fmt.bind & PIPE_BIND_SAMPLER_VIEW) { 69bf215546Sopenharmony_ci tex |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | 70bf215546Sopenharmony_ci VK_FORMAT_FEATURE_TRANSFER_DST_BIT | 71bf215546Sopenharmony_ci VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | 72bf215546Sopenharmony_ci VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT | 73bf215546Sopenharmony_ci VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci /* Integer formats only support nearest filtering */ 76bf215546Sopenharmony_ci if (!util_format_is_scaled(pfmt) && 77bf215546Sopenharmony_ci !util_format_is_pure_integer(pfmt)) 78bf215546Sopenharmony_ci tex |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci tex |= VK_FORMAT_FEATURE_BLIT_SRC_BIT; 83bf215546Sopenharmony_ci } 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci if (fmt.bind & PIPE_BIND_RENDER_TARGET) { 86bf215546Sopenharmony_ci tex |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 87bf215546Sopenharmony_ci VK_FORMAT_FEATURE_BLIT_DST_BIT; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci tex |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; 90bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT; 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci /* Can always blend via blend shaders */ 93bf215546Sopenharmony_ci tex |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci if (fmt.bind & PIPE_BIND_DEPTH_STENCIL) 97bf215546Sopenharmony_ci tex |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ciend: 100bf215546Sopenharmony_ci out_properties->linearTilingFeatures = tex; 101bf215546Sopenharmony_ci out_properties->optimalTilingFeatures = tex; 102bf215546Sopenharmony_ci out_properties->bufferFeatures = buffer; 103bf215546Sopenharmony_ci} 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_civoid 106bf215546Sopenharmony_cipanvk_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, 107bf215546Sopenharmony_ci VkFormat format, 108bf215546Sopenharmony_ci VkFormatProperties *pFormatProperties) 109bf215546Sopenharmony_ci{ 110bf215546Sopenharmony_ci VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci get_format_properties(physical_device, format, pFormatProperties); 113bf215546Sopenharmony_ci} 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_civoid 116bf215546Sopenharmony_cipanvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, 117bf215546Sopenharmony_ci VkFormat format, 118bf215546Sopenharmony_ci VkFormatProperties2 *pFormatProperties) 119bf215546Sopenharmony_ci{ 120bf215546Sopenharmony_ci VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci get_format_properties(physical_device, format, 123bf215546Sopenharmony_ci &pFormatProperties->formatProperties); 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesListEXT *list = 126bf215546Sopenharmony_ci vk_find_struct(pFormatProperties->pNext, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT); 127bf215546Sopenharmony_ci if (list) { 128bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out, 129bf215546Sopenharmony_ci list->pDrmFormatModifierProperties, 130bf215546Sopenharmony_ci &list->drmFormatModifierCount); 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out, mod_props) { 133bf215546Sopenharmony_ci mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; 134bf215546Sopenharmony_ci mod_props->drmFormatModifierPlaneCount = 1; 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci } 137bf215546Sopenharmony_ci} 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_cistatic VkResult 140bf215546Sopenharmony_ciget_image_format_properties(struct panvk_physical_device *physical_device, 141bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *info, 142bf215546Sopenharmony_ci VkImageFormatProperties *pImageFormatProperties, 143bf215546Sopenharmony_ci VkFormatFeatureFlags *p_feature_flags) 144bf215546Sopenharmony_ci{ 145bf215546Sopenharmony_ci VkFormatProperties format_props; 146bf215546Sopenharmony_ci VkFormatFeatureFlags format_feature_flags; 147bf215546Sopenharmony_ci VkExtent3D maxExtent; 148bf215546Sopenharmony_ci uint32_t maxMipLevels; 149bf215546Sopenharmony_ci uint32_t maxArraySize; 150bf215546Sopenharmony_ci VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT; 151bf215546Sopenharmony_ci enum pipe_format format = vk_format_to_pipe_format(info->format); 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci get_format_properties(physical_device, info->format, &format_props); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci switch (info->tiling) { 156bf215546Sopenharmony_ci case VK_IMAGE_TILING_LINEAR: 157bf215546Sopenharmony_ci format_feature_flags = format_props.linearTilingFeatures; 158bf215546Sopenharmony_ci break; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: 161bf215546Sopenharmony_ci /* The only difference between optimal and linear is currently whether 162bf215546Sopenharmony_ci * depth/stencil attachments are allowed on depth/stencil formats. 163bf215546Sopenharmony_ci * There's no reason to allow importing depth/stencil textures, so just 164bf215546Sopenharmony_ci * disallow it and then this annoying edge case goes away. 165bf215546Sopenharmony_ci * 166bf215546Sopenharmony_ci * TODO: If anyone cares, we could enable this by looking at the 167bf215546Sopenharmony_ci * modifier and checking if it's LINEAR or not. 168bf215546Sopenharmony_ci */ 169bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(format)) 170bf215546Sopenharmony_ci goto unsupported; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci assert(format_props.optimalTilingFeatures == format_props.linearTilingFeatures); 173bf215546Sopenharmony_ci FALLTHROUGH; 174bf215546Sopenharmony_ci case VK_IMAGE_TILING_OPTIMAL: 175bf215546Sopenharmony_ci format_feature_flags = format_props.optimalTilingFeatures; 176bf215546Sopenharmony_ci break; 177bf215546Sopenharmony_ci default: 178bf215546Sopenharmony_ci unreachable("bad VkPhysicalDeviceImageFormatInfo2"); 179bf215546Sopenharmony_ci } 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if (format_feature_flags == 0) 182bf215546Sopenharmony_ci goto unsupported; 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci if (info->type != VK_IMAGE_TYPE_2D && 185bf215546Sopenharmony_ci util_format_is_depth_or_stencil(format)) 186bf215546Sopenharmony_ci goto unsupported; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci switch (info->type) { 189bf215546Sopenharmony_ci default: 190bf215546Sopenharmony_ci unreachable("bad vkimage type"); 191bf215546Sopenharmony_ci case VK_IMAGE_TYPE_1D: 192bf215546Sopenharmony_ci maxExtent.width = 16384; 193bf215546Sopenharmony_ci maxExtent.height = 1; 194bf215546Sopenharmony_ci maxExtent.depth = 1; 195bf215546Sopenharmony_ci maxMipLevels = 15; /* log2(maxWidth) + 1 */ 196bf215546Sopenharmony_ci maxArraySize = 2048; 197bf215546Sopenharmony_ci break; 198bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 199bf215546Sopenharmony_ci maxExtent.width = 16384; 200bf215546Sopenharmony_ci maxExtent.height = 16384; 201bf215546Sopenharmony_ci maxExtent.depth = 1; 202bf215546Sopenharmony_ci maxMipLevels = 15; /* log2(maxWidth) + 1 */ 203bf215546Sopenharmony_ci maxArraySize = 2048; 204bf215546Sopenharmony_ci break; 205bf215546Sopenharmony_ci case VK_IMAGE_TYPE_3D: 206bf215546Sopenharmony_ci maxExtent.width = 2048; 207bf215546Sopenharmony_ci maxExtent.height = 2048; 208bf215546Sopenharmony_ci maxExtent.depth = 2048; 209bf215546Sopenharmony_ci maxMipLevels = 12; /* log2(maxWidth) + 1 */ 210bf215546Sopenharmony_ci maxArraySize = 1; 211bf215546Sopenharmony_ci break; 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci if (info->tiling == VK_IMAGE_TILING_OPTIMAL && 215bf215546Sopenharmony_ci info->type == VK_IMAGE_TYPE_2D && 216bf215546Sopenharmony_ci (format_feature_flags & 217bf215546Sopenharmony_ci (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 218bf215546Sopenharmony_ci VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) && 219bf215546Sopenharmony_ci !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 220bf215546Sopenharmony_ci !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) { 221bf215546Sopenharmony_ci sampleCounts |= VK_SAMPLE_COUNT_4_BIT; 222bf215546Sopenharmony_ci } 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) { 225bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 226bf215546Sopenharmony_ci goto unsupported; 227bf215546Sopenharmony_ci } 228bf215546Sopenharmony_ci } 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) { 231bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) { 232bf215546Sopenharmony_ci goto unsupported; 233bf215546Sopenharmony_ci } 234bf215546Sopenharmony_ci } 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 237bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { 238bf215546Sopenharmony_ci goto unsupported; 239bf215546Sopenharmony_ci } 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 243bf215546Sopenharmony_ci if (!(format_feature_flags & 244bf215546Sopenharmony_ci VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 245bf215546Sopenharmony_ci goto unsupported; 246bf215546Sopenharmony_ci } 247bf215546Sopenharmony_ci } 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci *pImageFormatProperties = (VkImageFormatProperties) { 250bf215546Sopenharmony_ci .maxExtent = maxExtent, 251bf215546Sopenharmony_ci .maxMipLevels = maxMipLevels, 252bf215546Sopenharmony_ci .maxArrayLayers = maxArraySize, 253bf215546Sopenharmony_ci .sampleCounts = sampleCounts, 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci /* FINISHME: Accurately calculate 256bf215546Sopenharmony_ci * VkImageFormatProperties::maxResourceSize. 257bf215546Sopenharmony_ci */ 258bf215546Sopenharmony_ci .maxResourceSize = UINT32_MAX, 259bf215546Sopenharmony_ci }; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci if (p_feature_flags) 262bf215546Sopenharmony_ci *p_feature_flags = format_feature_flags; 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci return VK_SUCCESS; 265bf215546Sopenharmony_ciunsupported: 266bf215546Sopenharmony_ci *pImageFormatProperties = (VkImageFormatProperties) { 267bf215546Sopenharmony_ci .maxExtent = { 0, 0, 0 }, 268bf215546Sopenharmony_ci .maxMipLevels = 0, 269bf215546Sopenharmony_ci .maxArrayLayers = 0, 270bf215546Sopenharmony_ci .sampleCounts = 0, 271bf215546Sopenharmony_ci .maxResourceSize = 0, 272bf215546Sopenharmony_ci }; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 275bf215546Sopenharmony_ci} 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ciVkResult 279bf215546Sopenharmony_cipanvk_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, 280bf215546Sopenharmony_ci VkFormat format, 281bf215546Sopenharmony_ci VkImageType type, 282bf215546Sopenharmony_ci VkImageTiling tiling, 283bf215546Sopenharmony_ci VkImageUsageFlags usage, 284bf215546Sopenharmony_ci VkImageCreateFlags createFlags, 285bf215546Sopenharmony_ci VkImageFormatProperties *pImageFormatProperties) 286bf215546Sopenharmony_ci{ 287bf215546Sopenharmony_ci VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 info = { 290bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, 291bf215546Sopenharmony_ci .pNext = NULL, 292bf215546Sopenharmony_ci .format = format, 293bf215546Sopenharmony_ci .type = type, 294bf215546Sopenharmony_ci .tiling = tiling, 295bf215546Sopenharmony_ci .usage = usage, 296bf215546Sopenharmony_ci .flags = createFlags, 297bf215546Sopenharmony_ci }; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci return get_image_format_properties(physical_device, &info, 300bf215546Sopenharmony_ci pImageFormatProperties, NULL); 301bf215546Sopenharmony_ci} 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_cistatic VkResult 304bf215546Sopenharmony_cipanvk_get_external_image_format_properties(const struct panvk_physical_device *physical_device, 305bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, 306bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlagBits handleType, 307bf215546Sopenharmony_ci VkExternalMemoryProperties *external_properties) 308bf215546Sopenharmony_ci{ 309bf215546Sopenharmony_ci VkExternalMemoryFeatureFlagBits flags = 0; 310bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags export_flags = 0; 311bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags compat_flags = 0; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci /* From the Vulkan 1.1.98 spec: 314bf215546Sopenharmony_ci * 315bf215546Sopenharmony_ci * If handleType is not compatible with the format, type, tiling, 316bf215546Sopenharmony_ci * usage, and flags specified in VkPhysicalDeviceImageFormatInfo2, 317bf215546Sopenharmony_ci * then vkGetPhysicalDeviceImageFormatProperties2 returns 318bf215546Sopenharmony_ci * VK_ERROR_FORMAT_NOT_SUPPORTED. 319bf215546Sopenharmony_ci */ 320bf215546Sopenharmony_ci switch (handleType) { 321bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 322bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 323bf215546Sopenharmony_ci switch (pImageFormatInfo->type) { 324bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 325bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT | 326bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 327bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 328bf215546Sopenharmony_ci compat_flags = export_flags = 329bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 330bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 331bf215546Sopenharmony_ci break; 332bf215546Sopenharmony_ci default: 333bf215546Sopenharmony_ci return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 334bf215546Sopenharmony_ci "VkExternalMemoryTypeFlagBits(0x%x) unsupported for VkImageType(%d)", 335bf215546Sopenharmony_ci handleType, pImageFormatInfo->type); 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci break; 338bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 339bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 340bf215546Sopenharmony_ci compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; 341bf215546Sopenharmony_ci break; 342bf215546Sopenharmony_ci default: 343bf215546Sopenharmony_ci return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 344bf215546Sopenharmony_ci "VkExternalMemoryTypeFlagBits(0x%x) unsupported", 345bf215546Sopenharmony_ci handleType); 346bf215546Sopenharmony_ci } 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci *external_properties = (VkExternalMemoryProperties) { 349bf215546Sopenharmony_ci .externalMemoryFeatures = flags, 350bf215546Sopenharmony_ci .exportFromImportedHandleTypes = export_flags, 351bf215546Sopenharmony_ci .compatibleHandleTypes = compat_flags, 352bf215546Sopenharmony_ci }; 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci return VK_SUCCESS; 355bf215546Sopenharmony_ci} 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ciVkResult 358bf215546Sopenharmony_cipanvk_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, 359bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *base_info, 360bf215546Sopenharmony_ci VkImageFormatProperties2 *base_props) 361bf215546Sopenharmony_ci{ 362bf215546Sopenharmony_ci VK_FROM_HANDLE(panvk_physical_device, physical_device, physicalDevice); 363bf215546Sopenharmony_ci const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL; 364bf215546Sopenharmony_ci const VkPhysicalDeviceImageViewImageFormatInfoEXT *image_view_info = NULL; 365bf215546Sopenharmony_ci VkExternalImageFormatProperties *external_props = NULL; 366bf215546Sopenharmony_ci VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL; 367bf215546Sopenharmony_ci VkFormatFeatureFlags format_feature_flags; 368bf215546Sopenharmony_ci VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL; 369bf215546Sopenharmony_ci VkResult result; 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci result = get_image_format_properties(physical_device, base_info, 372bf215546Sopenharmony_ci &base_props->imageFormatProperties, 373bf215546Sopenharmony_ci &format_feature_flags); 374bf215546Sopenharmony_ci if (result != VK_SUCCESS) 375bf215546Sopenharmony_ci return result; 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci /* Extract input structs */ 378bf215546Sopenharmony_ci vk_foreach_struct_const(s, base_info->pNext) 379bf215546Sopenharmony_ci { 380bf215546Sopenharmony_ci switch (s->sType) { 381bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: 382bf215546Sopenharmony_ci external_info = (const void *) s; 383bf215546Sopenharmony_ci break; 384bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT: 385bf215546Sopenharmony_ci image_view_info = (const void *) s; 386bf215546Sopenharmony_ci break; 387bf215546Sopenharmony_ci default: 388bf215546Sopenharmony_ci break; 389bf215546Sopenharmony_ci } 390bf215546Sopenharmony_ci } 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci /* Extract output structs */ 393bf215546Sopenharmony_ci vk_foreach_struct(s, base_props->pNext) 394bf215546Sopenharmony_ci { 395bf215546Sopenharmony_ci switch (s->sType) { 396bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES: 397bf215546Sopenharmony_ci external_props = (void *) s; 398bf215546Sopenharmony_ci break; 399bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT: 400bf215546Sopenharmony_ci cubic_props = (void *) s; 401bf215546Sopenharmony_ci break; 402bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES: 403bf215546Sopenharmony_ci ycbcr_props = (void *) s; 404bf215546Sopenharmony_ci break; 405bf215546Sopenharmony_ci default: 406bf215546Sopenharmony_ci break; 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci } 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci /* From the Vulkan 1.0.42 spec: 411bf215546Sopenharmony_ci * 412bf215546Sopenharmony_ci * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will 413bf215546Sopenharmony_ci * behave as if VkPhysicalDeviceExternalImageFormatInfo was not 414bf215546Sopenharmony_ci * present and VkExternalImageFormatProperties will be ignored. 415bf215546Sopenharmony_ci */ 416bf215546Sopenharmony_ci if (external_info && external_info->handleType != 0) { 417bf215546Sopenharmony_ci result = panvk_get_external_image_format_properties(physical_device, 418bf215546Sopenharmony_ci base_info, 419bf215546Sopenharmony_ci external_info->handleType, 420bf215546Sopenharmony_ci &external_props->externalMemoryProperties); 421bf215546Sopenharmony_ci if (result != VK_SUCCESS) 422bf215546Sopenharmony_ci goto fail; 423bf215546Sopenharmony_ci } 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci if (cubic_props) { 426bf215546Sopenharmony_ci /* note: blob only allows cubic filtering for 2D and 2D array views 427bf215546Sopenharmony_ci * its likely we can enable it for 1D and CUBE, needs testing however 428bf215546Sopenharmony_ci */ 429bf215546Sopenharmony_ci if ((image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D || 430bf215546Sopenharmony_ci image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) && 431bf215546Sopenharmony_ci (format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) { 432bf215546Sopenharmony_ci cubic_props->filterCubic = true; 433bf215546Sopenharmony_ci cubic_props->filterCubicMinmax = true; 434bf215546Sopenharmony_ci } else { 435bf215546Sopenharmony_ci cubic_props->filterCubic = false; 436bf215546Sopenharmony_ci cubic_props->filterCubicMinmax = false; 437bf215546Sopenharmony_ci } 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci if (ycbcr_props) 441bf215546Sopenharmony_ci ycbcr_props->combinedImageSamplerDescriptorCount = 1; 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci return VK_SUCCESS; 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_cifail: 446bf215546Sopenharmony_ci if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) { 447bf215546Sopenharmony_ci /* From the Vulkan 1.0.42 spec: 448bf215546Sopenharmony_ci * 449bf215546Sopenharmony_ci * If the combination of parameters to 450bf215546Sopenharmony_ci * vkGetPhysicalDeviceImageFormatProperties2 is not supported by 451bf215546Sopenharmony_ci * the implementation for use in vkCreateImage, then all members of 452bf215546Sopenharmony_ci * imageFormatProperties will be filled with zero. 453bf215546Sopenharmony_ci */ 454bf215546Sopenharmony_ci base_props->imageFormatProperties = (VkImageFormatProperties) {}; 455bf215546Sopenharmony_ci } 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci return result; 458bf215546Sopenharmony_ci} 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_civoid 461bf215546Sopenharmony_cipanvk_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, 462bf215546Sopenharmony_ci VkFormat format, 463bf215546Sopenharmony_ci VkImageType type, 464bf215546Sopenharmony_ci uint32_t samples, 465bf215546Sopenharmony_ci VkImageUsageFlags usage, 466bf215546Sopenharmony_ci VkImageTiling tiling, 467bf215546Sopenharmony_ci uint32_t *pNumProperties, 468bf215546Sopenharmony_ci VkSparseImageFormatProperties *pProperties) 469bf215546Sopenharmony_ci{ 470bf215546Sopenharmony_ci /* Sparse images are not yet supported. */ 471bf215546Sopenharmony_ci *pNumProperties = 0; 472bf215546Sopenharmony_ci} 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_civoid 475bf215546Sopenharmony_cipanvk_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice, 476bf215546Sopenharmony_ci const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, 477bf215546Sopenharmony_ci uint32_t *pPropertyCount, 478bf215546Sopenharmony_ci VkSparseImageFormatProperties2 *pProperties) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci /* Sparse images are not yet supported. */ 481bf215546Sopenharmony_ci *pPropertyCount = 0; 482bf215546Sopenharmony_ci} 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_civoid 485bf215546Sopenharmony_cipanvk_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice, 486bf215546Sopenharmony_ci const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, 487bf215546Sopenharmony_ci VkExternalBufferProperties *pExternalBufferProperties) 488bf215546Sopenharmony_ci{ 489bf215546Sopenharmony_ci panvk_stub(); 490bf215546Sopenharmony_ci} 491