1 /*
2 * Copyright © 2016 Intel Corporation
3 * Copyright © 2019 Google LLC
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #ifndef U_FORMAT_VK_H
26 #define U_FORMAT_VK_H
27
28 #include <vulkan/vulkan_core.h>
29 #include "util/format/u_format.h"
30 #include "util/u_math.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 extern const enum pipe_format vk_format_map[];
37
38 enum pipe_format
39 vk_format_to_pipe_format(enum VkFormat vkformat);
40
41 VkImageAspectFlags
42 vk_format_aspects(VkFormat format);
43
44 static inline bool
vk_format_is_color(VkFormat format)45 vk_format_is_color(VkFormat format)
46 {
47 return vk_format_aspects(format) == VK_IMAGE_ASPECT_COLOR_BIT;
48 }
49
50 static inline bool
vk_format_is_depth_or_stencil(VkFormat format)51 vk_format_is_depth_or_stencil(VkFormat format)
52 {
53 const VkImageAspectFlags aspects = vk_format_aspects(format);
54 return aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
55 }
56
57 static inline bool
vk_format_has_depth(VkFormat format)58 vk_format_has_depth(VkFormat format)
59 {
60 const VkImageAspectFlags aspects = vk_format_aspects(format);
61 return aspects & VK_IMAGE_ASPECT_DEPTH_BIT;
62 }
63
64 static inline bool
vk_format_has_stencil(VkFormat format)65 vk_format_has_stencil(VkFormat format)
66 {
67 const VkImageAspectFlags aspects = vk_format_aspects(format);
68 return aspects & VK_IMAGE_ASPECT_STENCIL_BIT;
69 }
70
71 static inline VkFormat
vk_format_depth_only(VkFormat format)72 vk_format_depth_only(VkFormat format)
73 {
74 assert(vk_format_has_depth(format));
75 switch (format) {
76 case VK_FORMAT_D16_UNORM_S8_UINT:
77 return VK_FORMAT_D16_UNORM;
78 case VK_FORMAT_D24_UNORM_S8_UINT:
79 return VK_FORMAT_X8_D24_UNORM_PACK32;
80 case VK_FORMAT_D32_SFLOAT_S8_UINT:
81 return VK_FORMAT_D32_SFLOAT;
82 default:
83 return format;
84 }
85 }
86
87 static inline VkFormat
vk_format_stencil_only(VkFormat format)88 vk_format_stencil_only(VkFormat format)
89 {
90 assert(vk_format_has_stencil(format));
91 return VK_FORMAT_S8_UINT;
92 }
93
94 void vk_component_mapping_to_pipe_swizzle(VkComponentMapping mapping,
95 unsigned char out_swizzle[4]);
96
97 static inline bool
vk_format_is_int(VkFormat format)98 vk_format_is_int(VkFormat format)
99 {
100 return util_format_is_pure_integer(vk_format_to_pipe_format(format));
101 }
102
103 static inline bool
vk_format_is_sint(VkFormat format)104 vk_format_is_sint(VkFormat format)
105 {
106 return util_format_is_pure_sint(vk_format_to_pipe_format(format));
107 }
108
109 static inline bool
vk_format_is_uint(VkFormat format)110 vk_format_is_uint(VkFormat format)
111 {
112 return util_format_is_pure_uint(vk_format_to_pipe_format(format));
113 }
114
115 static inline bool
vk_format_is_unorm(VkFormat format)116 vk_format_is_unorm(VkFormat format)
117 {
118 return util_format_is_unorm(vk_format_to_pipe_format(format));
119 }
120
121 static inline bool
vk_format_is_snorm(VkFormat format)122 vk_format_is_snorm(VkFormat format)
123 {
124 return util_format_is_snorm(vk_format_to_pipe_format(format));
125 }
126
127 static inline bool
vk_format_is_float(VkFormat format)128 vk_format_is_float(VkFormat format)
129 {
130 return util_format_is_float(vk_format_to_pipe_format(format));
131 }
132
133 static inline bool
vk_format_is_srgb(VkFormat format)134 vk_format_is_srgb(VkFormat format)
135 {
136 return util_format_is_srgb(vk_format_to_pipe_format(format));
137 }
138
139 static inline unsigned
vk_format_get_blocksize(VkFormat format)140 vk_format_get_blocksize(VkFormat format)
141 {
142 return util_format_get_blocksize(vk_format_to_pipe_format(format));
143 }
144
145 static inline unsigned
vk_format_get_blockwidth(VkFormat format)146 vk_format_get_blockwidth(VkFormat format)
147 {
148 return util_format_get_blockwidth(vk_format_to_pipe_format(format));
149 }
150
151 static inline unsigned
vk_format_get_blockheight(VkFormat format)152 vk_format_get_blockheight(VkFormat format)
153 {
154 return util_format_get_blockheight(vk_format_to_pipe_format(format));
155 }
156
157 static inline bool
vk_format_is_compressed(VkFormat format)158 vk_format_is_compressed(VkFormat format)
159 {
160 /* this includes 4:2:2 formats, which are compressed formats for vulkan */
161 return vk_format_get_blockwidth(format) > 1;
162 }
163
164 static inline bool
vk_format_is_block_compressed(VkFormat format)165 vk_format_is_block_compressed(VkFormat format)
166 {
167 return util_format_is_compressed(vk_format_to_pipe_format(format));
168 }
169
170 static inline const struct util_format_description *
vk_format_description(VkFormat format)171 vk_format_description(VkFormat format)
172 {
173 return util_format_description(vk_format_to_pipe_format(format));
174 }
175
176 static inline unsigned
vk_format_get_component_bits(VkFormat format,enum util_format_colorspace colorspace,unsigned component)177 vk_format_get_component_bits(VkFormat format, enum util_format_colorspace colorspace,
178 unsigned component)
179 {
180 return util_format_get_component_bits(vk_format_to_pipe_format(format),
181 colorspace,
182 component);
183 }
184
185 static inline unsigned
vk_format_get_nr_components(VkFormat format)186 vk_format_get_nr_components(VkFormat format)
187 {
188 return util_format_get_nr_components(vk_format_to_pipe_format(format));
189 }
190
191 static inline bool
vk_format_has_alpha(VkFormat format)192 vk_format_has_alpha(VkFormat format)
193 {
194 return util_format_has_alpha(vk_format_to_pipe_format(format));
195 }
196
197 static inline unsigned
vk_format_get_blocksizebits(VkFormat format)198 vk_format_get_blocksizebits(VkFormat format)
199 {
200 return util_format_get_blocksizebits(vk_format_to_pipe_format(format));
201 }
202
203 VkFormat
204 vk_format_get_plane_format(VkFormat format, unsigned plane_id);
205
206 VkFormat
207 vk_format_get_aspect_format(VkFormat format, const VkImageAspectFlags aspect);
208
209 struct vk_format_ycbcr_plane {
210 /* RGBA format for this plane */
211 VkFormat format;
212
213 /* Whether this plane contains chroma channels */
214 bool has_chroma;
215
216 /* For downscaling of YUV planes */
217 uint8_t denominator_scales[2];
218
219 /* How to map sampled ycbcr planes to a single 4 component element.
220 *
221 * We use uint8_t for compactness but it's actually VkComponentSwizzle.
222 */
223 uint8_t ycbcr_swizzle[4];
224 };
225
226 struct vk_format_ycbcr_info {
227 uint8_t n_planes;
228 struct vk_format_ycbcr_plane planes[3];
229 };
230
231 const struct vk_format_ycbcr_info *vk_format_get_ycbcr_info(VkFormat format);
232
233 static inline unsigned
vk_format_get_plane_count(VkFormat format)234 vk_format_get_plane_count(VkFormat format)
235 {
236 const struct vk_format_ycbcr_info *ycbcr_info =
237 vk_format_get_ycbcr_info(format);
238 return ycbcr_info ? ycbcr_info->n_planes : 1;
239 }
240
241 VkClearColorValue
242 vk_swizzle_color_value(VkClearColorValue color,
243 VkComponentMapping swizzle, bool is_int);
244
245 #ifdef __cplusplus
246 }
247 #endif
248
249 #endif
250