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/format/u_format.h"
26 #include "util/u_math.h"
27 #define COMMON_NAME(x) [VK_FORMAT_##x] = PIPE_FORMAT_##x
28 
29 #define FLOAT_NAME(x) [VK_FORMAT_##x##_SFLOAT] = PIPE_FORMAT_##x##_FLOAT
30 
31 static enum pipe_format format_to_vk_table[VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1] = {
32 
33    COMMON_NAME(R8_UNORM),
34    COMMON_NAME(R8G8_UNORM),
35    COMMON_NAME(R8G8B8_UNORM),
36    COMMON_NAME(R8G8B8A8_UNORM),
37 
38    COMMON_NAME(R8_SNORM),
39    COMMON_NAME(R8G8_SNORM),
40    COMMON_NAME(R8G8B8_SNORM),
41    COMMON_NAME(R8G8B8A8_SNORM),
42 
43    //   COMMON_NAME(R8_SRGB),
44    COMMON_NAME(R8G8B8_SRGB),
45    COMMON_NAME(R8G8B8A8_SRGB),
46 
47    COMMON_NAME(B8G8R8A8_UNORM),
48    COMMON_NAME(R8G8B8A8_SRGB),
49    COMMON_NAME(B8G8R8A8_SRGB),
50 
51    COMMON_NAME(R8_UINT),
52    COMMON_NAME(R8G8_UINT),
53    COMMON_NAME(R8G8B8_UINT),
54    COMMON_NAME(R8G8B8A8_UINT),
55 
56    COMMON_NAME(R16_UINT),
57    COMMON_NAME(R16G16_UINT),
58    COMMON_NAME(R16G16B16_UINT),
59    COMMON_NAME(R16G16B16A16_UINT),
60 
61    COMMON_NAME(R32_UINT),
62    COMMON_NAME(R32G32_UINT),
63    COMMON_NAME(R32G32B32_UINT),
64    COMMON_NAME(R32G32B32A32_UINT),
65 
66    COMMON_NAME(R8_SINT),
67    COMMON_NAME(R8G8_SINT),
68    COMMON_NAME(R8G8B8_SINT),
69    COMMON_NAME(R8G8B8A8_SINT),
70 
71    COMMON_NAME(R16_SINT),
72    COMMON_NAME(R16G16_SINT),
73    COMMON_NAME(R16G16B16_SINT),
74    COMMON_NAME(R16G16B16A16_SINT),
75 
76    COMMON_NAME(R32_SINT),
77    COMMON_NAME(R32G32_SINT),
78    COMMON_NAME(R32G32B32_SINT),
79    COMMON_NAME(R32G32B32A32_SINT),
80 
81    COMMON_NAME(R16_UNORM),
82    COMMON_NAME(R16G16_UNORM),
83    COMMON_NAME(R16G16B16A16_UNORM),
84 
85    COMMON_NAME(R16_SNORM),
86    COMMON_NAME(R16G16_SNORM),
87    COMMON_NAME(R16G16B16A16_SNORM),
88    FLOAT_NAME(R16),
89    FLOAT_NAME(R16G16),
90    FLOAT_NAME(R16G16B16),
91    FLOAT_NAME(R16G16B16A16),
92 
93    FLOAT_NAME(R32),
94    FLOAT_NAME(R32G32),
95    FLOAT_NAME(R32G32B32),
96    FLOAT_NAME(R32G32B32A32),
97 
98    COMMON_NAME(S8_UINT),
99    [VK_FORMAT_UNDEFINED] = PIPE_FORMAT_NONE,
100    [VK_FORMAT_R5G6B5_UNORM_PACK16] = PIPE_FORMAT_B5G6R5_UNORM,
101    [VK_FORMAT_A1R5G5B5_UNORM_PACK16] = PIPE_FORMAT_B5G5R5A1_UNORM,
102    [VK_FORMAT_B4G4R4A4_UNORM_PACK16] = PIPE_FORMAT_A4R4G4B4_UNORM,
103    [VK_FORMAT_D16_UNORM] = PIPE_FORMAT_Z16_UNORM,
104 
105    [VK_FORMAT_A8B8G8R8_UNORM_PACK32] = PIPE_FORMAT_R8G8B8A8_UNORM,
106    [VK_FORMAT_A8B8G8R8_SNORM_PACK32] = PIPE_FORMAT_R8G8B8A8_SNORM,
107    [VK_FORMAT_A8B8G8R8_UINT_PACK32] = PIPE_FORMAT_R8G8B8A8_UINT,
108    [VK_FORMAT_A8B8G8R8_SINT_PACK32] = PIPE_FORMAT_R8G8B8A8_SINT,
109    [VK_FORMAT_A8B8G8R8_SRGB_PACK32] = PIPE_FORMAT_R8G8B8A8_SRGB,
110 
111    [VK_FORMAT_A2B10G10R10_UNORM_PACK32] = PIPE_FORMAT_R10G10B10A2_UNORM,
112    [VK_FORMAT_A2B10G10R10_UINT_PACK32] = PIPE_FORMAT_R10G10B10A2_UINT,
113 
114    [VK_FORMAT_B10G11R11_UFLOAT_PACK32] = PIPE_FORMAT_R11G11B10_FLOAT,
115    [VK_FORMAT_E5B9G9R9_UFLOAT_PACK32] = PIPE_FORMAT_R9G9B9E5_FLOAT,
116 
117    [VK_FORMAT_X8_D24_UNORM_PACK32] = PIPE_FORMAT_Z24X8_UNORM,
118    [VK_FORMAT_D32_SFLOAT] = PIPE_FORMAT_Z32_FLOAT,
119    [VK_FORMAT_D24_UNORM_S8_UINT] = PIPE_FORMAT_Z24_UNORM_S8_UINT,
120    [VK_FORMAT_D32_SFLOAT_S8_UINT] = PIPE_FORMAT_Z32_FLOAT_S8X24_UINT,
121 
122    [VK_FORMAT_BC1_RGB_UNORM_BLOCK] = PIPE_FORMAT_DXT1_RGB,
123    [VK_FORMAT_BC1_RGBA_UNORM_BLOCK] = PIPE_FORMAT_DXT1_RGBA,
124    [VK_FORMAT_BC2_UNORM_BLOCK] = PIPE_FORMAT_DXT3_RGBA,
125    [VK_FORMAT_BC3_UNORM_BLOCK] = PIPE_FORMAT_DXT5_RGBA,
126    [VK_FORMAT_BC4_UNORM_BLOCK] = PIPE_FORMAT_RGTC1_UNORM,
127    [VK_FORMAT_BC5_UNORM_BLOCK] = PIPE_FORMAT_RGTC2_UNORM,
128 
129    [VK_FORMAT_BC1_RGB_SRGB_BLOCK] = PIPE_FORMAT_DXT1_SRGB,
130    [VK_FORMAT_BC1_RGBA_SRGB_BLOCK] = PIPE_FORMAT_DXT1_SRGBA,
131    [VK_FORMAT_BC2_SRGB_BLOCK] = PIPE_FORMAT_DXT3_SRGBA,
132    [VK_FORMAT_BC3_SRGB_BLOCK] = PIPE_FORMAT_DXT5_SRGBA,
133 
134    [VK_FORMAT_BC4_SNORM_BLOCK] = PIPE_FORMAT_RGTC1_SNORM,
135    [VK_FORMAT_BC5_SNORM_BLOCK] = PIPE_FORMAT_RGTC2_SNORM,
136 
137    [VK_FORMAT_BC6H_UFLOAT_BLOCK] = PIPE_FORMAT_BPTC_RGB_UFLOAT,
138    [VK_FORMAT_BC6H_SFLOAT_BLOCK] = PIPE_FORMAT_BPTC_RGB_FLOAT,
139    [VK_FORMAT_BC7_UNORM_BLOCK] = PIPE_FORMAT_BPTC_RGBA_UNORM,
140    [VK_FORMAT_BC7_SRGB_BLOCK] = PIPE_FORMAT_BPTC_SRGBA,
141 };
142 
vk_format_to_pipe(VkFormat format)143 enum pipe_format vk_format_to_pipe(VkFormat format)
144 {
145    if (format > VK_FORMAT_ASTC_12x12_SRGB_BLOCK)
146       return PIPE_FORMAT_NONE;
147    return format_to_vk_table[format];
148 }
149 
150 static void
lvp_physical_device_get_format_properties(struct lvp_physical_device * physical_device,VkFormat format,VkFormatProperties * out_properties)151 lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_device,
152                                           VkFormat format,
153                                           VkFormatProperties *out_properties)
154 {
155    enum pipe_format pformat = vk_format_to_pipe(format);
156    unsigned features = 0, buffer_features = 0;
157    if (pformat == PIPE_FORMAT_NONE) {
158      out_properties->linearTilingFeatures = 0;
159      out_properties->optimalTilingFeatures = 0;
160      out_properties->bufferFeatures = 0;
161      return;
162    }
163 
164    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
165                                                      PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_DEPTH_STENCIL)) {
166       out_properties->linearTilingFeatures = 0;
167       out_properties->optimalTilingFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
168          VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
169          VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
170 
171       out_properties->bufferFeatures = 0;
172       return;
173    }
174 
175    if (util_format_is_compressed(pformat)) {
176       if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
177                                                         PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
178          features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
179          features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
180          features |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
181          features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
182       }
183       out_properties->linearTilingFeatures = features;
184       out_properties->optimalTilingFeatures = features;
185       out_properties->bufferFeatures = buffer_features;
186       return;
187    }
188    buffer_features = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
189    if (!util_format_is_srgb(pformat) &&
190        physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
191                                                      PIPE_BUFFER, 0, 0, PIPE_BIND_VERTEX_BUFFER)) {
192       buffer_features |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
193    }
194 
195    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
196                                                      PIPE_BUFFER, 0, 0, PIPE_BIND_CONSTANT_BUFFER)) {
197       buffer_features |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
198    }
199 
200 
201    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
202                                                      PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
203       features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
204       if (!util_format_is_pure_integer(pformat))
205          features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
206    }
207 
208    if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
209                                                      PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_RENDER_TARGET)) {
210       features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
211       /* SNORM blending on llvmpipe fails CTS - disable for now */
212       if (!util_format_is_snorm(pformat))
213          features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
214       features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
215    }
216 
217    if (pformat == PIPE_FORMAT_R32_UINT || pformat == PIPE_FORMAT_R32_SINT) {
218       features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
219       buffer_features |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
220    }
221 
222    if (pformat == PIPE_FORMAT_R11G11B10_FLOAT || pformat == PIPE_FORMAT_R9G9B9E5_FLOAT)
223      features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
224 
225    features |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
226    if (pformat == PIPE_FORMAT_B5G6R5_UNORM)
227      features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
228    if ((pformat != PIPE_FORMAT_R9G9B9E5_FLOAT) && util_format_get_nr_components(pformat) != 3) {
229       features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
230    }
231    out_properties->linearTilingFeatures = features;
232    out_properties->optimalTilingFeatures = features;
233    out_properties->bufferFeatures = buffer_features;
234    return;
235 }
236 
lvp_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)237 void lvp_GetPhysicalDeviceFormatProperties(
238     VkPhysicalDevice                            physicalDevice,
239     VkFormat                                    format,
240     VkFormatProperties*                         pFormatProperties)
241 {
242    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
243 
244    lvp_physical_device_get_format_properties(physical_device,
245                                              format,
246                                              pFormatProperties);
247 }
248 
lvp_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)249 void lvp_GetPhysicalDeviceFormatProperties2(
250         VkPhysicalDevice                            physicalDevice,
251         VkFormat                                    format,
252         VkFormatProperties2*                        pFormatProperties)
253 {
254    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
255 
256    lvp_physical_device_get_format_properties(physical_device,
257                                              format,
258                                              &pFormatProperties->formatProperties);
259 }
lvp_get_image_format_properties(struct lvp_physical_device * physical_device,const VkPhysicalDeviceImageFormatInfo2 * info,VkImageFormatProperties * pImageFormatProperties)260 static VkResult lvp_get_image_format_properties(struct lvp_physical_device *physical_device,
261                                                  const VkPhysicalDeviceImageFormatInfo2 *info,
262                                                  VkImageFormatProperties *pImageFormatProperties)
263 {
264    VkFormatProperties format_props;
265    VkFormatFeatureFlags format_feature_flags;
266    VkExtent3D maxExtent;
267    uint32_t maxMipLevels;
268    uint32_t maxArraySize;
269    VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
270    enum pipe_format pformat = vk_format_to_pipe(info->format);
271    lvp_physical_device_get_format_properties(physical_device, info->format,
272                                              &format_props);
273    if (info->tiling == VK_IMAGE_TILING_LINEAR) {
274       format_feature_flags = format_props.linearTilingFeatures;
275    } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
276       format_feature_flags = format_props.optimalTilingFeatures;
277    } else {
278       unreachable("bad VkImageTiling");
279    }
280 
281    if (format_feature_flags == 0)
282       goto unsupported;
283 
284    uint32_t max_2d_ext = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE);
285    uint32_t max_layers = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
286    switch (info->type) {
287    default:
288       unreachable("bad vkimage type\n");
289    case VK_IMAGE_TYPE_1D:
290       if (util_format_is_compressed(pformat))
291          goto unsupported;
292 
293       maxExtent.width = max_2d_ext;
294       maxExtent.height = 1;
295       maxExtent.depth = 1;
296       maxMipLevels = util_logbase2(max_2d_ext);
297       maxArraySize = max_layers;
298       break;
299    case VK_IMAGE_TYPE_2D:
300       maxExtent.width = max_2d_ext;
301       maxExtent.height = max_2d_ext;
302       maxExtent.depth = 1;
303       maxMipLevels = util_logbase2(max_2d_ext);
304       maxArraySize = max_layers;
305       sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
306       break;
307    case VK_IMAGE_TYPE_3D:
308       maxExtent.width = max_2d_ext;
309       maxExtent.height = max_2d_ext;
310       maxExtent.depth = (1 << physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS));
311       maxMipLevels = util_logbase2(max_2d_ext);
312       maxArraySize = 1;
313       break;
314    }
315 
316    if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
317       if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
318          goto unsupported;
319       }
320    }
321 
322    if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
323       if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
324          goto unsupported;
325       }
326    }
327 
328    if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
329       if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
330          goto unsupported;
331       }
332    }
333 
334    if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
335       if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
336          goto unsupported;
337       }
338    }
339 
340    if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
341       if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
342          goto unsupported;
343       }
344    }
345 
346    if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
347       if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) {
348          goto unsupported;
349       }
350    }
351 
352    if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
353       if (!(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
354                                     VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) {
355          goto unsupported;
356       }
357    }
358 
359    *pImageFormatProperties = (VkImageFormatProperties) {
360       .maxExtent = maxExtent,
361       .maxMipLevels = maxMipLevels,
362       .maxArrayLayers = maxArraySize,
363       .sampleCounts = sampleCounts,
364 
365       /* FINISHME: Accurately calculate
366        * VkImageFormatProperties::maxResourceSize.
367        */
368       .maxResourceSize = UINT32_MAX,
369    };
370    return VK_SUCCESS;
371  unsupported:
372    *pImageFormatProperties = (VkImageFormatProperties) {
373       .maxExtent = { 0, 0, 0 },
374       .maxMipLevels = 0,
375       .maxArrayLayers = 0,
376       .sampleCounts = 0,
377       .maxResourceSize = 0,
378    };
379 
380    return VK_ERROR_FORMAT_NOT_SUPPORTED;
381 }
382 
lvp_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags createFlags,VkImageFormatProperties * pImageFormatProperties)383 VkResult lvp_GetPhysicalDeviceImageFormatProperties(
384     VkPhysicalDevice                            physicalDevice,
385     VkFormat                                    format,
386     VkImageType                                 type,
387     VkImageTiling                               tiling,
388     VkImageUsageFlags                           usage,
389     VkImageCreateFlags                          createFlags,
390     VkImageFormatProperties*                    pImageFormatProperties)
391 {
392    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
393 
394    const VkPhysicalDeviceImageFormatInfo2 info = {
395       .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
396       .pNext = NULL,
397       .format = format,
398       .type = type,
399       .tiling = tiling,
400       .usage = usage,
401       .flags = createFlags,
402    };
403 
404    return lvp_get_image_format_properties(physical_device, &info,
405                                            pImageFormatProperties);
406 }
407 
lvp_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * base_info,VkImageFormatProperties2 * base_props)408 VkResult lvp_GetPhysicalDeviceImageFormatProperties2(
409         VkPhysicalDevice                            physicalDevice,
410         const VkPhysicalDeviceImageFormatInfo2     *base_info,
411         VkImageFormatProperties2                   *base_props)
412 {
413    LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
414    VkResult result;
415    result = lvp_get_image_format_properties(physical_device, base_info,
416                                              &base_props->imageFormatProperties);
417    if (result != VK_SUCCESS)
418       return result;
419 
420    return VK_SUCCESS;
421 }
422 
lvp_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,uint32_t samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pNumProperties,VkSparseImageFormatProperties * pProperties)423 void lvp_GetPhysicalDeviceSparseImageFormatProperties(
424     VkPhysicalDevice                            physicalDevice,
425     VkFormat                                    format,
426     VkImageType                                 type,
427     uint32_t                                    samples,
428     VkImageUsageFlags                           usage,
429     VkImageTiling                               tiling,
430     uint32_t*                                   pNumProperties,
431     VkSparseImageFormatProperties*              pProperties)
432 {
433    /* Sparse images are not yet supported. */
434    *pNumProperties = 0;
435 }
436 
lvp_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)437 void lvp_GetPhysicalDeviceSparseImageFormatProperties2(
438         VkPhysicalDevice                            physicalDevice,
439         const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
440         uint32_t                                   *pPropertyCount,
441         VkSparseImageFormatProperties2             *pProperties)
442 {
443         /* Sparse images are not yet supported. */
444         *pPropertyCount = 0;
445 }
446