• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
40 static VkExtent3D
sanitize_image_extent(const VkImageType imageType,const VkExtent3D imageExtent)41 sanitize_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 
56 void
vk_image_init(struct vk_device * device,struct vk_image * image,const VkImageCreateInfo * pCreateInfo)57 vk_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 
127 void *
vk_image_create(struct vk_device * device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc,size_t size)128 vk_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 
144 void
vk_image_finish(struct vk_image * image)145 vk_image_finish(struct vk_image *image)
146 {
147    vk_object_base_finish(&image->base);
148 }
149 
150 void
vk_image_destroy(struct vk_device * device,const VkAllocationCallbacks * alloc,struct vk_image * image)151 vk_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
159 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetImageDrmFormatModifierPropertiesEXT(UNUSED VkDevice device,VkImage _image,VkImageDrmFormatModifierPropertiesEXT * pProperties)160 vk_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 
176 void
vk_image_set_format(struct vk_image * image,VkFormat format)177 vk_image_set_format(struct vk_image *image, VkFormat format)
178 {
179    image->format = format;
180    image->aspects = vk_format_aspects(format);
181 }
182 
183 VkImageUsageFlags
vk_image_usage(const struct vk_image * image,VkImageAspectFlags aspect_mask)184 vk_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  */
241 VkImageAspectFlags
vk_image_expand_aspect_mask(const struct vk_image * image,VkImageAspectFlags aspect_mask)242 vk_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 
254 VkExtent3D
vk_image_extent_to_elements(const struct vk_image * image,VkExtent3D extent)255 vk_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 
268 VkOffset3D
vk_image_offset_to_elements(const struct vk_image * image,VkOffset3D offset)269 vk_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 
287 struct vk_image_buffer_layout
vk_image_buffer_copy_layout(const struct vk_image * image,const VkBufferImageCopy2 * region)288 vk_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 
319 static VkComponentSwizzle
remap_swizzle(VkComponentSwizzle swizzle,VkComponentSwizzle component)320 remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component)
321 {
322    return swizzle == VK_COMPONENT_SWIZZLE_IDENTITY ? component : swizzle;
323 }
324 
325 void
vk_image_view_init(struct vk_device * device,struct vk_image_view * image_view,bool driver_internal,const VkImageViewCreateInfo * pCreateInfo)326 vk_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 
508 void
vk_image_view_finish(struct vk_image_view * image_view)509 vk_image_view_finish(struct vk_image_view *image_view)
510 {
511    vk_object_base_finish(&image_view->base);
512 }
513 
514 void *
vk_image_view_create(struct vk_device * device,bool driver_internal,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc,size_t size)515 vk_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 
532 void
vk_image_view_destroy(struct vk_device * device,const VkAllocationCallbacks * alloc,struct vk_image_view * image_view)533 vk_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 
540 bool
vk_image_layout_is_read_only(VkImageLayout layout,VkImageAspectFlagBits aspect)541 vk_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 
602 bool
vk_image_layout_is_depth_only(VkImageLayout layout)603 vk_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  */
623 VkImageLayout
vk_att_ref_stencil_layout(const VkAttachmentReference2 * att_ref,const VkAttachmentDescription2 * attachments)624 vk_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  */
673 VkImageLayout
vk_att_desc_stencil_layout(const VkAttachmentDescription2 * att_desc,bool final)674 vk_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 
703 VkImageUsageFlags
vk_image_layout_to_usage_flags(VkImageLayout layout,VkImageAspectFlagBits aspect)704 vk_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