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