• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2019 Red Hat.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "lvp_private.h"
25 #include "util/detect.h"
26 #include "pipe/p_defines.h"
27 #include "util/format/u_format.h"
28 #include "util/u_math.h"
29 #include "vk_util.h"
30 #include "vk_enum_defines.h"
31 
lvp_is_filter_minmax_format_supported(VkFormat format)32 static bool lvp_is_filter_minmax_format_supported(VkFormat format)
33 {
34    /* From the Vulkan spec 1.1.71:
35     *
36     * "The following formats must support the
37     *  VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with
38     *  VK_IMAGE_TILING_OPTIMAL, if they support
39     *  VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT."
40     */
41    /* TODO: enable more formats. */
42    switch (format) {
43    case VK_FORMAT_R8_UNORM:
44    case VK_FORMAT_R8_SNORM:
45    case VK_FORMAT_R16_UNORM:
46    case VK_FORMAT_R16_SNORM:
47    case VK_FORMAT_R16_SFLOAT:
48    case VK_FORMAT_R32_SFLOAT:
49    case VK_FORMAT_D16_UNORM:
50    case VK_FORMAT_X8_D24_UNORM_PACK32:
51    case VK_FORMAT_D32_SFLOAT:
52    case VK_FORMAT_D16_UNORM_S8_UINT:
53    case VK_FORMAT_D24_UNORM_S8_UINT:
54    case VK_FORMAT_D32_SFLOAT_S8_UINT:
55       return true;
56    default:
57       return false;
58    }
59 }
60 
61 
62 static void
lvp_physical_device_get_format_properties(struct lvp_physical_device * physical_device,VkFormat format,VkFormatProperties3 * out_properties)63 lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_device,
64                                           VkFormat format,
65                                           VkFormatProperties3 *out_properties)
66 {
67    const enum pipe_format pformat = lvp_vk_format_to_pipe_format(format);
68    struct pipe_screen *pscreen = physical_device->pscreen;
69    VkFormatFeatureFlags2 features = 0, buffer_features = 0;
70 
71    if (pformat == PIPE_FORMAT_NONE) {
72      out_properties->linearTilingFeatures = 0;
73      out_properties->optimalTilingFeatures = 0;
74      out_properties->bufferFeatures = 0;
75      return;
76    }
77 
78    if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
79                                     PIPE_BIND_DEPTH_STENCIL)) {
80       out_properties->linearTilingFeatures = 0;
81       out_properties->optimalTilingFeatures =
82          (VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT |
83           VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
84           VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
85           VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT |
86           VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT |
87           VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT |
88           VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT);
89 
90       if (lvp_is_filter_minmax_format_supported(format))
91          out_properties->optimalTilingFeatures |=
92             VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
93       out_properties->bufferFeatures = 0;
94       return;
95    }
96 
97    if (util_format_is_compressed(pformat)) {
98       if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
99                                        PIPE_BIND_SAMPLER_VIEW)) {
100          features |= (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
101                       VK_FORMAT_FEATURE_2_BLIT_SRC_BIT |
102                       VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
103                       VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT |
104                       VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
105                       VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT);
106       }
107       out_properties->linearTilingFeatures = features;
108       out_properties->optimalTilingFeatures = features;
109       out_properties->bufferFeatures = buffer_features;
110       return;
111    }
112 
113    if (!util_format_is_srgb(pformat) &&
114        pscreen->is_format_supported(pscreen, pformat, PIPE_BUFFER, 0, 0,
115                                     PIPE_BIND_VERTEX_BUFFER)) {
116       buffer_features |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
117    }
118 
119    if (pscreen->is_format_supported(pscreen, pformat, PIPE_BUFFER, 0, 0,
120                                     PIPE_BIND_CONSTANT_BUFFER)) {
121       buffer_features |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT;
122    }
123 
124    if (pscreen->is_format_supported(pscreen, pformat, PIPE_BUFFER, 0, 0,
125                                     PIPE_BIND_SHADER_IMAGE)) {
126       buffer_features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT |
127                          VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
128                          VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
129    }
130 
131    if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
132                                     PIPE_BIND_SAMPLER_VIEW)) {
133       features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT;
134       if (util_format_has_depth(util_format_description(pformat)))
135          features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
136       if (!util_format_is_pure_integer(pformat))
137          features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
138       if (lvp_is_filter_minmax_format_supported(format))
139          features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
140       const struct vk_format_ycbcr_info *ycbcr_info =
141          vk_format_get_ycbcr_info(format);
142       if (ycbcr_info) {
143          if (ycbcr_info->n_planes > 1)
144             features |= VK_FORMAT_FEATURE_DISJOINT_BIT;
145          else
146             features |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT;
147 
148          for (uint8_t plane = 0; plane < ycbcr_info->n_planes; plane++) {
149             const struct vk_format_ycbcr_plane *plane_info = &ycbcr_info->planes[plane];
150             if (plane_info->denominator_scales[0] > 1 ||
151                 plane_info->denominator_scales[1] > 1)
152                features |= VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT;
153          }
154 
155          /* The subsampled formats have no support for linear filters. */
156          const struct util_format_description *desc = util_format_description(pformat);
157          if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED)
158             features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT;
159       }
160    }
161 
162    if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
163                                     PIPE_BIND_RENDER_TARGET)) {
164       features |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT;
165       /* SNORM blending on llvmpipe fails CTS - disable for now */
166       if (!util_format_is_snorm(pformat) &&
167           !util_format_is_pure_integer(pformat))
168          features |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
169    }
170 
171    if (pscreen->is_format_supported(pscreen, pformat, PIPE_TEXTURE_2D, 0, 0,
172                                     PIPE_BIND_SHADER_IMAGE)) {
173       features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT |
174                   VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
175                   VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
176    }
177 
178    if (pformat == PIPE_FORMAT_R32_UINT ||
179        pformat == PIPE_FORMAT_R32_SINT ||
180        pformat == PIPE_FORMAT_R32_FLOAT) {
181       features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
182       buffer_features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
183    } else if (pformat == PIPE_FORMAT_R11G11B10_FLOAT ||
184               pformat == PIPE_FORMAT_R9G9B9E5_FLOAT) {
185       features |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
186    }
187 
188    if (features && buffer_features != VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT) {
189       features |= (VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
190                    VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT);
191    }
192    if (pformat == PIPE_FORMAT_B5G6R5_UNORM) {
193       features |= (VK_FORMAT_FEATURE_2_BLIT_SRC_BIT |
194                    VK_FORMAT_FEATURE_2_BLIT_DST_BIT);
195    }
196    if ((pformat != PIPE_FORMAT_R9G9B9E5_FLOAT) &&
197        util_format_get_nr_components(pformat) != 3 &&
198        !util_format_is_subsampled_422(pformat) &&
199        !util_format_is_yuv(pformat) &&
200        pformat != PIPE_FORMAT_R10G10B10A2_SNORM &&
201        pformat != PIPE_FORMAT_B10G10R10A2_SNORM &&
202        pformat != PIPE_FORMAT_B10G10R10A2_UNORM) {
203       features |= (VK_FORMAT_FEATURE_2_BLIT_SRC_BIT |
204                    VK_FORMAT_FEATURE_2_BLIT_DST_BIT);
205    }
206 
207    out_properties->linearTilingFeatures = features;
208    out_properties->optimalTilingFeatures = features;
209    out_properties->bufferFeatures = buffer_features;
210    if (out_properties->linearTilingFeatures)
211       out_properties->linearTilingFeatures |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT;
212    if (out_properties->optimalTilingFeatures)
213       out_properties->optimalTilingFeatures |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT;
214 }
215 
216 
lvp_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)217 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFormatProperties2(
218         VkPhysicalDevice                            physicalDevice,
219         VkFormat                                    format,
220         VkFormatProperties2*                        pFormatProperties)
221 {
222    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
223 
224    VkFormatProperties3 format_props;
225    lvp_physical_device_get_format_properties(physical_device,
226                                              format,
227                                              &format_props);
228    pFormatProperties->formatProperties.linearTilingFeatures = vk_format_features2_to_features(format_props.linearTilingFeatures);
229    pFormatProperties->formatProperties.optimalTilingFeatures = vk_format_features2_to_features(format_props.optimalTilingFeatures);
230    pFormatProperties->formatProperties.bufferFeatures = vk_format_features2_to_features(format_props.bufferFeatures);
231    VkFormatProperties3 *prop3 = (void*)vk_find_struct_const(pFormatProperties->pNext, FORMAT_PROPERTIES_3);
232    if (prop3) {
233       prop3->linearTilingFeatures = format_props.linearTilingFeatures;
234       prop3->optimalTilingFeatures = format_props.optimalTilingFeatures;
235       prop3->bufferFeatures = format_props.bufferFeatures;
236    }
237    VkSubpassResolvePerformanceQueryEXT *perf = (void*)vk_find_struct_const(pFormatProperties->pNext, SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT);
238    if (perf)
239       perf->optimal = VK_FALSE;
240 }
241 
lvp_get_image_format_properties(struct lvp_physical_device * physical_device,const VkPhysicalDeviceImageFormatInfo2 * info,VkImageFormatProperties * pImageFormatProperties)242 static VkResult lvp_get_image_format_properties(struct lvp_physical_device *physical_device,
243                                                  const VkPhysicalDeviceImageFormatInfo2 *info,
244                                                  VkImageFormatProperties *pImageFormatProperties)
245 {
246    VkFormatProperties3 format_props;
247    VkFormatFeatureFlags2 format_feature_flags;
248    VkExtent3D maxExtent;
249    uint32_t maxMipLevels;
250    uint32_t maxArraySize;
251    VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
252    enum pipe_format pformat = lvp_vk_format_to_pipe_format(info->format);
253    lvp_physical_device_get_format_properties(physical_device, info->format,
254                                              &format_props);
255    if (info->tiling == VK_IMAGE_TILING_LINEAR) {
256       format_feature_flags = format_props.linearTilingFeatures;
257    } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
258       format_feature_flags = format_props.optimalTilingFeatures;
259    } else {
260       unreachable("bad VkImageTiling");
261    }
262 
263    if (format_feature_flags == 0)
264       goto unsupported;
265 
266    uint32_t max_2d_ext = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE);
267    uint32_t max_layers = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
268    switch (info->type) {
269    default:
270       unreachable("bad vkimage type\n");
271    case VK_IMAGE_TYPE_1D:
272       if (util_format_is_compressed(pformat))
273          goto unsupported;
274 
275       maxExtent.width = max_2d_ext;
276       maxExtent.height = 1;
277       maxExtent.depth = 1;
278       maxMipLevels = util_logbase2(max_2d_ext) + 1;
279       maxArraySize = max_layers;
280       break;
281    case VK_IMAGE_TYPE_2D:
282       maxExtent.width = max_2d_ext;
283       maxExtent.height = max_2d_ext;
284       maxExtent.depth = 1;
285       maxMipLevels = util_logbase2(max_2d_ext) + 1;
286       maxArraySize = max_layers;
287       if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
288           !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
289           !util_format_is_compressed(pformat) &&
290           (format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)))
291          sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
292       break;
293    case VK_IMAGE_TYPE_3D:
294       maxExtent.width = max_2d_ext;
295       maxExtent.height = max_2d_ext;
296       maxExtent.depth = (1 << physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS));
297       maxMipLevels = util_logbase2(max_2d_ext) + 1;
298       maxArraySize = 1;
299       break;
300    }
301 
302    if (info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT)
303       goto skip_checks;
304 
305    if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
306       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
307          goto unsupported;
308       }
309    }
310 
311    if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
312       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) {
313          goto unsupported;
314       }
315    }
316 
317    if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
318       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) {
319          goto unsupported;
320       }
321    }
322 
323    if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
324       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
325          goto unsupported;
326       }
327    }
328 
329    if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
330       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) {
331          goto unsupported;
332       }
333    }
334 
335    if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
336       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) {
337          goto unsupported;
338       }
339    }
340 
341    if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
342       if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
343                                     VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT))) {
344          goto unsupported;
345       }
346    }
347 
348 skip_checks:
349    *pImageFormatProperties = (VkImageFormatProperties) {
350       .maxExtent = maxExtent,
351       .maxMipLevels = maxMipLevels,
352       .maxArrayLayers = maxArraySize,
353       .sampleCounts = sampleCounts,
354 
355       /* FINISHME: Accurately calculate
356        * VkImageFormatProperties::maxResourceSize.
357        */
358       .maxResourceSize = UINT32_MAX,
359    };
360    return VK_SUCCESS;
361  unsupported:
362    *pImageFormatProperties = (VkImageFormatProperties) {
363       .maxExtent = { 0, 0, 0 },
364       .maxMipLevels = 0,
365       .maxArrayLayers = 0,
366       .sampleCounts = 0,
367       .maxResourceSize = 0,
368    };
369 
370    return VK_ERROR_FORMAT_NOT_SUPPORTED;
371 }
372 
lvp_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * base_info,VkImageFormatProperties2 * base_props)373 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceImageFormatProperties2(
374         VkPhysicalDevice                            physicalDevice,
375         const VkPhysicalDeviceImageFormatInfo2     *base_info,
376         VkImageFormatProperties2                   *base_props)
377 {
378    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
379    const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
380    VkExternalImageFormatProperties *external_props = NULL;
381    VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
382    VkHostImageCopyDevicePerformanceQueryEXT *hic;
383    VkResult result;
384    result = lvp_get_image_format_properties(physical_device, base_info,
385                                              &base_props->imageFormatProperties);
386    if (result != VK_SUCCESS)
387       return result;
388 
389    vk_foreach_struct_const(s, base_info->pNext) {
390       switch (s->sType) {
391       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
392          external_info = (const void *) s;
393          break;
394       default:
395          break;
396       }
397    }
398 
399    /* Extract output structs */
400    vk_foreach_struct(s, base_props->pNext) {
401       switch (s->sType) {
402       case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
403          external_props = (void *) s;
404          break;
405       case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
406          ycbcr_props = (void *) s;
407          break;
408       case VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT:
409          hic = (void*)s;
410          hic->optimalDeviceAccess = VK_TRUE;
411          hic->identicalMemoryLayout = VK_TRUE;
412          break;
413       default:
414          break;
415       }
416    }
417 
418    if (external_info && external_info->handleType != 0) {
419       VkExternalMemoryFeatureFlagBits flags = 0;
420       VkExternalMemoryHandleTypeFlags export_flags = 0;
421       VkExternalMemoryHandleTypeFlags compat_flags = 0;
422 
423       switch (external_info->handleType) {
424 #ifdef PIPE_MEMORY_FD
425       case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
426          flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
427          export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
428          compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
429          break;
430 #endif
431       case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
432          flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
433          compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
434          break;
435       default:
436          break;
437       }
438       external_props->externalMemoryProperties = (VkExternalMemoryProperties) {
439          .externalMemoryFeatures = flags,
440          .exportFromImportedHandleTypes = export_flags,
441          .compatibleHandleTypes = compat_flags,
442       };
443    }
444    if (ycbcr_props)
445       ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(base_info->format);
446    return VK_SUCCESS;
447 }
448 
lvp_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pNumProperties,VkSparseImageFormatProperties * pProperties)449 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties(
450     VkPhysicalDevice                            physicalDevice,
451     VkFormat                                    format,
452     VkImageType                                 type,
453     VkSampleCountFlagBits                       samples,
454     VkImageUsageFlags                           usage,
455     VkImageTiling                               tiling,
456     uint32_t*                                   pNumProperties,
457     VkSparseImageFormatProperties*              pProperties)
458 {
459    /* Sparse images are not yet supported. */
460    *pNumProperties = 0;
461 }
462 
lvp_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)463 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties2(
464         VkPhysicalDevice                            physicalDevice,
465         const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
466         uint32_t                                   *pPropertyCount,
467         VkSparseImageFormatProperties2             *pProperties)
468 {
469         /* Sparse images are not yet supported. */
470         *pPropertyCount = 0;
471 }
472 
lvp_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)473 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalBufferProperties(
474    VkPhysicalDevice                            physicalDevice,
475    const VkPhysicalDeviceExternalBufferInfo    *pExternalBufferInfo,
476    VkExternalBufferProperties                  *pExternalBufferProperties)
477 {
478    VkExternalMemoryFeatureFlagBits flags = 0;
479    VkExternalMemoryHandleTypeFlags export_flags = 0;
480    VkExternalMemoryHandleTypeFlags compat_flags = 0;
481    switch (pExternalBufferInfo->handleType) {
482 #ifdef PIPE_MEMORY_FD
483    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
484       flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
485       export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
486       compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
487       break;
488 #endif
489    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
490       flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
491       compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
492       break;
493    default:
494       break;
495    }
496 
497    pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties) {
498       .externalMemoryFeatures = flags,
499       .exportFromImportedHandleTypes = export_flags,
500       .compatibleHandleTypes = compat_flags,
501    };
502 }
503