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