1/*
2 * Copyright © 2021 Intel Corporation
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 "vk_image.h"
25
26#include <vulkan/vulkan_android.h>
27
28#ifndef _WIN32
29#include <drm-uapi/drm_fourcc.h>
30#endif
31
32#include "vk_alloc.h"
33#include "vk_common_entrypoints.h"
34#include "vk_device.h"
35#include "vk_format.h"
36#include "vk_render_pass.h"
37#include "vk_util.h"
38#include "vulkan/wsi/wsi_common.h"
39
40static VkExtent3D
41sanitize_image_extent(const VkImageType imageType,
42                      const VkExtent3D imageExtent)
43{
44   switch (imageType) {
45   case VK_IMAGE_TYPE_1D:
46      return (VkExtent3D) { imageExtent.width, 1, 1 };
47   case VK_IMAGE_TYPE_2D:
48      return (VkExtent3D) { imageExtent.width, imageExtent.height, 1 };
49   case VK_IMAGE_TYPE_3D:
50      return imageExtent;
51   default:
52      unreachable("invalid image type");
53   }
54}
55
56void
57vk_image_init(struct vk_device *device,
58              struct vk_image *image,
59              const VkImageCreateInfo *pCreateInfo)
60{
61   vk_object_base_init(device, &image->base, VK_OBJECT_TYPE_IMAGE);
62
63   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
64   assert(pCreateInfo->mipLevels > 0);
65   assert(pCreateInfo->arrayLayers > 0);
66   assert(pCreateInfo->samples > 0);
67   assert(pCreateInfo->extent.width > 0);
68   assert(pCreateInfo->extent.height > 0);
69   assert(pCreateInfo->extent.depth > 0);
70
71   if (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
72      assert(pCreateInfo->imageType == VK_IMAGE_TYPE_2D);
73   if (pCreateInfo->flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT)
74      assert(pCreateInfo->imageType == VK_IMAGE_TYPE_3D);
75
76   image->create_flags = pCreateInfo->flags;
77   image->image_type = pCreateInfo->imageType;
78   vk_image_set_format(image, pCreateInfo->format);
79   image->extent = sanitize_image_extent(pCreateInfo->imageType,
80                                         pCreateInfo->extent);
81   image->mip_levels = pCreateInfo->mipLevels;
82   image->array_layers = pCreateInfo->arrayLayers;
83   image->samples = pCreateInfo->samples;
84   image->tiling = pCreateInfo->tiling;
85   image->usage = pCreateInfo->usage;
86
87   if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
88      const VkImageStencilUsageCreateInfo *stencil_usage_info =
89         vk_find_struct_const(pCreateInfo->pNext,
90                              IMAGE_STENCIL_USAGE_CREATE_INFO);
91      image->stencil_usage =
92         stencil_usage_info ? stencil_usage_info->stencilUsage :
93                              pCreateInfo->usage;
94   } else {
95      image->stencil_usage = 0;
96   }
97
98   const VkExternalMemoryImageCreateInfo *ext_mem_info =
99      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
100   if (ext_mem_info)
101      image->external_handle_types = ext_mem_info->handleTypes;
102   else
103      image->external_handle_types = 0;
104
105   const struct wsi_image_create_info *wsi_info =
106      vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
107   image->wsi_legacy_scanout = wsi_info && wsi_info->scanout;
108
109#ifndef _WIN32
110   image->drm_format_mod = ((1ULL << 56) - 1) /* DRM_FORMAT_MOD_INVALID */;
111#endif
112
113#ifdef ANDROID
114   const VkExternalFormatANDROID *ext_format =
115      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
116   if (ext_format && ext_format->externalFormat != 0) {
117      assert(image->format == VK_FORMAT_UNDEFINED);
118      assert(image->external_handle_types &
119             VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID);
120      image->android_external_format = ext_format->externalFormat;
121   } else {
122      image->android_external_format = 0;
123   }
124#endif
125}
126
127void *
128vk_image_create(struct vk_device *device,
129                const VkImageCreateInfo *pCreateInfo,
130                const VkAllocationCallbacks *alloc,
131                size_t size)
132{
133   struct vk_image *image =
134      vk_zalloc2(&device->alloc, alloc, size, 8,
135                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
136   if (image == NULL)
137      return NULL;
138
139   vk_image_init(device, image, pCreateInfo);
140
141   return image;
142}
143
144void
145vk_image_finish(struct vk_image *image)
146{
147   vk_object_base_finish(&image->base);
148}
149
150void
151vk_image_destroy(struct vk_device *device,
152                 const VkAllocationCallbacks *alloc,
153                 struct vk_image *image)
154{
155   vk_object_free(device, alloc, image);
156}
157
158#ifndef _WIN32
159VKAPI_ATTR VkResult VKAPI_CALL
160vk_common_GetImageDrmFormatModifierPropertiesEXT(UNUSED VkDevice device,
161                                                 VkImage _image,
162                                                 VkImageDrmFormatModifierPropertiesEXT *pProperties)
163{
164   VK_FROM_HANDLE(vk_image, image, _image);
165
166   assert(pProperties->sType ==
167          VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT);
168
169   assert(image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
170   pProperties->drmFormatModifier = image->drm_format_mod;
171
172   return VK_SUCCESS;
173}
174#endif
175
176void
177vk_image_set_format(struct vk_image *image, VkFormat format)
178{
179   image->format = format;
180   image->aspects = vk_format_aspects(format);
181}
182
183VkImageUsageFlags
184vk_image_usage(const struct vk_image *image,
185               VkImageAspectFlags aspect_mask)
186{
187   assert(!(aspect_mask & ~image->aspects));
188
189   /* From the Vulkan 1.2.131 spec:
190    *
191    *    "If the image was has a depth-stencil format and was created with
192    *    a VkImageStencilUsageCreateInfo structure included in the pNext
193    *    chain of VkImageCreateInfo, the usage is calculated based on the
194    *    subresource.aspectMask provided:
195    *
196    *     - If aspectMask includes only VK_IMAGE_ASPECT_STENCIL_BIT, the
197    *       implicit usage is equal to
198    *       VkImageStencilUsageCreateInfo::stencilUsage.
199    *
200    *     - If aspectMask includes only VK_IMAGE_ASPECT_DEPTH_BIT, the
201    *       implicit usage is equal to VkImageCreateInfo::usage.
202    *
203    *     - If both aspects are included in aspectMask, the implicit usage
204    *       is equal to the intersection of VkImageCreateInfo::usage and
205    *       VkImageStencilUsageCreateInfo::stencilUsage.
206    */
207   if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
208      return image->stencil_usage;
209   } else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT |
210                              VK_IMAGE_ASPECT_STENCIL_BIT)) {
211      return image->usage & image->stencil_usage;
212   } else {
213      /* This also handles the color case */
214      return image->usage;
215   }
216}
217
218#define VK_IMAGE_ASPECT_ANY_COLOR_MASK_MESA ( \
219   VK_IMAGE_ASPECT_COLOR_BIT | \
220   VK_IMAGE_ASPECT_PLANE_0_BIT | \
221   VK_IMAGE_ASPECT_PLANE_1_BIT | \
222   VK_IMAGE_ASPECT_PLANE_2_BIT)
223
224/** Expands the given aspect mask relative to the image
225 *
226 * If the image has color plane aspects VK_IMAGE_ASPECT_COLOR_BIT has been
227 * requested, this returns the aspects of the underlying image.
228 *
229 * For example,
230 *
231 *    VK_IMAGE_ASPECT_COLOR_BIT
232 *
233 * will be converted to
234 *
235 *    VK_IMAGE_ASPECT_PLANE_0_BIT |
236 *    VK_IMAGE_ASPECT_PLANE_1_BIT |
237 *    VK_IMAGE_ASPECT_PLANE_2_BIT
238 *
239 * for an image of format VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM.
240 */
241VkImageAspectFlags
242vk_image_expand_aspect_mask(const struct vk_image *image,
243                            VkImageAspectFlags aspect_mask)
244{
245   if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
246      assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_MASK_MESA);
247      return image->aspects;
248   } else {
249      assert(aspect_mask && !(aspect_mask & ~image->aspects));
250      return aspect_mask;
251   }
252}
253
254VkExtent3D
255vk_image_extent_to_elements(const struct vk_image *image, VkExtent3D extent)
256{
257   const struct util_format_description *fmt =
258      vk_format_description(image->format);
259
260   extent = vk_image_sanitize_extent(image, extent);
261   extent.width = DIV_ROUND_UP(extent.width, fmt->block.width);
262   extent.height = DIV_ROUND_UP(extent.height, fmt->block.height);
263   extent.depth = DIV_ROUND_UP(extent.depth, fmt->block.depth);
264
265   return extent;
266}
267
268VkOffset3D
269vk_image_offset_to_elements(const struct vk_image *image, VkOffset3D offset)
270{
271   const struct util_format_description *fmt =
272      vk_format_description(image->format);
273
274   offset = vk_image_sanitize_offset(image, offset);
275
276   assert(offset.x % fmt->block.width == 0);
277   assert(offset.y % fmt->block.height == 0);
278   assert(offset.z % fmt->block.depth == 0);
279
280   offset.x /= fmt->block.width;
281   offset.y /= fmt->block.height;
282   offset.z /= fmt->block.depth;
283
284   return offset;
285}
286
287struct vk_image_buffer_layout
288vk_image_buffer_copy_layout(const struct vk_image *image,
289                            const VkBufferImageCopy2* region)
290{
291   VkExtent3D extent = vk_image_sanitize_extent(image, region->imageExtent);
292
293   const uint32_t row_length = region->bufferRowLength ?
294                               region->bufferRowLength : extent.width;
295   const uint32_t image_height = region->bufferImageHeight ?
296                                 region->bufferImageHeight : extent.height;
297
298   const VkImageAspectFlags aspect = region->imageSubresource.aspectMask;
299   VkFormat format = vk_format_get_aspect_format(image->format, aspect);
300   const struct util_format_description *fmt = vk_format_description(format);
301
302   assert(fmt->block.bits % 8 == 0);
303   const uint32_t element_size_B = fmt->block.bits / 8;
304
305   const uint32_t row_stride_B =
306      DIV_ROUND_UP(row_length, fmt->block.width) * element_size_B;
307   const uint64_t image_stride_B =
308      DIV_ROUND_UP(image_height, fmt->block.height) * (uint64_t)row_stride_B;
309
310   return (struct vk_image_buffer_layout) {
311      .row_length = row_length,
312      .image_height = image_height,
313      .element_size_B = element_size_B,
314      .row_stride_B = row_stride_B,
315      .image_stride_B = image_stride_B,
316   };
317}
318
319static VkComponentSwizzle
320remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component)
321{
322   return swizzle == VK_COMPONENT_SWIZZLE_IDENTITY ? component : swizzle;
323}
324
325void
326vk_image_view_init(struct vk_device *device,
327                   struct vk_image_view *image_view,
328                   bool driver_internal,
329                   const VkImageViewCreateInfo *pCreateInfo)
330{
331   vk_object_base_init(device, &image_view->base, VK_OBJECT_TYPE_IMAGE_VIEW);
332
333   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
334   VK_FROM_HANDLE(vk_image, image, pCreateInfo->image);
335
336   image_view->create_flags = pCreateInfo->flags;
337   image_view->image = image;
338   image_view->view_type = pCreateInfo->viewType;
339   image_view->format = pCreateInfo->format;
340
341   if (!driver_internal) {
342      switch (image_view->view_type) {
343      case VK_IMAGE_VIEW_TYPE_1D:
344      case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
345         assert(image->image_type == VK_IMAGE_TYPE_1D);
346         break;
347      case VK_IMAGE_VIEW_TYPE_2D:
348      case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
349         if (image->create_flags & (VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT |
350                                    VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT))
351            assert(image->image_type == VK_IMAGE_TYPE_3D);
352         else
353            assert(image->image_type == VK_IMAGE_TYPE_2D);
354         break;
355      case VK_IMAGE_VIEW_TYPE_3D:
356         assert(image->image_type == VK_IMAGE_TYPE_3D);
357         break;
358      case VK_IMAGE_VIEW_TYPE_CUBE:
359      case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
360         assert(image->image_type == VK_IMAGE_TYPE_2D);
361         assert(image->create_flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT);
362         break;
363      default:
364         unreachable("Invalid image view type");
365      }
366   }
367
368   const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
369
370   if (driver_internal) {
371      /* For driver internal images, all we require is that the block sizes
372       * match.  Otherwise, we trust the driver to use a format it knows what
373       * to do with.  Combined depth/stencil images might not match if the
374       * driver only cares about one of the two aspects.
375       */
376      if (image->aspects == VK_IMAGE_ASPECT_COLOR_BIT ||
377          image->aspects == VK_IMAGE_ASPECT_DEPTH_BIT ||
378          image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT) {
379         assert(vk_format_get_blocksize(image->format) ==
380                vk_format_get_blocksize(image_view->format));
381      }
382      image_view->aspects = range->aspectMask;
383      image_view->view_format = pCreateInfo->format;
384   } else {
385      image_view->aspects =
386         vk_image_expand_aspect_mask(image, range->aspectMask);
387
388      /* From the Vulkan 1.2.184 spec:
389       *
390       *    "If the image has a multi-planar format and
391       *    subresourceRange.aspectMask is VK_IMAGE_ASPECT_COLOR_BIT, and image
392       *    has been created with a usage value not containing any of the
393       *    VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR,
394       *    VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR,
395       *    VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR,
396       *    VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR,
397       *    VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, and
398       *    VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR flags, then the format must
399       *    be identical to the image format, and the sampler to be used with the
400       *    image view must enable sampler Y′CBCR conversion."
401       *
402       * Since no one implements video yet, we can ignore the bits about video
403       * create flags and assume YCbCr formats match.
404       */
405      if ((image->aspects & VK_IMAGE_ASPECT_PLANE_1_BIT) &&
406          (range->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT))
407         assert(pCreateInfo->format == image->format);
408
409      /* From the Vulkan 1.2.184 spec:
410       *
411       *    "Each depth/stencil format is only compatible with itself."
412       */
413      if (image_view->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
414                                 VK_IMAGE_ASPECT_STENCIL_BIT))
415         assert(pCreateInfo->format == image->format);
416
417      if (!(image->create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
418         assert(pCreateInfo->format == image->format);
419
420      /* Restrict the format to only the planes chosen.
421       *
422       * For combined depth and stencil images, this means the depth-only or
423       * stencil-only format if only one aspect is chosen and the full
424       * combined format if both aspects are chosen.
425       *
426       * For single-plane color images, we just take the format as-is.  For
427       * multi-plane views of multi-plane images, this means we want the full
428       * multi-plane format.  For single-plane views of multi-plane images, we
429       * want a format compatible with the one plane.  Fortunately, this is
430       * already what the client gives us.  The Vulkan 1.2.184 spec says:
431       *
432       *    "If image was created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
433       *    and the image has a multi-planar format, and if
434       *    subresourceRange.aspectMask is VK_IMAGE_ASPECT_PLANE_0_BIT,
435       *    VK_IMAGE_ASPECT_PLANE_1_BIT, or VK_IMAGE_ASPECT_PLANE_2_BIT,
436       *    format must be compatible with the corresponding plane of the
437       *    image, and the sampler to be used with the image view must not
438       *    enable sampler Y′CBCR conversion."
439       */
440      if (image_view->aspects == VK_IMAGE_ASPECT_STENCIL_BIT) {
441         image_view->view_format = vk_format_stencil_only(pCreateInfo->format);
442      } else if (image_view->aspects == VK_IMAGE_ASPECT_DEPTH_BIT) {
443         image_view->view_format = vk_format_depth_only(pCreateInfo->format);
444      } else {
445         image_view->view_format = pCreateInfo->format;
446      }
447   }
448
449   image_view->swizzle = (VkComponentMapping) {
450      .r = remap_swizzle(pCreateInfo->components.r, VK_COMPONENT_SWIZZLE_R),
451      .g = remap_swizzle(pCreateInfo->components.g, VK_COMPONENT_SWIZZLE_G),
452      .b = remap_swizzle(pCreateInfo->components.b, VK_COMPONENT_SWIZZLE_B),
453      .a = remap_swizzle(pCreateInfo->components.a, VK_COMPONENT_SWIZZLE_A),
454   };
455
456   assert(range->layerCount > 0);
457   assert(range->baseMipLevel < image->mip_levels);
458
459   image_view->base_mip_level = range->baseMipLevel;
460   image_view->level_count = vk_image_subresource_level_count(image, range);
461   image_view->base_array_layer = range->baseArrayLayer;
462   image_view->layer_count = vk_image_subresource_layer_count(image, range);
463
464   const VkImageViewMinLodCreateInfoEXT *min_lod_info =
465      vk_find_struct_const(pCreateInfo, IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT);
466   image_view->min_lod = min_lod_info ? min_lod_info->minLod : 0.0f;
467
468   /* From the Vulkan 1.3.215 spec:
469    *
470    *    VUID-VkImageViewMinLodCreateInfoEXT-minLod-06456
471    *
472    *    "minLod must be less or equal to the index of the last mipmap level
473    *    accessible to the view."
474    */
475   assert(image_view->min_lod <= image_view->base_mip_level +
476                                 image_view->level_count - 1);
477
478   image_view->extent =
479      vk_image_mip_level_extent(image, image_view->base_mip_level);
480
481   assert(image_view->base_mip_level + image_view->level_count
482          <= image->mip_levels);
483   switch (image->image_type) {
484   default:
485      unreachable("bad VkImageType");
486   case VK_IMAGE_TYPE_1D:
487   case VK_IMAGE_TYPE_2D:
488      assert(image_view->base_array_layer + image_view->layer_count
489             <= image->array_layers);
490      break;
491   case VK_IMAGE_TYPE_3D:
492      assert(image_view->base_array_layer + image_view->layer_count
493             <= image_view->extent.depth);
494      break;
495   }
496
497   /* If we are creating a color view from a depth/stencil image we compute
498    * usage from the underlying depth/stencil aspects.
499    */
500   const VkImageUsageFlags image_usage =
501      vk_image_usage(image, image_view->aspects);
502   const VkImageViewUsageCreateInfo *usage_info =
503      vk_find_struct_const(pCreateInfo, IMAGE_VIEW_USAGE_CREATE_INFO);
504   image_view->usage = usage_info ? usage_info->usage : image_usage;
505   assert(driver_internal || !(image_view->usage & ~image_usage));
506}
507
508void
509vk_image_view_finish(struct vk_image_view *image_view)
510{
511   vk_object_base_finish(&image_view->base);
512}
513
514void *
515vk_image_view_create(struct vk_device *device,
516                     bool driver_internal,
517                     const VkImageViewCreateInfo *pCreateInfo,
518                     const VkAllocationCallbacks *alloc,
519                     size_t size)
520{
521   struct vk_image_view *image_view =
522      vk_zalloc2(&device->alloc, alloc, size, 8,
523                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
524   if (image_view == NULL)
525      return NULL;
526
527   vk_image_view_init(device, image_view, driver_internal, pCreateInfo);
528
529   return image_view;
530}
531
532void
533vk_image_view_destroy(struct vk_device *device,
534                      const VkAllocationCallbacks *alloc,
535                      struct vk_image_view *image_view)
536{
537   vk_object_free(device, alloc, image_view);
538}
539
540bool
541vk_image_layout_is_read_only(VkImageLayout layout,
542                             VkImageAspectFlagBits aspect)
543{
544   assert(util_bitcount(aspect) == 1);
545
546   switch (layout) {
547   case VK_IMAGE_LAYOUT_UNDEFINED:
548   case VK_IMAGE_LAYOUT_PREINITIALIZED:
549      return true; /* These are only used for layout transitions */
550
551   case VK_IMAGE_LAYOUT_GENERAL:
552   case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
553   case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
554   case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
555   case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
556   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
557   case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL:
558   case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL:
559   case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT:
560#ifdef __GNUC__
561#pragma GCC diagnostic push
562#pragma GCC diagnostic ignored "-Wswitch"
563#endif
564   case VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA:
565#ifdef __GNUC__
566#pragma GCC diagnostic pop
567#endif
568      return false;
569
570   case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
571   case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
572   case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
573   case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
574   case VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR:
575   case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
576   case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL:
577   case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL:
578   case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL:
579      return true;
580
581   case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
582      return aspect == VK_IMAGE_ASPECT_DEPTH_BIT;
583
584   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
585      return aspect == VK_IMAGE_ASPECT_STENCIL_BIT;
586
587   case VK_IMAGE_LAYOUT_MAX_ENUM:
588#ifdef VK_ENABLE_BETA_EXTENSIONS
589   case VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR:
590   case VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR:
591   case VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR:
592   case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR:
593   case VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR:
594   case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR:
595#endif
596      unreachable("Invalid image layout.");
597   }
598
599   unreachable("Invalid image layout.");
600}
601
602bool
603vk_image_layout_is_depth_only(VkImageLayout layout)
604{
605   switch (layout) {
606   case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL:
607   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
608      return true;
609
610   default:
611      return false;
612   }
613}
614
615/* From the Vulkan Specification 1.2.166 - VkAttachmentReference2:
616 *
617 *   "If layout only specifies the layout of the depth aspect of the
618 *    attachment, the layout of the stencil aspect is specified by the
619 *    stencilLayout member of a VkAttachmentReferenceStencilLayout structure
620 *    included in the pNext chain. Otherwise, layout describes the layout for
621 *    all relevant image aspects."
622 */
623VkImageLayout
624vk_att_ref_stencil_layout(const VkAttachmentReference2 *att_ref,
625                          const VkAttachmentDescription2 *attachments)
626{
627   /* From VUID-VkAttachmentReference2-attachment-04755:
628    *  "If attachment is not VK_ATTACHMENT_UNUSED, and the format of the
629    *   referenced attachment is a depth/stencil format which includes both
630    *   depth and stencil aspects [...]
631    */
632   if (att_ref->attachment == VK_ATTACHMENT_UNUSED ||
633       !vk_format_has_stencil(attachments[att_ref->attachment].format))
634      return VK_IMAGE_LAYOUT_UNDEFINED;
635
636   const VkAttachmentReferenceStencilLayout *stencil_ref =
637      vk_find_struct_const(att_ref->pNext, ATTACHMENT_REFERENCE_STENCIL_LAYOUT);
638
639   if (stencil_ref)
640      return stencil_ref->stencilLayout;
641
642   /* From VUID-VkAttachmentReference2-attachment-04755:
643    *  "If attachment is not VK_ATTACHMENT_UNUSED, and the format of the
644    *   referenced attachment is a depth/stencil format which includes both
645    *   depth and stencil aspects, and layout is
646    *   VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL or
647    *   VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, the pNext chain must include
648    *   a VkAttachmentReferenceStencilLayout structure."
649    */
650   assert(!vk_image_layout_is_depth_only(att_ref->layout));
651
652   return att_ref->layout;
653}
654
655/* From the Vulkan Specification 1.2.184:
656 *
657 *   "If the pNext chain includes a VkAttachmentDescriptionStencilLayout
658 *    structure, then the stencilInitialLayout and stencilFinalLayout members
659 *    specify the initial and final layouts of the stencil aspect of a
660 *    depth/stencil format, and initialLayout and finalLayout only apply to the
661 *    depth aspect. For depth-only formats, the
662 *    VkAttachmentDescriptionStencilLayout structure is ignored. For
663 *    stencil-only formats, the initial and final layouts of the stencil aspect
664 *    are taken from the VkAttachmentDescriptionStencilLayout structure if
665 *    present, or initialLayout and finalLayout if not present."
666 *
667 *   "If format is a depth/stencil format, and either initialLayout or
668 *    finalLayout does not specify a layout for the stencil aspect, then the
669 *    application must specify the initial and final layouts of the stencil
670 *    aspect by including a VkAttachmentDescriptionStencilLayout structure in
671 *    the pNext chain."
672 */
673VkImageLayout
674vk_att_desc_stencil_layout(const VkAttachmentDescription2 *att_desc, bool final)
675{
676   if (!vk_format_has_stencil(att_desc->format))
677      return VK_IMAGE_LAYOUT_UNDEFINED;
678
679   const VkAttachmentDescriptionStencilLayout *stencil_desc =
680      vk_find_struct_const(att_desc->pNext, ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT);
681
682   if (stencil_desc) {
683      return final ?
684         stencil_desc->stencilFinalLayout :
685         stencil_desc->stencilInitialLayout;
686   }
687
688   const VkImageLayout main_layout =
689      final ? att_desc->finalLayout : att_desc->initialLayout;
690
691   /* From VUID-VkAttachmentDescription2-format-03302/03303:
692    *  "If format is a depth/stencil format which includes both depth and
693    *   stencil aspects, and initial/finalLayout is
694    *   VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL or
695    *   VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, the pNext chain must include
696    *   a VkAttachmentDescriptionStencilLayout structure."
697    */
698   assert(!vk_image_layout_is_depth_only(main_layout));
699
700   return main_layout;
701}
702
703VkImageUsageFlags
704vk_image_layout_to_usage_flags(VkImageLayout layout,
705                               VkImageAspectFlagBits aspect)
706{
707   assert(util_bitcount(aspect) == 1);
708
709   switch (layout) {
710   case VK_IMAGE_LAYOUT_UNDEFINED:
711   case VK_IMAGE_LAYOUT_PREINITIALIZED:
712      return 0u;
713
714   case VK_IMAGE_LAYOUT_GENERAL:
715#ifdef __GNUC__
716#pragma GCC diagnostic push
717#pragma GCC diagnostic ignored "-Wswitch"
718#endif
719   case VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA:
720#ifdef __GNUC__
721#pragma GCC diagnostic pop
722#endif
723      return ~0u;
724
725   case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
726      assert(aspect & VK_IMAGE_ASPECT_ANY_COLOR_MASK_MESA);
727      return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
728
729   case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
730      assert(aspect & (VK_IMAGE_ASPECT_DEPTH_BIT |
731                       VK_IMAGE_ASPECT_STENCIL_BIT));
732      return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
733
734   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
735      assert(aspect & VK_IMAGE_ASPECT_DEPTH_BIT);
736      return vk_image_layout_to_usage_flags(
737         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, aspect);
738
739   case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL:
740      assert(aspect & VK_IMAGE_ASPECT_STENCIL_BIT);
741      return vk_image_layout_to_usage_flags(
742         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, aspect);
743
744   case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
745      assert(aspect & (VK_IMAGE_ASPECT_DEPTH_BIT |
746                       VK_IMAGE_ASPECT_STENCIL_BIT));
747      return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
748             VK_IMAGE_USAGE_SAMPLED_BIT |
749             VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
750
751   case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL:
752      assert(aspect & VK_IMAGE_ASPECT_DEPTH_BIT);
753      return vk_image_layout_to_usage_flags(
754         VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, aspect);
755
756   case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL:
757      assert(aspect & VK_IMAGE_ASPECT_STENCIL_BIT);
758      return vk_image_layout_to_usage_flags(
759         VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, aspect);
760
761   case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
762      return VK_IMAGE_USAGE_SAMPLED_BIT |
763             VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
764
765   case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
766      return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
767
768   case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
769      return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
770
771   case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
772      if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
773         return vk_image_layout_to_usage_flags(
774            VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, aspect);
775      } else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {
776         return vk_image_layout_to_usage_flags(
777            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, aspect);
778      } else {
779         assert(!"Must be a depth/stencil aspect");
780         return 0;
781      }
782
783   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
784      if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
785         return vk_image_layout_to_usage_flags(
786            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, aspect);
787      } else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {
788         return vk_image_layout_to_usage_flags(
789            VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, aspect);
790      } else {
791         assert(!"Must be a depth/stencil aspect");
792         return 0;
793      }
794
795   case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
796      assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
797      /* This needs to be handled specially by the caller */
798      return 0;
799
800   case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
801      assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
802      return vk_image_layout_to_usage_flags(VK_IMAGE_LAYOUT_GENERAL, aspect);
803
804   case VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR:
805      assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
806      return VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
807
808   case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
809      assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
810      return VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT;
811
812   case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL:
813      if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT ||
814          aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {
815         return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
816      } else {
817         assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
818         return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
819      }
820
821   case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL:
822      return VK_IMAGE_USAGE_SAMPLED_BIT |
823             VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
824
825   case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT:
826      return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
827             VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
828             VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
829             VK_IMAGE_USAGE_SAMPLED_BIT;
830
831   case VK_IMAGE_LAYOUT_MAX_ENUM:
832#ifdef VK_ENABLE_BETA_EXTENSIONS
833   case VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR:
834   case VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR:
835   case VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR:
836   case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR:
837   case VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR:
838   case VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR:
839#endif
840      unreachable("Invalid image layout.");
841   }
842
843   unreachable("Invalid image layout.");
844}
845