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#ifndef VK_IMAGE_H 24#define VK_IMAGE_H 25 26#include "vk_object.h" 27 28#include "util/u_math.h" 29 30#ifdef __cplusplus 31extern "C" { 32#endif 33 34struct vk_image { 35 struct vk_object_base base; 36 37 VkImageCreateFlags create_flags; 38 VkImageType image_type; 39 VkFormat format; 40 VkExtent3D extent; 41 uint32_t mip_levels; 42 uint32_t array_layers; 43 VkSampleCountFlagBits samples; 44 VkImageTiling tiling; 45 VkImageUsageFlags usage; 46 47 /* Derived from format */ 48 VkImageAspectFlags aspects; 49 50 /* VK_EXT_separate_stencil_usage */ 51 VkImageUsageFlags stencil_usage; 52 53 /* VK_KHR_external_memory */ 54 VkExternalMemoryHandleTypeFlags external_handle_types; 55 56 /* wsi_image_create_info::scanout */ 57 bool wsi_legacy_scanout; 58 59#ifndef _WIN32 60 /* VK_EXT_drm_format_modifier 61 * 62 * Initialized by vk_image_create/init() to DRM_FORMAT_MOD_INVALID. It's 63 * the job of the driver to parse the VK_EXT_drm_format_modifier extension 64 * structs and choose the actual modifier. 65 * 66 * Must be DRM_FORMAT_MOD_INVALID unless tiling is 67 * VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. 68 */ 69 uint64_t drm_format_mod; 70#endif 71 72#ifdef ANDROID 73 /* VK_ANDROID_external_memory_android_hardware_buffer */ 74 uint64_t android_external_format; 75#endif 76}; 77VK_DEFINE_NONDISP_HANDLE_CASTS(vk_image, base, VkImage, 78 VK_OBJECT_TYPE_IMAGE); 79 80void vk_image_init(struct vk_device *device, 81 struct vk_image *image, 82 const VkImageCreateInfo *pCreateInfo); 83void vk_image_finish(struct vk_image *image); 84 85void *vk_image_create(struct vk_device *device, 86 const VkImageCreateInfo *pCreateInfo, 87 const VkAllocationCallbacks *alloc, 88 size_t size); 89void vk_image_destroy(struct vk_device *device, 90 const VkAllocationCallbacks *alloc, 91 struct vk_image *image); 92 93void vk_image_set_format(struct vk_image *image, VkFormat format); 94 95VkImageUsageFlags vk_image_usage(const struct vk_image *image, 96 VkImageAspectFlags aspect_mask); 97 98VkImageAspectFlags vk_image_expand_aspect_mask(const struct vk_image *image, 99 VkImageAspectFlags aspect_mask); 100 101static inline VkExtent3D 102vk_image_mip_level_extent(const struct vk_image *image, 103 uint32_t mip_level) 104{ 105 const VkExtent3D extent = { 106 u_minify(image->extent.width, mip_level), 107 u_minify(image->extent.height, mip_level), 108 u_minify(image->extent.depth, mip_level), 109 }; 110 return extent; 111} 112 113/* This is defined as a macro so that it works for both 114 * VkImageSubresourceRange and VkImageSubresourceLayers 115 */ 116#define vk_image_subresource_layer_count(_image, _range) \ 117 ((_range)->layerCount == VK_REMAINING_ARRAY_LAYERS ? \ 118 (_image)->array_layers - (_range)->baseArrayLayer : (_range)->layerCount) 119 120static inline uint32_t 121vk_image_subresource_level_count(const struct vk_image *image, 122 const VkImageSubresourceRange *range) 123{ 124 return range->levelCount == VK_REMAINING_MIP_LEVELS ? 125 image->mip_levels - range->baseMipLevel : range->levelCount; 126} 127 128static inline VkExtent3D 129vk_image_sanitize_extent(const struct vk_image *image, 130 const VkExtent3D imageExtent) 131{ 132 switch (image->image_type) { 133 case VK_IMAGE_TYPE_1D: 134 return (VkExtent3D) { imageExtent.width, 1, 1 }; 135 case VK_IMAGE_TYPE_2D: 136 return (VkExtent3D) { imageExtent.width, imageExtent.height, 1 }; 137 case VK_IMAGE_TYPE_3D: 138 return imageExtent; 139 default: 140 unreachable("invalid image type"); 141 } 142} 143 144VkExtent3D 145vk_image_extent_to_elements(const struct vk_image *image, VkExtent3D extent); 146 147static inline VkOffset3D 148vk_image_sanitize_offset(const struct vk_image *image, 149 const VkOffset3D imageOffset) 150{ 151 switch (image->image_type) { 152 case VK_IMAGE_TYPE_1D: 153 return (VkOffset3D) { imageOffset.x, 0, 0 }; 154 case VK_IMAGE_TYPE_2D: 155 return (VkOffset3D) { imageOffset.x, imageOffset.y, 0 }; 156 case VK_IMAGE_TYPE_3D: 157 return imageOffset; 158 default: 159 unreachable("invalid image type"); 160 } 161} 162 163VkOffset3D 164vk_image_offset_to_elements(const struct vk_image *image, VkOffset3D offset); 165 166struct vk_image_buffer_layout { 167 /** 168 * VkBufferImageCopy2::bufferRowLength or 169 * VkBufferImageCopy2::extent::width as needed. 170 */ 171 uint32_t row_length; 172 173 /** 174 * VkBufferImageCopy2::bufferImageHeight or 175 * VkBufferImageCopy2::extent::height as needed. 176 */ 177 uint32_t image_height; 178 179 /** Size of a single element (pixel or compressed block) in bytes */ 180 uint32_t element_size_B; 181 182 /** Row stride in bytes */ 183 uint32_t row_stride_B; 184 185 /** Image (or layer) stride in bytes 186 * 187 * For 1D or 2D array images, this is the stride in bytes between array 188 * slices. For 3D images, this is the stride in bytes between fixed-Z 189 * slices. 190 */ 191 uint64_t image_stride_B; 192}; 193 194struct vk_image_buffer_layout 195vk_image_buffer_copy_layout(const struct vk_image *image, 196 const VkBufferImageCopy2* region); 197 198struct vk_image_view { 199 struct vk_object_base base; 200 201 VkImageViewCreateFlags create_flags; 202 struct vk_image *image; 203 VkImageViewType view_type; 204 205 /** VkImageViewCreateInfo::format */ 206 VkFormat format; 207 208 /** Image view format, relative to the selected aspects 209 * 210 * For a depth/stencil image: 211 * 212 * - If vk_image_view::aspects contains both depth and stencil, this will 213 * be the full depth/stencil format of the image. 214 * 215 * - If only one aspect is selected, this will be the depth-only or 216 * stencil-only format, as per the selected aspect. 217 * 218 * For color images, we have three cases: 219 * 220 * 1. It's a single-plane image in which case this is the unmodified 221 * format provided to VkImageViewCreateInfo::format. 222 * 223 * 2. It's a YCbCr view of a multi-plane image in which case the 224 * client will have asked for VK_IMAGE_ASPECT_COLOR_BIT and the 225 * format provided will be the full planar format. In this case, 226 * the format will be the full format containing all the planes. 227 * 228 * 3. It's a single-plane view of a multi-plane image in which case 229 * the client will have asked for VK_IMAGE_ASPECT_PLANE_N_BIT and 230 * will have provided a format compatible with that specific 231 * plane of the multi-planar format. In this case, the format will be 232 * the plane-compatible format requested by the client. 233 */ 234 VkFormat view_format; 235 236 /* Component mapping, aka swizzle 237 * 238 * Unlike the swizzle provided via VkImageViewCreateInfo::components, this 239 * will never contain VK_COMPONENT_SWIZZLE_IDENTITY. It will be resolved 240 * to VK_COMPONENT_SWIZZLE_R/G/B/A, as appropriate. 241 */ 242 VkComponentMapping swizzle; 243 244 /** Aspects from the image represented by this view 245 * 246 * For depth/stencil images, this is the aspectMask provided by 247 * VkImageViewCreateinfo::subresourceRange::aspectMask. 248 * 249 * For color images, we have three cases: 250 * 251 * 1. It's a single-plane image in which case this only aspect is 252 * VK_IMAGE_ASPECT_COLOR_BIT. 253 * 254 * 2. It's a YCbCr view of a multi-plane image in which case the 255 * client will have asked for VK_IMAGE_ASPECT_COLOR_BIT and the 256 * format provided will be the full planar format. In this case, 257 * aspects will be the full set of plane aspects in the image. 258 * 259 * 3. It's a single-plane view of a multi-plane image in which case 260 * the client will have asked for VK_IMAGE_ASPECT_PLANE_N_BIT and 261 * will have provided a format compatible with that specific 262 * plane of the multi-planar format. In this case, aspects will be 263 * VK_IMAGE_ASPECT_PLANE_N_BIT where N is the selected plane. 264 * 265 * This seems almost backwards from the API but ensures that 266 * vk_image_view::aspects is always a subset of vk_image::aspects. 267 */ 268 VkImageAspectFlags aspects; 269 270 uint32_t base_mip_level; 271 uint32_t level_count; 272 uint32_t base_array_layer; 273 uint32_t layer_count; 274 275 /* VK_EXT_image_view_min_lod */ 276 float min_lod; 277 278 /* Image extent at LOD 0 */ 279 VkExtent3D extent; 280 281 /* VK_KHR_maintenance2 */ 282 VkImageUsageFlags usage; 283}; 284VK_DEFINE_NONDISP_HANDLE_CASTS(vk_image_view, base, VkImageView, 285 VK_OBJECT_TYPE_IMAGE_VIEW); 286 287void vk_image_view_init(struct vk_device *device, 288 struct vk_image_view *image_view, 289 bool driver_internal, 290 const VkImageViewCreateInfo *pCreateInfo); 291void vk_image_view_finish(struct vk_image_view *image_view); 292 293void *vk_image_view_create(struct vk_device *device, 294 bool driver_internal, 295 const VkImageViewCreateInfo *pCreateInfo, 296 const VkAllocationCallbacks *alloc, 297 size_t size); 298void vk_image_view_destroy(struct vk_device *device, 299 const VkAllocationCallbacks *alloc, 300 struct vk_image_view *image_view); 301 302static inline VkImageSubresourceRange 303vk_image_view_subresource_range(const struct vk_image_view *view) 304{ 305 VkImageSubresourceRange range = { 306 .aspectMask = view->aspects, 307 .baseMipLevel = view->base_mip_level, 308 .levelCount = view->level_count, 309 .baseArrayLayer = view->base_array_layer, 310 .layerCount = view->layer_count, 311 }; 312 313 return range; 314} 315 316bool vk_image_layout_is_read_only(VkImageLayout layout, 317 VkImageAspectFlagBits aspect); 318bool vk_image_layout_is_depth_only(VkImageLayout layout); 319 320VkImageUsageFlags vk_image_layout_to_usage_flags(VkImageLayout layout, 321 VkImageAspectFlagBits aspect); 322 323VkImageLayout vk_att_ref_stencil_layout(const VkAttachmentReference2 *att_ref, 324 const VkAttachmentDescription2 *attachments); 325VkImageLayout vk_att_desc_stencil_layout(const VkAttachmentDescription2 *att_desc, 326 bool final); 327 328#ifdef __cplusplus 329} 330#endif 331 332#endif /* VK_IMAGE_H */ 333