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