• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
31 extern "C" {
32 #endif
33 
34 struct 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 };
77 VK_DEFINE_NONDISP_HANDLE_CASTS(vk_image, base, VkImage,
78                                VK_OBJECT_TYPE_IMAGE);
79 
80 void vk_image_init(struct vk_device *device,
81                    struct vk_image *image,
82                    const VkImageCreateInfo *pCreateInfo);
83 void vk_image_finish(struct vk_image *image);
84 
85 void *vk_image_create(struct vk_device *device,
86                       const VkImageCreateInfo *pCreateInfo,
87                       const VkAllocationCallbacks *alloc,
88                       size_t size);
89 void vk_image_destroy(struct vk_device *device,
90                       const VkAllocationCallbacks *alloc,
91                       struct vk_image *image);
92 
93 void vk_image_set_format(struct vk_image *image, VkFormat format);
94 
95 VkImageUsageFlags vk_image_usage(const struct vk_image *image,
96                                  VkImageAspectFlags aspect_mask);
97 
98 VkImageAspectFlags vk_image_expand_aspect_mask(const struct vk_image *image,
99                                                VkImageAspectFlags aspect_mask);
100 
101 static inline VkExtent3D
vk_image_mip_level_extent(const struct vk_image * image,uint32_t mip_level)102 vk_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 
120 static inline uint32_t
vk_image_subresource_level_count(const struct vk_image * image,const VkImageSubresourceRange * range)121 vk_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 
128 static inline VkExtent3D
vk_image_sanitize_extent(const struct vk_image * image,const VkExtent3D imageExtent)129 vk_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 
144 VkExtent3D
145 vk_image_extent_to_elements(const struct vk_image *image, VkExtent3D extent);
146 
147 static inline VkOffset3D
vk_image_sanitize_offset(const struct vk_image * image,const VkOffset3D imageOffset)148 vk_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 
163 VkOffset3D
164 vk_image_offset_to_elements(const struct vk_image *image, VkOffset3D offset);
165 
166 struct 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 
194 struct vk_image_buffer_layout
195 vk_image_buffer_copy_layout(const struct vk_image *image,
196                             const VkBufferImageCopy2* region);
197 
198 struct 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 };
284 VK_DEFINE_NONDISP_HANDLE_CASTS(vk_image_view, base, VkImageView,
285                                VK_OBJECT_TYPE_IMAGE_VIEW);
286 
287 void vk_image_view_init(struct vk_device *device,
288                         struct vk_image_view *image_view,
289                         bool driver_internal,
290                         const VkImageViewCreateInfo *pCreateInfo);
291 void vk_image_view_finish(struct vk_image_view *image_view);
292 
293 void *vk_image_view_create(struct vk_device *device,
294                            bool driver_internal,
295                            const VkImageViewCreateInfo *pCreateInfo,
296                            const VkAllocationCallbacks *alloc,
297                            size_t size);
298 void vk_image_view_destroy(struct vk_device *device,
299                            const VkAllocationCallbacks *alloc,
300                            struct vk_image_view *image_view);
301 
302 static inline VkImageSubresourceRange
vk_image_view_subresource_range(const struct vk_image_view * view)303 vk_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 
316 bool vk_image_layout_is_read_only(VkImageLayout layout,
317                                   VkImageAspectFlagBits aspect);
318 bool vk_image_layout_is_depth_only(VkImageLayout layout);
319 
320 VkImageUsageFlags vk_image_layout_to_usage_flags(VkImageLayout layout,
321                                                  VkImageAspectFlagBits aspect);
322 
323 VkImageLayout vk_att_ref_stencil_layout(const VkAttachmentReference2 *att_ref,
324                                         const VkAttachmentDescription2 *attachments);
325 VkImageLayout 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