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