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