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