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