1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 3bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 4bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 5bf215546Sopenharmony_ci */ 6bf215546Sopenharmony_ci 7bf215546Sopenharmony_ci#include "tu_formats.h" 8bf215546Sopenharmony_ci 9bf215546Sopenharmony_ci#include "fdl/fd6_format_table.h" 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci#include "vk_util.h" 12bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 13bf215546Sopenharmony_ci 14bf215546Sopenharmony_ci#include "tu_device.h" 15bf215546Sopenharmony_ci#include "tu_image.h" 16bf215546Sopenharmony_ci 17bf215546Sopenharmony_cistruct tu_native_format 18bf215546Sopenharmony_citu6_format_vtx(VkFormat vk_format) 19bf215546Sopenharmony_ci{ 20bf215546Sopenharmony_ci enum pipe_format format = vk_format_to_pipe_format(vk_format); 21bf215546Sopenharmony_ci struct tu_native_format fmt = { 22bf215546Sopenharmony_ci .fmt = fd6_vertex_format(format), 23bf215546Sopenharmony_ci .swap = fd6_vertex_swap(format), 24bf215546Sopenharmony_ci }; 25bf215546Sopenharmony_ci assert(fmt.fmt != FMT6_NONE); 26bf215546Sopenharmony_ci return fmt; 27bf215546Sopenharmony_ci} 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_cibool 30bf215546Sopenharmony_citu6_format_vtx_supported(VkFormat vk_format) 31bf215546Sopenharmony_ci{ 32bf215546Sopenharmony_ci enum pipe_format format = vk_format_to_pipe_format(vk_format); 33bf215546Sopenharmony_ci return fd6_vertex_format(format) != FMT6_NONE; 34bf215546Sopenharmony_ci} 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci/* Map non-colorspace-converted YUV formats to RGB pipe formats where we can, 37bf215546Sopenharmony_ci * since our hardware doesn't support colorspace conversion. 38bf215546Sopenharmony_ci * 39bf215546Sopenharmony_ci * Really, we should probably be returning the RGB formats in 40bf215546Sopenharmony_ci * vk_format_to_pipe_format, but we don't have all the equivalent pipe formats 41bf215546Sopenharmony_ci * for VK RGB formats yet, and we'd have to switch all consumers of that 42bf215546Sopenharmony_ci * function at once. 43bf215546Sopenharmony_ci */ 44bf215546Sopenharmony_cienum pipe_format 45bf215546Sopenharmony_citu_vk_format_to_pipe_format(VkFormat vk_format) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci switch (vk_format) { 48bf215546Sopenharmony_ci case VK_FORMAT_G8B8G8R8_422_UNORM: /* YUYV */ 49bf215546Sopenharmony_ci return PIPE_FORMAT_R8G8_R8B8_UNORM; 50bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8G8_422_UNORM: /* UYVY */ 51bf215546Sopenharmony_ci return PIPE_FORMAT_G8R8_B8R8_UNORM; 52bf215546Sopenharmony_ci case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 53bf215546Sopenharmony_ci return PIPE_FORMAT_G8_B8R8_420_UNORM; 54bf215546Sopenharmony_ci case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 55bf215546Sopenharmony_ci return PIPE_FORMAT_G8_B8_R8_420_UNORM; 56bf215546Sopenharmony_ci default: 57bf215546Sopenharmony_ci return vk_format_to_pipe_format(vk_format); 58bf215546Sopenharmony_ci } 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_cistatic struct tu_native_format 62bf215546Sopenharmony_citu6_format_color_unchecked(enum pipe_format format, enum a6xx_tile_mode tile_mode) 63bf215546Sopenharmony_ci{ 64bf215546Sopenharmony_ci struct tu_native_format fmt = { 65bf215546Sopenharmony_ci .fmt = fd6_color_format(format, tile_mode), 66bf215546Sopenharmony_ci .swap = fd6_color_swap(format, tile_mode), 67bf215546Sopenharmony_ci }; 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci switch (format) { 70bf215546Sopenharmony_ci case PIPE_FORMAT_Z24X8_UNORM: 71bf215546Sopenharmony_ci case PIPE_FORMAT_Z24_UNORM_S8_UINT: 72bf215546Sopenharmony_ci fmt.fmt = FMT6_8_8_8_8_UNORM; 73bf215546Sopenharmony_ci break; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci default: 76bf215546Sopenharmony_ci break; 77bf215546Sopenharmony_ci } 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci return fmt; 80bf215546Sopenharmony_ci} 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_cibool 83bf215546Sopenharmony_citu6_format_color_supported(enum pipe_format format) 84bf215546Sopenharmony_ci{ 85bf215546Sopenharmony_ci return tu6_format_color_unchecked(format, TILE6_LINEAR).fmt != FMT6_NONE; 86bf215546Sopenharmony_ci} 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_cistruct tu_native_format 89bf215546Sopenharmony_citu6_format_color(enum pipe_format format, enum a6xx_tile_mode tile_mode) 90bf215546Sopenharmony_ci{ 91bf215546Sopenharmony_ci struct tu_native_format fmt = tu6_format_color_unchecked(format, tile_mode); 92bf215546Sopenharmony_ci assert(fmt.fmt != FMT6_NONE); 93bf215546Sopenharmony_ci return fmt; 94bf215546Sopenharmony_ci} 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_cistatic struct tu_native_format 97bf215546Sopenharmony_citu6_format_texture_unchecked(enum pipe_format format, enum a6xx_tile_mode tile_mode) 98bf215546Sopenharmony_ci{ 99bf215546Sopenharmony_ci struct tu_native_format fmt = { 100bf215546Sopenharmony_ci .fmt = fd6_texture_format(format, tile_mode), 101bf215546Sopenharmony_ci .swap = fd6_texture_swap(format, tile_mode), 102bf215546Sopenharmony_ci }; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci switch (format) { 105bf215546Sopenharmony_ci case PIPE_FORMAT_Z24X8_UNORM: 106bf215546Sopenharmony_ci case PIPE_FORMAT_Z24_UNORM_S8_UINT: 107bf215546Sopenharmony_ci /* freedreno uses Z24_UNORM_S8_UINT (sampling) or 108bf215546Sopenharmony_ci * FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 (blits) for this format, while we use 109bf215546Sopenharmony_ci * FMT6_8_8_8_8_UNORM or FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 110bf215546Sopenharmony_ci */ 111bf215546Sopenharmony_ci fmt.fmt = FMT6_8_8_8_8_UNORM; 112bf215546Sopenharmony_ci break; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci default: 115bf215546Sopenharmony_ci break; 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci return fmt; 119bf215546Sopenharmony_ci} 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_cistruct tu_native_format 122bf215546Sopenharmony_citu6_format_texture(enum pipe_format format, enum a6xx_tile_mode tile_mode) 123bf215546Sopenharmony_ci{ 124bf215546Sopenharmony_ci struct tu_native_format fmt = tu6_format_texture_unchecked(format, tile_mode); 125bf215546Sopenharmony_ci assert(fmt.fmt != FMT6_NONE); 126bf215546Sopenharmony_ci return fmt; 127bf215546Sopenharmony_ci} 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_cibool 130bf215546Sopenharmony_citu6_format_texture_supported(enum pipe_format format) 131bf215546Sopenharmony_ci{ 132bf215546Sopenharmony_ci return tu6_format_texture_unchecked(format, TILE6_LINEAR).fmt != FMT6_NONE; 133bf215546Sopenharmony_ci} 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_cistatic void 136bf215546Sopenharmony_citu_physical_device_get_format_properties( 137bf215546Sopenharmony_ci struct tu_physical_device *physical_device, 138bf215546Sopenharmony_ci VkFormat vk_format, 139bf215546Sopenharmony_ci VkFormatProperties3 *out_properties) 140bf215546Sopenharmony_ci{ 141bf215546Sopenharmony_ci VkFormatFeatureFlags2 linear = 0, optimal = 0, buffer = 0; 142bf215546Sopenharmony_ci enum pipe_format format = tu_vk_format_to_pipe_format(vk_format); 143bf215546Sopenharmony_ci const struct util_format_description *desc = util_format_description(format); 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci bool supported_vtx = tu6_format_vtx_supported(vk_format); 146bf215546Sopenharmony_ci bool supported_color = tu6_format_color_supported(format); 147bf215546Sopenharmony_ci bool supported_tex = tu6_format_texture_supported(format); 148bf215546Sopenharmony_ci bool is_npot = !util_is_power_of_two_or_zero(desc->block.bits); 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci if (format == PIPE_FORMAT_NONE || 151bf215546Sopenharmony_ci !(supported_vtx || supported_color || supported_tex)) { 152bf215546Sopenharmony_ci goto end; 153bf215546Sopenharmony_ci } 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci /* We don't support BufferToImage/ImageToBuffer for npot formats */ 156bf215546Sopenharmony_ci if (!is_npot) 157bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT; 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci if (supported_vtx) 160bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT; 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci if (supported_tex) 163bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci /* Don't support anything but texel buffers for non-power-of-two formats 166bf215546Sopenharmony_ci * with 3 components. We'd need several workarounds for copying and 167bf215546Sopenharmony_ci * clearing them because they're not renderable. 168bf215546Sopenharmony_ci */ 169bf215546Sopenharmony_ci if (supported_tex && !is_npot) { 170bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | 171bf215546Sopenharmony_ci VK_FORMAT_FEATURE_TRANSFER_DST_BIT | 172bf215546Sopenharmony_ci VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | 173bf215546Sopenharmony_ci VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT | 174bf215546Sopenharmony_ci VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT | 175bf215546Sopenharmony_ci VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT; 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci /* no blit src bit for YUYV/NV12/I420 formats */ 178bf215546Sopenharmony_ci if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED && 179bf215546Sopenharmony_ci desc->layout != UTIL_FORMAT_LAYOUT_PLANAR2 && 180bf215546Sopenharmony_ci desc->layout != UTIL_FORMAT_LAYOUT_PLANAR3) 181bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_BLIT_SRC_BIT; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED) 184bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT; 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci if (!vk_format_is_int(vk_format)) { 187bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci if (physical_device->vk.supported_extensions.EXT_filter_cubic) 190bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT; 191bf215546Sopenharmony_ci } 192bf215546Sopenharmony_ci } 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if (supported_color) { 195bf215546Sopenharmony_ci assert(supported_tex); 196bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 197bf215546Sopenharmony_ci VK_FORMAT_FEATURE_BLIT_DST_BIT | 198bf215546Sopenharmony_ci VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | 199bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT | 200bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | 203bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT | 204bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci /* TODO: The blob also exposes these for R16G16_UINT/R16G16_SINT, but we 207bf215546Sopenharmony_ci * don't have any tests for those. 208bf215546Sopenharmony_ci */ 209bf215546Sopenharmony_ci if (vk_format == VK_FORMAT_R32_UINT || vk_format == VK_FORMAT_R32_SINT) { 210bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT; 211bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT; 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci if (!util_format_is_pure_integer(format)) 215bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci /* For the most part, we can do anything with a linear image that we could 219bf215546Sopenharmony_ci * do with a tiled image. However, we can't support sysmem rendering with a 220bf215546Sopenharmony_ci * linear depth texture, because we don't know if there's a bit to control 221bf215546Sopenharmony_ci * the tiling of the depth buffer in BYPASS mode, and the blob also 222bf215546Sopenharmony_ci * disables linear depth rendering, so there's no way to discover it. We 223bf215546Sopenharmony_ci * also can't force GMEM mode, because there are other situations where we 224bf215546Sopenharmony_ci * have to use sysmem rendering. So follow the blob here, and only enable 225bf215546Sopenharmony_ci * DEPTH_STENCIL_ATTACHMENT_BIT for the optimal features. 226bf215546Sopenharmony_ci */ 227bf215546Sopenharmony_ci linear = optimal; 228bf215546Sopenharmony_ci if (tu6_pipe2depth(vk_format) != (enum a6xx_depth_format)~0) 229bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci if (!tiling_possible(vk_format) && 232bf215546Sopenharmony_ci /* We don't actually support tiling for this format, but we need to 233bf215546Sopenharmony_ci * fake it as it's required by VK_KHR_sampler_ycbcr_conversion. 234bf215546Sopenharmony_ci */ 235bf215546Sopenharmony_ci vk_format != VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) { 236bf215546Sopenharmony_ci optimal = 0; 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci if (vk_format == VK_FORMAT_G8B8G8R8_422_UNORM || 240bf215546Sopenharmony_ci vk_format == VK_FORMAT_B8G8R8G8_422_UNORM || 241bf215546Sopenharmony_ci vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM || 242bf215546Sopenharmony_ci vk_format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) { 243bf215546Sopenharmony_ci /* Disable buffer texturing of subsampled (422) and planar YUV textures. 244bf215546Sopenharmony_ci * The subsampling requirement comes from "If format is a block-compressed 245bf215546Sopenharmony_ci * format, then bufferFeatures must not support any features for the 246bf215546Sopenharmony_ci * format" plus the specification of subsampled as 2x1 compressed block 247bf215546Sopenharmony_ci * format. I couldn't find the citation for planar, but 1D access of 248bf215546Sopenharmony_ci * planar YUV would be really silly. 249bf215546Sopenharmony_ci */ 250bf215546Sopenharmony_ci buffer = 0; 251bf215546Sopenharmony_ci } 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci /* We don't support writing into VK__FORMAT_*_PACK16 images/buffers */ 254bf215546Sopenharmony_ci if (desc->nr_channels > 2 && desc->block.bits == 16) { 255bf215546Sopenharmony_ci buffer &= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; 256bf215546Sopenharmony_ci linear &= ~(VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | 257bf215546Sopenharmony_ci VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT); 258bf215546Sopenharmony_ci optimal &= ~(VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | 259bf215546Sopenharmony_ci VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT); 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci /* All our depth formats support shadow comparisons. */ 263bf215546Sopenharmony_ci if (vk_format_has_depth(vk_format) && (optimal & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 264bf215546Sopenharmony_ci optimal |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT; 265bf215546Sopenharmony_ci linear |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT; 266bf215546Sopenharmony_ci } 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci /* From the Vulkan 1.3.205 spec, section 19.3 "43.3. Required Format Support": 269bf215546Sopenharmony_ci * 270bf215546Sopenharmony_ci * Mandatory format support: depth/stencil with VkImageType 271bf215546Sopenharmony_ci * VK_IMAGE_TYPE_2D 272bf215546Sopenharmony_ci * [...] 273bf215546Sopenharmony_ci * bufferFeatures must not support any features for these formats 274bf215546Sopenharmony_ci */ 275bf215546Sopenharmony_ci if (vk_format_is_depth_or_stencil(vk_format)) 276bf215546Sopenharmony_ci buffer = 0; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci /* D32_SFLOAT_S8_UINT is tiled as two images, so no linear format 279bf215546Sopenharmony_ci * blob enables some linear features, but its not useful, so don't bother. 280bf215546Sopenharmony_ci */ 281bf215546Sopenharmony_ci if (vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT) 282bf215546Sopenharmony_ci linear = 0; 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ciend: 285bf215546Sopenharmony_ci out_properties->linearTilingFeatures = linear; 286bf215546Sopenharmony_ci out_properties->optimalTilingFeatures = optimal; 287bf215546Sopenharmony_ci out_properties->bufferFeatures = buffer; 288bf215546Sopenharmony_ci} 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 291bf215546Sopenharmony_citu_GetPhysicalDeviceFormatProperties2( 292bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 293bf215546Sopenharmony_ci VkFormat format, 294bf215546Sopenharmony_ci VkFormatProperties2 *pFormatProperties) 295bf215546Sopenharmony_ci{ 296bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice); 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci VkFormatProperties3 local_props3; 299bf215546Sopenharmony_ci VkFormatProperties3 *props3 = 300bf215546Sopenharmony_ci vk_find_struct(pFormatProperties->pNext, FORMAT_PROPERTIES_3); 301bf215546Sopenharmony_ci if (!props3) 302bf215546Sopenharmony_ci props3 = &local_props3; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci tu_physical_device_get_format_properties( 305bf215546Sopenharmony_ci physical_device, format, props3); 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci pFormatProperties->formatProperties = (VkFormatProperties) { 308bf215546Sopenharmony_ci .linearTilingFeatures = props3->linearTilingFeatures, 309bf215546Sopenharmony_ci .optimalTilingFeatures = props3->optimalTilingFeatures, 310bf215546Sopenharmony_ci .bufferFeatures = props3->bufferFeatures, 311bf215546Sopenharmony_ci }; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesListEXT *list = 314bf215546Sopenharmony_ci vk_find_struct(pFormatProperties->pNext, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT); 315bf215546Sopenharmony_ci if (list) { 316bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out, 317bf215546Sopenharmony_ci list->pDrmFormatModifierProperties, 318bf215546Sopenharmony_ci &list->drmFormatModifierCount); 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci if (pFormatProperties->formatProperties.linearTilingFeatures) { 321bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, mod_props) { 322bf215546Sopenharmony_ci mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; 323bf215546Sopenharmony_ci mod_props->drmFormatModifierPlaneCount = tu6_plane_count(format); 324bf215546Sopenharmony_ci mod_props->drmFormatModifierTilingFeatures = 325bf215546Sopenharmony_ci pFormatProperties->formatProperties.linearTilingFeatures; 326bf215546Sopenharmony_ci } 327bf215546Sopenharmony_ci } 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci /* note: ubwc_possible() argument values to be ignored except for format */ 330bf215546Sopenharmony_ci if (pFormatProperties->formatProperties.optimalTilingFeatures && 331bf215546Sopenharmony_ci tiling_possible(format) && 332bf215546Sopenharmony_ci ubwc_possible(format, VK_IMAGE_TYPE_2D, 0, 0, physical_device->info, VK_SAMPLE_COUNT_1_BIT, false)) { 333bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, mod_props) { 334bf215546Sopenharmony_ci mod_props->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; 335bf215546Sopenharmony_ci mod_props->drmFormatModifierPlaneCount = tu6_plane_count(format); 336bf215546Sopenharmony_ci mod_props->drmFormatModifierTilingFeatures = 337bf215546Sopenharmony_ci pFormatProperties->formatProperties.optimalTilingFeatures; 338bf215546Sopenharmony_ci } 339bf215546Sopenharmony_ci } 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci} 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_cistatic VkResult 344bf215546Sopenharmony_citu_get_image_format_properties( 345bf215546Sopenharmony_ci struct tu_physical_device *physical_device, 346bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *info, 347bf215546Sopenharmony_ci VkImageFormatProperties *pImageFormatProperties, 348bf215546Sopenharmony_ci VkFormatFeatureFlags *p_feature_flags) 349bf215546Sopenharmony_ci{ 350bf215546Sopenharmony_ci VkFormatProperties3 format_props; 351bf215546Sopenharmony_ci VkFormatFeatureFlags format_feature_flags; 352bf215546Sopenharmony_ci VkExtent3D maxExtent; 353bf215546Sopenharmony_ci uint32_t maxMipLevels; 354bf215546Sopenharmony_ci uint32_t maxArraySize; 355bf215546Sopenharmony_ci VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT; 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci tu_physical_device_get_format_properties(physical_device, info->format, 358bf215546Sopenharmony_ci &format_props); 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci switch (info->tiling) { 361bf215546Sopenharmony_ci case VK_IMAGE_TILING_LINEAR: 362bf215546Sopenharmony_ci format_feature_flags = format_props.linearTilingFeatures; 363bf215546Sopenharmony_ci break; 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: { 366bf215546Sopenharmony_ci const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_info = 367bf215546Sopenharmony_ci vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT); 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci switch (drm_info->drmFormatModifier) { 370bf215546Sopenharmony_ci case DRM_FORMAT_MOD_QCOM_COMPRESSED: 371bf215546Sopenharmony_ci /* falling back to linear/non-UBWC isn't possible with explicit modifier */ 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci /* formats which don't support tiling */ 374bf215546Sopenharmony_ci if (!format_props.optimalTilingFeatures || 375bf215546Sopenharmony_ci !tiling_possible(info->format)) 376bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci /* for mutable formats, its very unlikely to be possible to use UBWC */ 379bf215546Sopenharmony_ci if (info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) 380bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci if (!ubwc_possible(info->format, info->type, info->usage, info->usage, physical_device->info, sampleCounts, false)) 384bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci format_feature_flags = format_props.optimalTilingFeatures; 387bf215546Sopenharmony_ci break; 388bf215546Sopenharmony_ci case DRM_FORMAT_MOD_LINEAR: 389bf215546Sopenharmony_ci format_feature_flags = format_props.linearTilingFeatures; 390bf215546Sopenharmony_ci break; 391bf215546Sopenharmony_ci default: 392bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 393bf215546Sopenharmony_ci } 394bf215546Sopenharmony_ci } break; 395bf215546Sopenharmony_ci case VK_IMAGE_TILING_OPTIMAL: 396bf215546Sopenharmony_ci format_feature_flags = format_props.optimalTilingFeatures; 397bf215546Sopenharmony_ci break; 398bf215546Sopenharmony_ci default: 399bf215546Sopenharmony_ci unreachable("bad VkPhysicalDeviceImageFormatInfo2"); 400bf215546Sopenharmony_ci } 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci if (format_feature_flags == 0) 403bf215546Sopenharmony_ci goto unsupported; 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci if (info->type != VK_IMAGE_TYPE_2D && 406bf215546Sopenharmony_ci vk_format_is_depth_or_stencil(info->format)) 407bf215546Sopenharmony_ci goto unsupported; 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci switch (info->type) { 410bf215546Sopenharmony_ci default: 411bf215546Sopenharmony_ci unreachable("bad vkimage type\n"); 412bf215546Sopenharmony_ci case VK_IMAGE_TYPE_1D: 413bf215546Sopenharmony_ci maxExtent.width = 16384; 414bf215546Sopenharmony_ci maxExtent.height = 1; 415bf215546Sopenharmony_ci maxExtent.depth = 1; 416bf215546Sopenharmony_ci maxMipLevels = 15; /* log2(maxWidth) + 1 */ 417bf215546Sopenharmony_ci maxArraySize = 2048; 418bf215546Sopenharmony_ci break; 419bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 420bf215546Sopenharmony_ci maxExtent.width = 16384; 421bf215546Sopenharmony_ci maxExtent.height = 16384; 422bf215546Sopenharmony_ci maxExtent.depth = 1; 423bf215546Sopenharmony_ci maxMipLevels = 15; /* log2(maxWidth) + 1 */ 424bf215546Sopenharmony_ci maxArraySize = 2048; 425bf215546Sopenharmony_ci break; 426bf215546Sopenharmony_ci case VK_IMAGE_TYPE_3D: 427bf215546Sopenharmony_ci maxExtent.width = 2048; 428bf215546Sopenharmony_ci maxExtent.height = 2048; 429bf215546Sopenharmony_ci maxExtent.depth = 2048; 430bf215546Sopenharmony_ci maxMipLevels = 12; /* log2(maxWidth) + 1 */ 431bf215546Sopenharmony_ci maxArraySize = 1; 432bf215546Sopenharmony_ci break; 433bf215546Sopenharmony_ci } 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci if (info->tiling == VK_IMAGE_TILING_OPTIMAL && 436bf215546Sopenharmony_ci info->type == VK_IMAGE_TYPE_2D && 437bf215546Sopenharmony_ci (format_feature_flags & 438bf215546Sopenharmony_ci (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 439bf215546Sopenharmony_ci VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) && 440bf215546Sopenharmony_ci !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 441bf215546Sopenharmony_ci !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) { 442bf215546Sopenharmony_ci sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT; 443bf215546Sopenharmony_ci /* note: most operations support 8 samples (GMEM render/resolve do at least) 444bf215546Sopenharmony_ci * but some do not (which ones?), just disable 8 samples completely, 445bf215546Sopenharmony_ci * (no 8x msaa matches the blob driver behavior) 446bf215546Sopenharmony_ci */ 447bf215546Sopenharmony_ci } 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci /* From the Vulkan 1.3.206 spec: 450bf215546Sopenharmony_ci * 451bf215546Sopenharmony_ci * "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT specifies that the image can be 452bf215546Sopenharmony_ci * created with usage flags that are not supported for the format the image 453bf215546Sopenharmony_ci * is created with but are supported for at least one format a VkImageView 454bf215546Sopenharmony_ci * created from the image can have." 455bf215546Sopenharmony_ci * 456bf215546Sopenharmony_ci * This means we should relax checks that only depend on the 457bf215546Sopenharmony_ci * format_feature_flags, to allow the user to create images that may be 458bf215546Sopenharmony_ci * e.g. reinterpreted as storage when the original format doesn't allow it. 459bf215546Sopenharmony_ci * The user will have to check against the format features anyway. 460bf215546Sopenharmony_ci * Otherwise we'd unnecessarily disallow it. 461bf215546Sopenharmony_ci */ 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci VkImageUsageFlags image_usage = info->usage; 464bf215546Sopenharmony_ci if (info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) 465bf215546Sopenharmony_ci image_usage = 0; 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_SAMPLED_BIT) { 468bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 469bf215546Sopenharmony_ci goto unsupported; 470bf215546Sopenharmony_ci } 471bf215546Sopenharmony_ci } 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_STORAGE_BIT) { 474bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) { 475bf215546Sopenharmony_ci goto unsupported; 476bf215546Sopenharmony_ci } 477bf215546Sopenharmony_ci } 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 480bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { 481bf215546Sopenharmony_ci goto unsupported; 482bf215546Sopenharmony_ci } 483bf215546Sopenharmony_ci } 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 486bf215546Sopenharmony_ci if (!(format_feature_flags & 487bf215546Sopenharmony_ci VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 488bf215546Sopenharmony_ci goto unsupported; 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci } 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci *pImageFormatProperties = (VkImageFormatProperties) { 493bf215546Sopenharmony_ci .maxExtent = maxExtent, 494bf215546Sopenharmony_ci .maxMipLevels = maxMipLevels, 495bf215546Sopenharmony_ci .maxArrayLayers = maxArraySize, 496bf215546Sopenharmony_ci .sampleCounts = sampleCounts, 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci /* FINISHME: Accurately calculate 499bf215546Sopenharmony_ci * VkImageFormatProperties::maxResourceSize. 500bf215546Sopenharmony_ci */ 501bf215546Sopenharmony_ci .maxResourceSize = UINT32_MAX, 502bf215546Sopenharmony_ci }; 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci if (p_feature_flags) 505bf215546Sopenharmony_ci *p_feature_flags = format_feature_flags; 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci return VK_SUCCESS; 508bf215546Sopenharmony_ciunsupported: 509bf215546Sopenharmony_ci *pImageFormatProperties = (VkImageFormatProperties) { 510bf215546Sopenharmony_ci .maxExtent = { 0, 0, 0 }, 511bf215546Sopenharmony_ci .maxMipLevels = 0, 512bf215546Sopenharmony_ci .maxArrayLayers = 0, 513bf215546Sopenharmony_ci .sampleCounts = 0, 514bf215546Sopenharmony_ci .maxResourceSize = 0, 515bf215546Sopenharmony_ci }; 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 518bf215546Sopenharmony_ci} 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_cistatic VkResult 521bf215546Sopenharmony_citu_get_external_image_format_properties( 522bf215546Sopenharmony_ci const struct tu_physical_device *physical_device, 523bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, 524bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlagBits handleType, 525bf215546Sopenharmony_ci VkExternalImageFormatProperties *external_properties) 526bf215546Sopenharmony_ci{ 527bf215546Sopenharmony_ci VkExternalMemoryFeatureFlagBits flags = 0; 528bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags export_flags = 0; 529bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags compat_flags = 0; 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ci /* From the Vulkan 1.1.98 spec: 532bf215546Sopenharmony_ci * 533bf215546Sopenharmony_ci * If handleType is not compatible with the format, type, tiling, 534bf215546Sopenharmony_ci * usage, and flags specified in VkPhysicalDeviceImageFormatInfo2, 535bf215546Sopenharmony_ci * then vkGetPhysicalDeviceImageFormatProperties2 returns 536bf215546Sopenharmony_ci * VK_ERROR_FORMAT_NOT_SUPPORTED. 537bf215546Sopenharmony_ci */ 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci switch (handleType) { 540bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 541bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 542bf215546Sopenharmony_ci switch (pImageFormatInfo->type) { 543bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 544bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT | 545bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 546bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 547bf215546Sopenharmony_ci compat_flags = export_flags = 548bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 549bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 550bf215546Sopenharmony_ci break; 551bf215546Sopenharmony_ci default: 552bf215546Sopenharmony_ci return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 553bf215546Sopenharmony_ci "VkExternalMemoryTypeFlagBits(0x%x) unsupported for VkImageType(%d)", 554bf215546Sopenharmony_ci handleType, pImageFormatInfo->type); 555bf215546Sopenharmony_ci } 556bf215546Sopenharmony_ci break; 557bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 558bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 559bf215546Sopenharmony_ci compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; 560bf215546Sopenharmony_ci break; 561bf215546Sopenharmony_ci default: 562bf215546Sopenharmony_ci return vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 563bf215546Sopenharmony_ci "VkExternalMemoryTypeFlagBits(0x%x) unsupported", 564bf215546Sopenharmony_ci handleType); 565bf215546Sopenharmony_ci } 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci if (external_properties) { 568bf215546Sopenharmony_ci external_properties->externalMemoryProperties = 569bf215546Sopenharmony_ci (VkExternalMemoryProperties) { 570bf215546Sopenharmony_ci .externalMemoryFeatures = flags, 571bf215546Sopenharmony_ci .exportFromImportedHandleTypes = export_flags, 572bf215546Sopenharmony_ci .compatibleHandleTypes = compat_flags, 573bf215546Sopenharmony_ci }; 574bf215546Sopenharmony_ci } 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci return VK_SUCCESS; 577bf215546Sopenharmony_ci} 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 580bf215546Sopenharmony_citu_GetPhysicalDeviceImageFormatProperties2( 581bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 582bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *base_info, 583bf215546Sopenharmony_ci VkImageFormatProperties2 *base_props) 584bf215546Sopenharmony_ci{ 585bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice); 586bf215546Sopenharmony_ci const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL; 587bf215546Sopenharmony_ci const VkPhysicalDeviceImageViewImageFormatInfoEXT *image_view_info = NULL; 588bf215546Sopenharmony_ci VkExternalImageFormatProperties *external_props = NULL; 589bf215546Sopenharmony_ci VkFilterCubicImageViewImageFormatPropertiesEXT *cubic_props = NULL; 590bf215546Sopenharmony_ci VkFormatFeatureFlags format_feature_flags; 591bf215546Sopenharmony_ci VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL; 592bf215546Sopenharmony_ci VkResult result; 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci result = tu_get_image_format_properties(physical_device, 595bf215546Sopenharmony_ci base_info, &base_props->imageFormatProperties, &format_feature_flags); 596bf215546Sopenharmony_ci if (result != VK_SUCCESS) 597bf215546Sopenharmony_ci return result; 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci /* Extract input structs */ 600bf215546Sopenharmony_ci vk_foreach_struct_const(s, base_info->pNext) 601bf215546Sopenharmony_ci { 602bf215546Sopenharmony_ci switch (s->sType) { 603bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: 604bf215546Sopenharmony_ci external_info = (const void *) s; 605bf215546Sopenharmony_ci break; 606bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT: 607bf215546Sopenharmony_ci image_view_info = (const void *) s; 608bf215546Sopenharmony_ci break; 609bf215546Sopenharmony_ci default: 610bf215546Sopenharmony_ci break; 611bf215546Sopenharmony_ci } 612bf215546Sopenharmony_ci } 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci /* Extract output structs */ 615bf215546Sopenharmony_ci vk_foreach_struct(s, base_props->pNext) 616bf215546Sopenharmony_ci { 617bf215546Sopenharmony_ci switch (s->sType) { 618bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES: 619bf215546Sopenharmony_ci external_props = (void *) s; 620bf215546Sopenharmony_ci break; 621bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT: 622bf215546Sopenharmony_ci cubic_props = (void *) s; 623bf215546Sopenharmony_ci break; 624bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES: 625bf215546Sopenharmony_ci ycbcr_props = (void *) s; 626bf215546Sopenharmony_ci break; 627bf215546Sopenharmony_ci default: 628bf215546Sopenharmony_ci break; 629bf215546Sopenharmony_ci } 630bf215546Sopenharmony_ci } 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci /* From the Vulkan 1.0.42 spec: 633bf215546Sopenharmony_ci * 634bf215546Sopenharmony_ci * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will 635bf215546Sopenharmony_ci * behave as if VkPhysicalDeviceExternalImageFormatInfo was not 636bf215546Sopenharmony_ci * present and VkExternalImageFormatProperties will be ignored. 637bf215546Sopenharmony_ci */ 638bf215546Sopenharmony_ci if (external_info && external_info->handleType != 0) { 639bf215546Sopenharmony_ci result = tu_get_external_image_format_properties( 640bf215546Sopenharmony_ci physical_device, base_info, external_info->handleType, 641bf215546Sopenharmony_ci external_props); 642bf215546Sopenharmony_ci if (result != VK_SUCCESS) 643bf215546Sopenharmony_ci goto fail; 644bf215546Sopenharmony_ci } 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci if (cubic_props) { 647bf215546Sopenharmony_ci /* note: blob only allows cubic filtering for 2D and 2D array views 648bf215546Sopenharmony_ci * its likely we can enable it for 1D and CUBE, needs testing however 649bf215546Sopenharmony_ci */ 650bf215546Sopenharmony_ci if ((image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D || 651bf215546Sopenharmony_ci image_view_info->imageViewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) && 652bf215546Sopenharmony_ci (format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) { 653bf215546Sopenharmony_ci cubic_props->filterCubic = true; 654bf215546Sopenharmony_ci cubic_props->filterCubicMinmax = true; 655bf215546Sopenharmony_ci } else { 656bf215546Sopenharmony_ci cubic_props->filterCubic = false; 657bf215546Sopenharmony_ci cubic_props->filterCubicMinmax = false; 658bf215546Sopenharmony_ci } 659bf215546Sopenharmony_ci } 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_ci if (ycbcr_props) 662bf215546Sopenharmony_ci ycbcr_props->combinedImageSamplerDescriptorCount = 1; 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_ci return VK_SUCCESS; 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_cifail: 667bf215546Sopenharmony_ci if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) { 668bf215546Sopenharmony_ci /* From the Vulkan 1.0.42 spec: 669bf215546Sopenharmony_ci * 670bf215546Sopenharmony_ci * If the combination of parameters to 671bf215546Sopenharmony_ci * vkGetPhysicalDeviceImageFormatProperties2 is not supported by 672bf215546Sopenharmony_ci * the implementation for use in vkCreateImage, then all members of 673bf215546Sopenharmony_ci * imageFormatProperties will be filled with zero. 674bf215546Sopenharmony_ci */ 675bf215546Sopenharmony_ci base_props->imageFormatProperties = (VkImageFormatProperties) {}; 676bf215546Sopenharmony_ci } 677bf215546Sopenharmony_ci 678bf215546Sopenharmony_ci return result; 679bf215546Sopenharmony_ci} 680bf215546Sopenharmony_ci 681bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 682bf215546Sopenharmony_citu_GetPhysicalDeviceSparseImageFormatProperties2( 683bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 684bf215546Sopenharmony_ci const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, 685bf215546Sopenharmony_ci uint32_t *pPropertyCount, 686bf215546Sopenharmony_ci VkSparseImageFormatProperties2 *pProperties) 687bf215546Sopenharmony_ci{ 688bf215546Sopenharmony_ci /* Sparse images are not yet supported. */ 689bf215546Sopenharmony_ci *pPropertyCount = 0; 690bf215546Sopenharmony_ci} 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 693bf215546Sopenharmony_citu_GetPhysicalDeviceExternalBufferProperties( 694bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 695bf215546Sopenharmony_ci const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, 696bf215546Sopenharmony_ci VkExternalBufferProperties *pExternalBufferProperties) 697bf215546Sopenharmony_ci{ 698bf215546Sopenharmony_ci VkExternalMemoryFeatureFlagBits flags = 0; 699bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags export_flags = 0; 700bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags compat_flags = 0; 701bf215546Sopenharmony_ci switch (pExternalBufferInfo->handleType) { 702bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 703bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 704bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 705bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 706bf215546Sopenharmony_ci compat_flags = export_flags = 707bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 708bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 709bf215546Sopenharmony_ci break; 710bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 711bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 712bf215546Sopenharmony_ci compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; 713bf215546Sopenharmony_ci break; 714bf215546Sopenharmony_ci default: 715bf215546Sopenharmony_ci break; 716bf215546Sopenharmony_ci } 717bf215546Sopenharmony_ci pExternalBufferProperties->externalMemoryProperties = 718bf215546Sopenharmony_ci (VkExternalMemoryProperties) { 719bf215546Sopenharmony_ci .externalMemoryFeatures = flags, 720bf215546Sopenharmony_ci .exportFromImportedHandleTypes = export_flags, 721bf215546Sopenharmony_ci .compatibleHandleTypes = compat_flags, 722bf215546Sopenharmony_ci }; 723bf215546Sopenharmony_ci} 724