• 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 "pipe/p_config.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 static void
lvp_physical_device_get_format_properties(struct lvp_physical_device * physical_device,VkFormat format,VkFormatProperties3 * out_properties)62 lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_device,
63                                           VkFormat format,
64                                           VkFormatProperties3 *out_properties)
65 {
66    enum pipe_format pformat = lvp_vk_format_to_pipe_format(format);
67    VkFormatFeatureFlags2 features = 0, buffer_features = 0;
68    if (pformat == PIPE_FORMAT_NONE) {
69      out_properties->linearTilingFeatures = 0;
70      out_properties->optimalTilingFeatures = 0;
71      out_properties->bufferFeatures = 0;
72      return;
73    }
74 
75    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
76                                                      PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_DEPTH_STENCIL)) {
77       out_properties->linearTilingFeatures = 0;
78       out_properties->optimalTilingFeatures = VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
79          VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT |
80          VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT |
81          VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
82 
83       if (lvp_is_filter_minmax_format_supported(format))
84          out_properties->optimalTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
85       out_properties->bufferFeatures = 0;
86       return;
87    }
88 
89    if (util_format_is_compressed(pformat)) {
90       if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
91                                                         PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
92          features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT;
93          features |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
94          features |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
95          features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
96       }
97       out_properties->linearTilingFeatures = features;
98       out_properties->optimalTilingFeatures = features;
99       out_properties->bufferFeatures = buffer_features;
100       return;
101    }
102 
103    if (!util_format_is_srgb(pformat) &&
104        physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
105                                                      PIPE_BUFFER, 0, 0, PIPE_BIND_VERTEX_BUFFER)) {
106       buffer_features |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
107    }
108 
109    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
110                                                      PIPE_BUFFER, 0, 0, PIPE_BIND_CONSTANT_BUFFER)) {
111       buffer_features |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT;
112    }
113 
114    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
115                                                      PIPE_BUFFER, 0, 0, PIPE_BIND_SHADER_IMAGE)) {
116       buffer_features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
117       if (physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_IMAGE_LOAD_FORMATTED))
118          buffer_features |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT;
119       if (physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_IMAGE_STORE_FORMATTED))
120          buffer_features |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
121    }
122 
123    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
124                                                      PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
125       features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT;
126       if (util_format_has_depth(util_format_description(pformat)))
127          features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
128       if (!util_format_is_pure_integer(pformat))
129          features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
130       if (lvp_is_filter_minmax_format_supported(format))
131          features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
132    }
133 
134    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
135                                                      PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_RENDER_TARGET)) {
136       features |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT;
137       /* SNORM blending on llvmpipe fails CTS - disable for now */
138       if (!util_format_is_snorm(pformat))
139          features |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
140    }
141 
142    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
143                                                      PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SHADER_IMAGE)) {
144       features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
145       if (physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_IMAGE_LOAD_FORMATTED))
146          features |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT;
147       if (physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_IMAGE_STORE_FORMATTED))
148          features |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
149    }
150 
151    if (pformat == PIPE_FORMAT_R32_UINT || pformat == PIPE_FORMAT_R32_SINT) {
152       features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
153       buffer_features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
154    }
155 
156    if (pformat == PIPE_FORMAT_R11G11B10_FLOAT || pformat == PIPE_FORMAT_R9G9B9E5_FLOAT)
157      features |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
158 
159    if (features && buffer_features != VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT)
160       features |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
161    if (pformat == PIPE_FORMAT_B5G6R5_UNORM)
162      features |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
163    if ((pformat != PIPE_FORMAT_R9G9B9E5_FLOAT) && util_format_get_nr_components(pformat) != 3 &&
164        pformat != PIPE_FORMAT_R10G10B10A2_SNORM && pformat != PIPE_FORMAT_B10G10R10A2_SNORM &&
165        pformat != PIPE_FORMAT_B10G10R10A2_UNORM) {
166       features |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
167    }
168 
169    out_properties->linearTilingFeatures = features;
170    out_properties->optimalTilingFeatures = features;
171    out_properties->bufferFeatures = buffer_features;
172    return;
173 }
174 
lvp_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)175 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFormatProperties2(
176         VkPhysicalDevice                            physicalDevice,
177         VkFormat                                    format,
178         VkFormatProperties2*                        pFormatProperties)
179 {
180    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
181 
182    VkFormatProperties3 format_props;
183    lvp_physical_device_get_format_properties(physical_device,
184                                              format,
185                                              &format_props);
186    pFormatProperties->formatProperties.linearTilingFeatures = format_props.linearTilingFeatures & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
187    pFormatProperties->formatProperties.optimalTilingFeatures = format_props.optimalTilingFeatures & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
188    pFormatProperties->formatProperties.bufferFeatures = format_props.bufferFeatures & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
189    VkFormatProperties3 *prop3 = (void*)vk_find_struct_const(pFormatProperties->pNext, FORMAT_PROPERTIES_3);
190    if (prop3) {
191       prop3->linearTilingFeatures = format_props.linearTilingFeatures;
192       prop3->optimalTilingFeatures = format_props.optimalTilingFeatures;
193       prop3->bufferFeatures = format_props.bufferFeatures;
194    }
195    VkSubpassResolvePerformanceQueryEXT *perf = (void*)vk_find_struct_const(pFormatProperties->pNext, SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT);
196    if (perf)
197       perf->optimal = VK_FALSE;
198 }
lvp_get_image_format_properties(struct lvp_physical_device * physical_device,const VkPhysicalDeviceImageFormatInfo2 * info,VkImageFormatProperties * pImageFormatProperties)199 static VkResult lvp_get_image_format_properties(struct lvp_physical_device *physical_device,
200                                                  const VkPhysicalDeviceImageFormatInfo2 *info,
201                                                  VkImageFormatProperties *pImageFormatProperties)
202 {
203    VkFormatProperties3 format_props;
204    VkFormatFeatureFlags2 format_feature_flags;
205    VkExtent3D maxExtent;
206    uint32_t maxMipLevels;
207    uint32_t maxArraySize;
208    VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
209    enum pipe_format pformat = lvp_vk_format_to_pipe_format(info->format);
210    lvp_physical_device_get_format_properties(physical_device, info->format,
211                                              &format_props);
212    if (info->tiling == VK_IMAGE_TILING_LINEAR) {
213       format_feature_flags = format_props.linearTilingFeatures;
214    } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
215       format_feature_flags = format_props.optimalTilingFeatures;
216    } else {
217       unreachable("bad VkImageTiling");
218    }
219 
220    if (format_feature_flags == 0)
221       goto unsupported;
222 
223    uint32_t max_2d_ext = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE);
224    uint32_t max_layers = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
225    switch (info->type) {
226    default:
227       unreachable("bad vkimage type\n");
228    case VK_IMAGE_TYPE_1D:
229       if (util_format_is_compressed(pformat))
230          goto unsupported;
231 
232       maxExtent.width = max_2d_ext;
233       maxExtent.height = 1;
234       maxExtent.depth = 1;
235       maxMipLevels = util_logbase2(max_2d_ext) + 1;
236       maxArraySize = max_layers;
237       break;
238    case VK_IMAGE_TYPE_2D:
239       maxExtent.width = max_2d_ext;
240       maxExtent.height = max_2d_ext;
241       maxExtent.depth = 1;
242       maxMipLevels = util_logbase2(max_2d_ext) + 1;
243       maxArraySize = max_layers;
244       if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
245           !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
246           !util_format_is_compressed(pformat) &&
247           (format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)))
248          sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
249       break;
250    case VK_IMAGE_TYPE_3D:
251       maxExtent.width = max_2d_ext;
252       maxExtent.height = max_2d_ext;
253       maxExtent.depth = (1 << physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS));
254       maxMipLevels = util_logbase2(max_2d_ext) + 1;
255       maxArraySize = 1;
256       break;
257    }
258 
259    if (info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT)
260       goto skip_checks;
261 
262    if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
263       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
264          goto unsupported;
265       }
266    }
267 
268    if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
269       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) {
270          goto unsupported;
271       }
272    }
273 
274    if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
275       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) {
276          goto unsupported;
277       }
278    }
279 
280    if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
281       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
282          goto unsupported;
283       }
284    }
285 
286    if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
287       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) {
288          goto unsupported;
289       }
290    }
291 
292    if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
293       if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) {
294          goto unsupported;
295       }
296    }
297 
298    if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
299       if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
300                                     VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT))) {
301          goto unsupported;
302       }
303    }
304 
305 skip_checks:
306    *pImageFormatProperties = (VkImageFormatProperties) {
307       .maxExtent = maxExtent,
308       .maxMipLevels = maxMipLevels,
309       .maxArrayLayers = maxArraySize,
310       .sampleCounts = sampleCounts,
311 
312       /* FINISHME: Accurately calculate
313        * VkImageFormatProperties::maxResourceSize.
314        */
315       .maxResourceSize = UINT32_MAX,
316    };
317    return VK_SUCCESS;
318  unsupported:
319    *pImageFormatProperties = (VkImageFormatProperties) {
320       .maxExtent = { 0, 0, 0 },
321       .maxMipLevels = 0,
322       .maxArrayLayers = 0,
323       .sampleCounts = 0,
324       .maxResourceSize = 0,
325    };
326 
327    return VK_ERROR_FORMAT_NOT_SUPPORTED;
328 }
329 
lvp_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * base_info,VkImageFormatProperties2 * base_props)330 VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceImageFormatProperties2(
331         VkPhysicalDevice                            physicalDevice,
332         const VkPhysicalDeviceImageFormatInfo2     *base_info,
333         VkImageFormatProperties2                   *base_props)
334 {
335    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
336    const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
337    VkExternalImageFormatProperties *external_props = NULL;
338    VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
339    VkResult result;
340    result = lvp_get_image_format_properties(physical_device, base_info,
341                                              &base_props->imageFormatProperties);
342    if (result != VK_SUCCESS)
343       return result;
344 
345    vk_foreach_struct_const(s, base_info->pNext) {
346       switch (s->sType) {
347       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
348          external_info = (const void *) s;
349          break;
350       default:
351          break;
352       }
353    }
354 
355    /* Extract output structs */
356    vk_foreach_struct(s, base_props->pNext) {
357       switch (s->sType) {
358       case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
359          external_props = (void *) s;
360          break;
361       case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
362          ycbcr_props = (void *) s;
363          break;
364       default:
365          break;
366       }
367    }
368 
369    if (external_info && external_info->handleType != 0) {
370       VkExternalMemoryFeatureFlagBits flags = 0;
371       VkExternalMemoryHandleTypeFlags export_flags = 0;
372       VkExternalMemoryHandleTypeFlags compat_flags = 0;
373 
374       switch (external_info->handleType) {
375 #ifdef PIPE_MEMORY_FD
376       case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
377          flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
378          export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
379          compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
380          break;
381 #endif
382       case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
383          flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
384          compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
385          break;
386       default:
387          break;
388       }
389       external_props->externalMemoryProperties = (VkExternalMemoryProperties) {
390          .externalMemoryFeatures = flags,
391          .exportFromImportedHandleTypes = export_flags,
392          .compatibleHandleTypes = compat_flags,
393       };
394    }
395    if (ycbcr_props)
396       ycbcr_props->combinedImageSamplerDescriptorCount = 0;
397    return VK_SUCCESS;
398 }
399 
lvp_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,uint32_t samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pNumProperties,VkSparseImageFormatProperties * pProperties)400 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties(
401     VkPhysicalDevice                            physicalDevice,
402     VkFormat                                    format,
403     VkImageType                                 type,
404     uint32_t                                    samples,
405     VkImageUsageFlags                           usage,
406     VkImageTiling                               tiling,
407     uint32_t*                                   pNumProperties,
408     VkSparseImageFormatProperties*              pProperties)
409 {
410    /* Sparse images are not yet supported. */
411    *pNumProperties = 0;
412 }
413 
lvp_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)414 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties2(
415         VkPhysicalDevice                            physicalDevice,
416         const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
417         uint32_t                                   *pPropertyCount,
418         VkSparseImageFormatProperties2             *pProperties)
419 {
420         /* Sparse images are not yet supported. */
421         *pPropertyCount = 0;
422 }
423 
lvp_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)424 VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalBufferProperties(
425    VkPhysicalDevice                            physicalDevice,
426    const VkPhysicalDeviceExternalBufferInfo    *pExternalBufferInfo,
427    VkExternalBufferProperties                  *pExternalBufferProperties)
428 {
429    VkExternalMemoryFeatureFlagBits flags = 0;
430    VkExternalMemoryHandleTypeFlags export_flags = 0;
431    VkExternalMemoryHandleTypeFlags compat_flags = 0;
432    switch (pExternalBufferInfo->handleType) {
433 #ifdef PIPE_MEMORY_FD
434    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
435       flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
436       export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
437       compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
438       break;
439 #endif
440    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
441       flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
442       compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
443       break;
444    default:
445       break;
446    }
447 
448    pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties) {
449       .externalMemoryFeatures = flags,
450       .exportFromImportedHandleTypes = export_flags,
451       .compatibleHandleTypes = compat_flags,
452    };
453 }
454