1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2019 Raspberry Pi Ltd 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "v3dv_private.h" 25bf215546Sopenharmony_ci#include "vk_util.h" 26bf215546Sopenharmony_ci#include "vk_enum_defines.h" 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 29bf215546Sopenharmony_ci#include "util/format/u_format.h" 30bf215546Sopenharmony_ci#include "vulkan/wsi/wsi_common.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ciconst uint8_t * 33bf215546Sopenharmony_civ3dv_get_format_swizzle(struct v3dv_device *device, VkFormat f) 34bf215546Sopenharmony_ci{ 35bf215546Sopenharmony_ci const struct v3dv_format *vf = v3dv_X(device, get_format)(f); 36bf215546Sopenharmony_ci static const uint8_t fallback[] = {0, 1, 2, 3}; 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci if (!vf) 39bf215546Sopenharmony_ci return fallback; 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci return vf->swizzle; 42bf215546Sopenharmony_ci} 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cibool 45bf215546Sopenharmony_civ3dv_format_swizzle_needs_rb_swap(const uint8_t *swizzle) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci /* Normal case */ 48bf215546Sopenharmony_ci if (swizzle[0] == PIPE_SWIZZLE_Z) 49bf215546Sopenharmony_ci return swizzle[2] == PIPE_SWIZZLE_X; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci /* Format uses reverse flag */ 52bf215546Sopenharmony_ci if (swizzle[0] == PIPE_SWIZZLE_Y) 53bf215546Sopenharmony_ci return swizzle[2] == PIPE_SWIZZLE_W; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci return false; 56bf215546Sopenharmony_ci} 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_cibool 59bf215546Sopenharmony_civ3dv_format_swizzle_needs_reverse(const uint8_t *swizzle) 60bf215546Sopenharmony_ci{ 61bf215546Sopenharmony_ci /* Normal case */ 62bf215546Sopenharmony_ci if (swizzle[0] == PIPE_SWIZZLE_W && 63bf215546Sopenharmony_ci swizzle[1] == PIPE_SWIZZLE_Z && 64bf215546Sopenharmony_ci swizzle[2] == PIPE_SWIZZLE_Y && 65bf215546Sopenharmony_ci swizzle[3] == PIPE_SWIZZLE_X) { 66bf215546Sopenharmony_ci return true; 67bf215546Sopenharmony_ci } 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci /* Format uses RB swap flag */ 70bf215546Sopenharmony_ci if (swizzle[0] == PIPE_SWIZZLE_Y && 71bf215546Sopenharmony_ci swizzle[1] == PIPE_SWIZZLE_Z && 72bf215546Sopenharmony_ci swizzle[2] == PIPE_SWIZZLE_W && 73bf215546Sopenharmony_ci swizzle[3] == PIPE_SWIZZLE_X) { 74bf215546Sopenharmony_ci return true; 75bf215546Sopenharmony_ci } 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci return false; 78bf215546Sopenharmony_ci} 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ciuint8_t 81bf215546Sopenharmony_civ3dv_get_tex_return_size(const struct v3dv_format *vf, 82bf215546Sopenharmony_ci bool compare_enable) 83bf215546Sopenharmony_ci{ 84bf215546Sopenharmony_ci if (unlikely(V3D_DEBUG & V3D_DEBUG_TMU_16BIT)) 85bf215546Sopenharmony_ci return 16; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci if (unlikely(V3D_DEBUG & V3D_DEBUG_TMU_32BIT)) 88bf215546Sopenharmony_ci return 32; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci if (compare_enable) 91bf215546Sopenharmony_ci return 16; 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci return vf->return_size; 94bf215546Sopenharmony_ci} 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci/* Some cases of transfer operations are raw data copies that don't depend 97bf215546Sopenharmony_ci * on the semantics of the pixel format (no pixel format conversions are 98bf215546Sopenharmony_ci * involved). In these cases, it is safe to choose any format supported by 99bf215546Sopenharmony_ci * the TFU so long as it has the same texel size, which allows us to use the 100bf215546Sopenharmony_ci * TFU paths with formats that are not TFU supported otherwise. 101bf215546Sopenharmony_ci */ 102bf215546Sopenharmony_ciconst struct v3dv_format * 103bf215546Sopenharmony_civ3dv_get_compatible_tfu_format(struct v3dv_device *device, 104bf215546Sopenharmony_ci uint32_t bpp, 105bf215546Sopenharmony_ci VkFormat *out_vk_format) 106bf215546Sopenharmony_ci{ 107bf215546Sopenharmony_ci VkFormat vk_format; 108bf215546Sopenharmony_ci switch (bpp) { 109bf215546Sopenharmony_ci case 16: vk_format = VK_FORMAT_R32G32B32A32_SFLOAT; break; 110bf215546Sopenharmony_ci case 8: vk_format = VK_FORMAT_R16G16B16A16_SFLOAT; break; 111bf215546Sopenharmony_ci case 4: vk_format = VK_FORMAT_R32_SFLOAT; break; 112bf215546Sopenharmony_ci case 2: vk_format = VK_FORMAT_R16_SFLOAT; break; 113bf215546Sopenharmony_ci case 1: vk_format = VK_FORMAT_R8_UNORM; break; 114bf215546Sopenharmony_ci default: unreachable("unsupported format bit-size"); break; 115bf215546Sopenharmony_ci }; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci if (out_vk_format) 118bf215546Sopenharmony_ci *out_vk_format = vk_format; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci const struct v3dv_format *format = v3dv_X(device, get_format)(vk_format); 121bf215546Sopenharmony_ci assert(v3dv_X(device, tfu_supports_tex_format)(format->tex_type)); 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci return format; 124bf215546Sopenharmony_ci} 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_cistatic VkFormatFeatureFlags2 127bf215546Sopenharmony_ciimage_format_features(struct v3dv_physical_device *pdevice, 128bf215546Sopenharmony_ci VkFormat vk_format, 129bf215546Sopenharmony_ci const struct v3dv_format *v3dv_format, 130bf215546Sopenharmony_ci VkImageTiling tiling) 131bf215546Sopenharmony_ci{ 132bf215546Sopenharmony_ci if (!v3dv_format || !v3dv_format->supported) 133bf215546Sopenharmony_ci return 0; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci const VkImageAspectFlags aspects = vk_format_aspects(vk_format); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci const VkImageAspectFlags zs_aspects = VK_IMAGE_ASPECT_DEPTH_BIT | 138bf215546Sopenharmony_ci VK_IMAGE_ASPECT_STENCIL_BIT; 139bf215546Sopenharmony_ci const VkImageAspectFlags supported_aspects = VK_IMAGE_ASPECT_COLOR_BIT | 140bf215546Sopenharmony_ci zs_aspects; 141bf215546Sopenharmony_ci if ((aspects & supported_aspects) != aspects) 142bf215546Sopenharmony_ci return 0; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci /* FIXME: We don't support separate stencil yet */ 145bf215546Sopenharmony_ci if ((aspects & zs_aspects) == VK_IMAGE_ASPECT_STENCIL_BIT) 146bf215546Sopenharmony_ci return 0; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci if (v3dv_format->tex_type == TEXTURE_DATA_FORMAT_NO && 149bf215546Sopenharmony_ci v3dv_format->rt_type == V3D_OUTPUT_IMAGE_FORMAT_NO) { 150bf215546Sopenharmony_ci return 0; 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci VkFormatFeatureFlags2 flags = 0; 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci /* Raster format is only supported for 1D textures, so let's just 156bf215546Sopenharmony_ci * always require optimal tiling for anything that requires sampling. 157bf215546Sopenharmony_ci * Note: even if the user requests optimal for a 1D image, we will still 158bf215546Sopenharmony_ci * use raster format since that is what the HW requires. 159bf215546Sopenharmony_ci */ 160bf215546Sopenharmony_ci if (v3dv_format->tex_type != TEXTURE_DATA_FORMAT_NO && 161bf215546Sopenharmony_ci tiling == VK_IMAGE_TILING_OPTIMAL) { 162bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | 163bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_BLIT_SRC_BIT; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci if (v3dv_format->supports_filtering) 166bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci if (v3dv_format->rt_type != V3D_OUTPUT_IMAGE_FORMAT_NO) { 170bf215546Sopenharmony_ci if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) { 171bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | 172bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_BLIT_DST_BIT; 173bf215546Sopenharmony_ci if (v3dv_X(pdevice, format_supports_blending)(v3dv_format)) 174bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT; 175bf215546Sopenharmony_ci } else if (aspects & zs_aspects) { 176bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT | 177bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_BLIT_DST_BIT; 178bf215546Sopenharmony_ci } 179bf215546Sopenharmony_ci } 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci const struct util_format_description *desc = 182bf215546Sopenharmony_ci vk_format_description(vk_format); 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci if (tiling != VK_IMAGE_TILING_LINEAR) { 185bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && desc->is_array) { 186bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT; 187bf215546Sopenharmony_ci if (desc->nr_channels == 1 && vk_format_is_int(vk_format)) 188bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT; 189bf215546Sopenharmony_ci } else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 || 190bf215546Sopenharmony_ci vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32 || 191bf215546Sopenharmony_ci vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { 192bf215546Sopenharmony_ci /* To comply with shaderStorageImageExtendedFormats */ 193bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT; 194bf215546Sopenharmony_ci } 195bf215546Sopenharmony_ci } 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci /* All our depth formats support shadow comparisons. */ 198bf215546Sopenharmony_ci if (vk_format_has_depth(vk_format) && 199bf215546Sopenharmony_ci (flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) { 200bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT; 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci if (flags) { 204bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | 205bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; 206bf215546Sopenharmony_ci } 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci return flags; 209bf215546Sopenharmony_ci} 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_cistatic VkFormatFeatureFlags2 212bf215546Sopenharmony_cibuffer_format_features(VkFormat vk_format, const struct v3dv_format *v3dv_format) 213bf215546Sopenharmony_ci{ 214bf215546Sopenharmony_ci if (!v3dv_format || !v3dv_format->supported) 215bf215546Sopenharmony_ci return 0; 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci if (!v3dv_format->supported) 218bf215546Sopenharmony_ci return 0; 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci /* We probably only want to support buffer formats that have a 221bf215546Sopenharmony_ci * color format specification. 222bf215546Sopenharmony_ci */ 223bf215546Sopenharmony_ci if (!vk_format_is_color(vk_format)) 224bf215546Sopenharmony_ci return 0; 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci const struct util_format_description *desc = 227bf215546Sopenharmony_ci vk_format_description(vk_format); 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci VkFormatFeatureFlags2 flags = 0; 230bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && 231bf215546Sopenharmony_ci desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB && 232bf215546Sopenharmony_ci desc->is_array) { 233bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT; 234bf215546Sopenharmony_ci if (v3dv_format->tex_type != TEXTURE_DATA_FORMAT_NO) { 235bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT | 236bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT; 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci } else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) { 239bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT | 240bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT | 241bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT; 242bf215546Sopenharmony_ci } else if (vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32 || 243bf215546Sopenharmony_ci vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { 244bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT | 245bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT; 246bf215546Sopenharmony_ci } 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && 249bf215546Sopenharmony_ci desc->is_array && 250bf215546Sopenharmony_ci desc->nr_channels == 1 && 251bf215546Sopenharmony_ci vk_format_is_int(vk_format)) { 252bf215546Sopenharmony_ci flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT; 253bf215546Sopenharmony_ci } 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci return flags; 256bf215546Sopenharmony_ci} 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_cibool 259bf215546Sopenharmony_civ3dv_buffer_format_supports_features(struct v3dv_device *device, 260bf215546Sopenharmony_ci VkFormat vk_format, 261bf215546Sopenharmony_ci VkFormatFeatureFlags2 features) 262bf215546Sopenharmony_ci{ 263bf215546Sopenharmony_ci const struct v3dv_format *v3dv_format = v3dv_X(device, get_format)(vk_format); 264bf215546Sopenharmony_ci const VkFormatFeatureFlags2 supported = 265bf215546Sopenharmony_ci buffer_format_features(vk_format, v3dv_format); 266bf215546Sopenharmony_ci return (supported & features) == features; 267bf215546Sopenharmony_ci} 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci/* FIXME: this helper now on anv, radv, lvp, and v3dv. Perhaps common 270bf215546Sopenharmony_ci * place? 271bf215546Sopenharmony_ci */ 272bf215546Sopenharmony_cistatic inline VkFormatFeatureFlags 273bf215546Sopenharmony_cifeatures2_to_features(VkFormatFeatureFlags2 features2) 274bf215546Sopenharmony_ci{ 275bf215546Sopenharmony_ci return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS; 276bf215546Sopenharmony_ci} 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 279bf215546Sopenharmony_civ3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, 280bf215546Sopenharmony_ci VkFormat format, 281bf215546Sopenharmony_ci VkFormatProperties2 *pFormatProperties) 282bf215546Sopenharmony_ci{ 283bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice); 284bf215546Sopenharmony_ci const struct v3dv_format *v3dv_format = v3dv_X(pdevice, get_format)(format); 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci VkFormatFeatureFlags2 linear2, optimal2, buffer2; 287bf215546Sopenharmony_ci linear2 = image_format_features(pdevice, format, v3dv_format, 288bf215546Sopenharmony_ci VK_IMAGE_TILING_LINEAR); 289bf215546Sopenharmony_ci optimal2 = image_format_features(pdevice, format, v3dv_format, 290bf215546Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL); 291bf215546Sopenharmony_ci buffer2 = buffer_format_features(format, v3dv_format); 292bf215546Sopenharmony_ci pFormatProperties->formatProperties = (VkFormatProperties) { 293bf215546Sopenharmony_ci .linearTilingFeatures = features2_to_features(linear2), 294bf215546Sopenharmony_ci .optimalTilingFeatures = features2_to_features(optimal2), 295bf215546Sopenharmony_ci .bufferFeatures = features2_to_features(buffer2), 296bf215546Sopenharmony_ci }; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci vk_foreach_struct(ext, pFormatProperties->pNext) { 299bf215546Sopenharmony_ci switch ((unsigned)ext->sType) { 300bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: { 301bf215546Sopenharmony_ci struct VkDrmFormatModifierPropertiesListEXT *list = (void *)ext; 302bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out, 303bf215546Sopenharmony_ci list->pDrmFormatModifierProperties, 304bf215546Sopenharmony_ci &list->drmFormatModifierCount); 305bf215546Sopenharmony_ci if (pFormatProperties->formatProperties.linearTilingFeatures) { 306bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, 307bf215546Sopenharmony_ci &out, mod_props) { 308bf215546Sopenharmony_ci mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; 309bf215546Sopenharmony_ci mod_props->drmFormatModifierPlaneCount = 1; 310bf215546Sopenharmony_ci mod_props->drmFormatModifierTilingFeatures = 311bf215546Sopenharmony_ci pFormatProperties->formatProperties.linearTilingFeatures; 312bf215546Sopenharmony_ci } 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci if (pFormatProperties->formatProperties.optimalTilingFeatures) { 315bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, 316bf215546Sopenharmony_ci &out, mod_props) { 317bf215546Sopenharmony_ci mod_props->drmFormatModifier = DRM_FORMAT_MOD_BROADCOM_UIF; 318bf215546Sopenharmony_ci mod_props->drmFormatModifierPlaneCount = 1; 319bf215546Sopenharmony_ci mod_props->drmFormatModifierTilingFeatures = 320bf215546Sopenharmony_ci pFormatProperties->formatProperties.optimalTilingFeatures; 321bf215546Sopenharmony_ci } 322bf215546Sopenharmony_ci } 323bf215546Sopenharmony_ci break; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: { 326bf215546Sopenharmony_ci struct VkDrmFormatModifierPropertiesList2EXT *list = (void *)ext; 327bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out, 328bf215546Sopenharmony_ci list->pDrmFormatModifierProperties, 329bf215546Sopenharmony_ci &list->drmFormatModifierCount); 330bf215546Sopenharmony_ci if (linear2) { 331bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, 332bf215546Sopenharmony_ci &out, mod_props) { 333bf215546Sopenharmony_ci mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR; 334bf215546Sopenharmony_ci mod_props->drmFormatModifierPlaneCount = 1; 335bf215546Sopenharmony_ci mod_props->drmFormatModifierTilingFeatures = linear2; 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci if (optimal2) { 339bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, 340bf215546Sopenharmony_ci &out, mod_props) { 341bf215546Sopenharmony_ci mod_props->drmFormatModifier = DRM_FORMAT_MOD_BROADCOM_UIF; 342bf215546Sopenharmony_ci mod_props->drmFormatModifierPlaneCount = 1; 343bf215546Sopenharmony_ci mod_props->drmFormatModifierTilingFeatures = optimal2; 344bf215546Sopenharmony_ci } 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci break; 347bf215546Sopenharmony_ci } 348bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3: { 349bf215546Sopenharmony_ci VkFormatProperties3 *props = (VkFormatProperties3 *)ext; 350bf215546Sopenharmony_ci props->linearTilingFeatures = linear2; 351bf215546Sopenharmony_ci props->optimalTilingFeatures = optimal2; 352bf215546Sopenharmony_ci props->bufferFeatures = buffer2; 353bf215546Sopenharmony_ci break; 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci default: 356bf215546Sopenharmony_ci v3dv_debug_ignored_stype(ext->sType); 357bf215546Sopenharmony_ci break; 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci} 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_cistatic VkResult 363bf215546Sopenharmony_ciget_image_format_properties( 364bf215546Sopenharmony_ci struct v3dv_physical_device *physical_device, 365bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *info, 366bf215546Sopenharmony_ci VkImageTiling tiling, 367bf215546Sopenharmony_ci VkImageFormatProperties *pImageFormatProperties, 368bf215546Sopenharmony_ci VkSamplerYcbcrConversionImageFormatProperties *pYcbcrImageFormatProperties) 369bf215546Sopenharmony_ci{ 370bf215546Sopenharmony_ci const struct v3dv_format *v3dv_format = v3dv_X(physical_device, get_format)(info->format); 371bf215546Sopenharmony_ci VkFormatFeatureFlags2 format_feature_flags = 372bf215546Sopenharmony_ci image_format_features(physical_device, info->format, v3dv_format, tiling); 373bf215546Sopenharmony_ci if (!format_feature_flags) 374bf215546Sopenharmony_ci goto unsupported; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci /* This allows users to create uncompressed views of compressed images, 377bf215546Sopenharmony_ci * however this is not something the hardware supports naturally and requires 378bf215546Sopenharmony_ci * the driver to lie when programming the texture state to make the hardware 379bf215546Sopenharmony_ci * sample with the uncompressed view correctly, and even then, there are 380bf215546Sopenharmony_ci * issues when running on real hardware. 381bf215546Sopenharmony_ci * 382bf215546Sopenharmony_ci * See https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11336 383bf215546Sopenharmony_ci * for details. 384bf215546Sopenharmony_ci */ 385bf215546Sopenharmony_ci if (info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) 386bf215546Sopenharmony_ci goto unsupported; 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_ci const VkImageStencilUsageCreateInfo *stencil_usage_info = 389bf215546Sopenharmony_ci vk_find_struct_const(info->pNext, IMAGE_STENCIL_USAGE_CREATE_INFO); 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci VkImageUsageFlags image_usage = 392bf215546Sopenharmony_ci info->usage | (stencil_usage_info ? stencil_usage_info->stencilUsage : 0); 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci /* If VK_IMAGE_CREATE_EXTENDED_USAGE_BIT is set it means the usage flags may 395bf215546Sopenharmony_ci * not be be supported for the image format but are supported for at least 396bf215546Sopenharmony_ci * one compatible format from which an image view can be created for the 397bf215546Sopenharmony_ci * image. This means we should not report the format as unsupported based 398bf215546Sopenharmony_ci * on the usage flags when usage refers to how an image view may be used 399bf215546Sopenharmony_ci * (i.e. as a framebuffer attachment, for sampling, etc). 400bf215546Sopenharmony_ci */ 401bf215546Sopenharmony_ci VkImageUsageFlags view_usage = 402bf215546Sopenharmony_ci info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT ? 0 : image_usage; 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { 405bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) { 406bf215546Sopenharmony_ci goto unsupported; 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci /* Sampling of raster depth/stencil images is not supported. Since 1D 410bf215546Sopenharmony_ci * images are always raster, even if the user requested optimal tiling, 411bf215546Sopenharmony_ci * we can't have them be used as transfer sources, since that includes 412bf215546Sopenharmony_ci * using them for blit sources, which might require sampling. 413bf215546Sopenharmony_ci */ 414bf215546Sopenharmony_ci if (info->type == VK_IMAGE_TYPE_1D && 415bf215546Sopenharmony_ci vk_format_is_depth_or_stencil(info->format)) { 416bf215546Sopenharmony_ci goto unsupported; 417bf215546Sopenharmony_ci } 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { 421bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) { 422bf215546Sopenharmony_ci goto unsupported; 423bf215546Sopenharmony_ci } 424bf215546Sopenharmony_ci } 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci if (view_usage & (VK_IMAGE_USAGE_SAMPLED_BIT | 427bf215546Sopenharmony_ci VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) { 428bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) { 429bf215546Sopenharmony_ci goto unsupported; 430bf215546Sopenharmony_ci } 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci /* Sampling of raster depth/stencil images is not supported. Since 1D 433bf215546Sopenharmony_ci * images are always raster, even if the user requested optimal tiling, 434bf215546Sopenharmony_ci * we can't allow sampling if the format is depth/stencil. 435bf215546Sopenharmony_ci */ 436bf215546Sopenharmony_ci if (info->type == VK_IMAGE_TYPE_1D && 437bf215546Sopenharmony_ci vk_format_is_depth_or_stencil(info->format)) { 438bf215546Sopenharmony_ci goto unsupported; 439bf215546Sopenharmony_ci } 440bf215546Sopenharmony_ci } 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ci if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) { 443bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) { 444bf215546Sopenharmony_ci goto unsupported; 445bf215546Sopenharmony_ci } 446bf215546Sopenharmony_ci } 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci if (view_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 449bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) { 450bf215546Sopenharmony_ci goto unsupported; 451bf215546Sopenharmony_ci } 452bf215546Sopenharmony_ci } 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci if (view_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 455bf215546Sopenharmony_ci if (!(format_feature_flags & 456bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) { 457bf215546Sopenharmony_ci goto unsupported; 458bf215546Sopenharmony_ci } 459bf215546Sopenharmony_ci } 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci switch (info->type) { 462bf215546Sopenharmony_ci case VK_IMAGE_TYPE_1D: 463bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.width = V3D_MAX_IMAGE_DIMENSION; 464bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.height = 1; 465bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.depth = 1; 466bf215546Sopenharmony_ci pImageFormatProperties->maxArrayLayers = V3D_MAX_ARRAY_LAYERS; 467bf215546Sopenharmony_ci pImageFormatProperties->maxMipLevels = V3D_MAX_MIP_LEVELS; 468bf215546Sopenharmony_ci break; 469bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 470bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.width = V3D_MAX_IMAGE_DIMENSION; 471bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.height = V3D_MAX_IMAGE_DIMENSION; 472bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.depth = 1; 473bf215546Sopenharmony_ci pImageFormatProperties->maxArrayLayers = V3D_MAX_ARRAY_LAYERS; 474bf215546Sopenharmony_ci pImageFormatProperties->maxMipLevels = V3D_MAX_MIP_LEVELS; 475bf215546Sopenharmony_ci break; 476bf215546Sopenharmony_ci case VK_IMAGE_TYPE_3D: 477bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.width = V3D_MAX_IMAGE_DIMENSION; 478bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.height = V3D_MAX_IMAGE_DIMENSION; 479bf215546Sopenharmony_ci pImageFormatProperties->maxExtent.depth = V3D_MAX_IMAGE_DIMENSION; 480bf215546Sopenharmony_ci pImageFormatProperties->maxArrayLayers = 1; 481bf215546Sopenharmony_ci pImageFormatProperties->maxMipLevels = V3D_MAX_MIP_LEVELS; 482bf215546Sopenharmony_ci break; 483bf215546Sopenharmony_ci default: 484bf215546Sopenharmony_ci unreachable("bad VkImageType"); 485bf215546Sopenharmony_ci } 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci /* Our hw doesn't support 1D compressed textures. */ 488bf215546Sopenharmony_ci if (info->type == VK_IMAGE_TYPE_1D && 489bf215546Sopenharmony_ci vk_format_is_compressed(info->format)) { 490bf215546Sopenharmony_ci goto unsupported; 491bf215546Sopenharmony_ci } 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci /* From the Vulkan 1.0 spec, section 34.1.1. Supported Sample Counts: 494bf215546Sopenharmony_ci * 495bf215546Sopenharmony_ci * sampleCounts will be set to VK_SAMPLE_COUNT_1_BIT if at least one of the 496bf215546Sopenharmony_ci * following conditions is true: 497bf215546Sopenharmony_ci * 498bf215546Sopenharmony_ci * - tiling is VK_IMAGE_TILING_LINEAR 499bf215546Sopenharmony_ci * - type is not VK_IMAGE_TYPE_2D 500bf215546Sopenharmony_ci * - flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT 501bf215546Sopenharmony_ci * - neither the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag nor the 502bf215546Sopenharmony_ci * VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in 503bf215546Sopenharmony_ci * VkFormatProperties::optimalTilingFeatures returned by 504bf215546Sopenharmony_ci * vkGetPhysicalDeviceFormatProperties is set. 505bf215546Sopenharmony_ci */ 506bf215546Sopenharmony_ci pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT; 507bf215546Sopenharmony_ci if (tiling != VK_IMAGE_TILING_LINEAR && 508bf215546Sopenharmony_ci info->type == VK_IMAGE_TYPE_2D && 509bf215546Sopenharmony_ci !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 510bf215546Sopenharmony_ci (format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT || 511bf215546Sopenharmony_ci format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) { 512bf215546Sopenharmony_ci pImageFormatProperties->sampleCounts |= VK_SAMPLE_COUNT_4_BIT; 513bf215546Sopenharmony_ci } 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci if (tiling == VK_IMAGE_TILING_LINEAR) 516bf215546Sopenharmony_ci pImageFormatProperties->maxMipLevels = 1; 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci pImageFormatProperties->maxResourceSize = 0xffffffff; /* 32-bit allocation */ 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci return VK_SUCCESS; 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ciunsupported: 523bf215546Sopenharmony_ci *pImageFormatProperties = (VkImageFormatProperties) { 524bf215546Sopenharmony_ci .maxExtent = { 0, 0, 0 }, 525bf215546Sopenharmony_ci .maxMipLevels = 0, 526bf215546Sopenharmony_ci .maxArrayLayers = 0, 527bf215546Sopenharmony_ci .sampleCounts = 0, 528bf215546Sopenharmony_ci .maxResourceSize = 0, 529bf215546Sopenharmony_ci }; 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 532bf215546Sopenharmony_ci} 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_cistatic const VkExternalMemoryProperties prime_fd_props = { 535bf215546Sopenharmony_ci .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 536bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 537bf215546Sopenharmony_ci .exportFromImportedHandleTypes = 538bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 539bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 540bf215546Sopenharmony_ci .compatibleHandleTypes = 541bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 542bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 543bf215546Sopenharmony_ci}; 544bf215546Sopenharmony_ci 545bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 546bf215546Sopenharmony_civ3dv_GetPhysicalDeviceImageFormatProperties( 547bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 548bf215546Sopenharmony_ci VkFormat format, 549bf215546Sopenharmony_ci VkImageType type, 550bf215546Sopenharmony_ci VkImageTiling tiling, 551bf215546Sopenharmony_ci VkImageUsageFlags usage, 552bf215546Sopenharmony_ci VkImageCreateFlags createFlags, 553bf215546Sopenharmony_ci VkImageFormatProperties *pImageFormatProperties) 554bf215546Sopenharmony_ci{ 555bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice); 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 info = { 558bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, 559bf215546Sopenharmony_ci .pNext = NULL, 560bf215546Sopenharmony_ci .format = format, 561bf215546Sopenharmony_ci .type = type, 562bf215546Sopenharmony_ci .tiling = tiling, 563bf215546Sopenharmony_ci .usage = usage, 564bf215546Sopenharmony_ci .flags = createFlags, 565bf215546Sopenharmony_ci }; 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci return get_image_format_properties(physical_device, &info, tiling, 568bf215546Sopenharmony_ci pImageFormatProperties, NULL); 569bf215546Sopenharmony_ci} 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 572bf215546Sopenharmony_civ3dv_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, 573bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *base_info, 574bf215546Sopenharmony_ci VkImageFormatProperties2 *base_props) 575bf215546Sopenharmony_ci{ 576bf215546Sopenharmony_ci V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice); 577bf215546Sopenharmony_ci const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL; 578bf215546Sopenharmony_ci const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_format_mod_info = NULL; 579bf215546Sopenharmony_ci VkExternalImageFormatProperties *external_props = NULL; 580bf215546Sopenharmony_ci VkImageTiling tiling = base_info->tiling; 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci /* Extract input structs */ 583bf215546Sopenharmony_ci vk_foreach_struct_const(s, base_info->pNext) { 584bf215546Sopenharmony_ci switch (s->sType) { 585bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: 586bf215546Sopenharmony_ci external_info = (const void *) s; 587bf215546Sopenharmony_ci break; 588bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO: 589bf215546Sopenharmony_ci /* Do nothing, get_image_format_properties() below will handle it */; 590bf215546Sopenharmony_ci break; 591bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: 592bf215546Sopenharmony_ci drm_format_mod_info = (const void *) s; 593bf215546Sopenharmony_ci switch (drm_format_mod_info->drmFormatModifier) { 594bf215546Sopenharmony_ci case DRM_FORMAT_MOD_LINEAR: 595bf215546Sopenharmony_ci tiling = VK_IMAGE_TILING_LINEAR; 596bf215546Sopenharmony_ci break; 597bf215546Sopenharmony_ci case DRM_FORMAT_MOD_BROADCOM_UIF: 598bf215546Sopenharmony_ci tiling = VK_IMAGE_TILING_OPTIMAL; 599bf215546Sopenharmony_ci break; 600bf215546Sopenharmony_ci default: 601bf215546Sopenharmony_ci assert("Unknown DRM format modifier"); 602bf215546Sopenharmony_ci } 603bf215546Sopenharmony_ci break; 604bf215546Sopenharmony_ci default: 605bf215546Sopenharmony_ci v3dv_debug_ignored_stype(s->sType); 606bf215546Sopenharmony_ci break; 607bf215546Sopenharmony_ci } 608bf215546Sopenharmony_ci } 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci assert(tiling == VK_IMAGE_TILING_OPTIMAL || 611bf215546Sopenharmony_ci tiling == VK_IMAGE_TILING_LINEAR); 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci /* Extract output structs */ 614bf215546Sopenharmony_ci vk_foreach_struct(s, base_props->pNext) { 615bf215546Sopenharmony_ci switch (s->sType) { 616bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES: 617bf215546Sopenharmony_ci external_props = (void *) s; 618bf215546Sopenharmony_ci break; 619bf215546Sopenharmony_ci default: 620bf215546Sopenharmony_ci v3dv_debug_ignored_stype(s->sType); 621bf215546Sopenharmony_ci break; 622bf215546Sopenharmony_ci } 623bf215546Sopenharmony_ci } 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci VkResult result = 626bf215546Sopenharmony_ci get_image_format_properties(physical_device, base_info, tiling, 627bf215546Sopenharmony_ci &base_props->imageFormatProperties, NULL); 628bf215546Sopenharmony_ci if (result != VK_SUCCESS) 629bf215546Sopenharmony_ci goto done; 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci if (external_info && external_info->handleType != 0) { 632bf215546Sopenharmony_ci switch (external_info->handleType) { 633bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 634bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 635bf215546Sopenharmony_ci if (external_props) 636bf215546Sopenharmony_ci external_props->externalMemoryProperties = prime_fd_props; 637bf215546Sopenharmony_ci break; 638bf215546Sopenharmony_ci default: 639bf215546Sopenharmony_ci result = VK_ERROR_FORMAT_NOT_SUPPORTED; 640bf215546Sopenharmony_ci break; 641bf215546Sopenharmony_ci } 642bf215546Sopenharmony_ci } 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_cidone: 645bf215546Sopenharmony_ci return result; 646bf215546Sopenharmony_ci} 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 649bf215546Sopenharmony_civ3dv_GetPhysicalDeviceSparseImageFormatProperties( 650bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 651bf215546Sopenharmony_ci VkFormat format, 652bf215546Sopenharmony_ci VkImageType type, 653bf215546Sopenharmony_ci VkSampleCountFlagBits samples, 654bf215546Sopenharmony_ci VkImageUsageFlags usage, 655bf215546Sopenharmony_ci VkImageTiling tiling, 656bf215546Sopenharmony_ci uint32_t *pPropertyCount, 657bf215546Sopenharmony_ci VkSparseImageFormatProperties *pProperties) 658bf215546Sopenharmony_ci{ 659bf215546Sopenharmony_ci *pPropertyCount = 0; 660bf215546Sopenharmony_ci} 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 663bf215546Sopenharmony_civ3dv_GetPhysicalDeviceSparseImageFormatProperties2( 664bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 665bf215546Sopenharmony_ci const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, 666bf215546Sopenharmony_ci uint32_t *pPropertyCount, 667bf215546Sopenharmony_ci VkSparseImageFormatProperties2 *pProperties) 668bf215546Sopenharmony_ci{ 669bf215546Sopenharmony_ci *pPropertyCount = 0; 670bf215546Sopenharmony_ci} 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 673bf215546Sopenharmony_civ3dv_GetPhysicalDeviceExternalBufferProperties( 674bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, 675bf215546Sopenharmony_ci const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, 676bf215546Sopenharmony_ci VkExternalBufferProperties *pExternalBufferProperties) 677bf215546Sopenharmony_ci{ 678bf215546Sopenharmony_ci switch (pExternalBufferInfo->handleType) { 679bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 680bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 681bf215546Sopenharmony_ci pExternalBufferProperties->externalMemoryProperties = prime_fd_props; 682bf215546Sopenharmony_ci return; 683bf215546Sopenharmony_ci default: /* Unsupported */ 684bf215546Sopenharmony_ci pExternalBufferProperties->externalMemoryProperties = 685bf215546Sopenharmony_ci (VkExternalMemoryProperties) { 686bf215546Sopenharmony_ci .compatibleHandleTypes = pExternalBufferInfo->handleType, 687bf215546Sopenharmony_ci }; 688bf215546Sopenharmony_ci break; 689bf215546Sopenharmony_ci } 690bf215546Sopenharmony_ci} 691