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