radv: trivial tidy ups
[mesa.git] / src / amd / vulkan / vk_format.h
1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * Based on u_format.h which is:
6 * Copyright 2009-2010 Vmware, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * IN THE SOFTWARE.
25 */
26
27 #pragma once
28
29 #include <assert.h>
30 #include <vulkan/vulkan.h>
31 #include <util/macros.h>
32
33 enum vk_format_layout {
34 /**
35 * Formats with vk_format_block::width == vk_format_block::height == 1
36 * that can be described as an ordinary data structure.
37 */
38 VK_FORMAT_LAYOUT_PLAIN = 0,
39
40 /**
41 * Formats with sub-sampled channels.
42 *
43 * This is for formats like YVYU where there is less than one sample per
44 * pixel.
45 */
46 VK_FORMAT_LAYOUT_SUBSAMPLED = 3,
47
48 /**
49 * S3 Texture Compression formats.
50 */
51 VK_FORMAT_LAYOUT_S3TC = 4,
52
53 /**
54 * Red-Green Texture Compression formats.
55 */
56 VK_FORMAT_LAYOUT_RGTC = 5,
57
58 /**
59 * Ericsson Texture Compression
60 */
61 VK_FORMAT_LAYOUT_ETC = 6,
62
63 /**
64 * BC6/7 Texture Compression
65 */
66 VK_FORMAT_LAYOUT_BPTC = 7,
67
68 /**
69 * ASTC
70 */
71 VK_FORMAT_LAYOUT_ASTC = 8,
72
73 /**
74 * Everything else that doesn't fit in any of the above layouts.
75 */
76 VK_FORMAT_LAYOUT_OTHER = 9
77 };
78
79 struct vk_format_block
80 {
81 /** Block width in pixels */
82 unsigned width;
83
84 /** Block height in pixels */
85 unsigned height;
86
87 /** Block size in bits */
88 unsigned bits;
89 };
90
91 enum vk_format_type {
92 VK_FORMAT_TYPE_VOID = 0,
93 VK_FORMAT_TYPE_UNSIGNED = 1,
94 VK_FORMAT_TYPE_SIGNED = 2,
95 VK_FORMAT_TYPE_FIXED = 3,
96 VK_FORMAT_TYPE_FLOAT = 4
97 };
98
99
100 enum vk_format_colorspace {
101 VK_FORMAT_COLORSPACE_RGB = 0,
102 VK_FORMAT_COLORSPACE_SRGB = 1,
103 VK_FORMAT_COLORSPACE_YUV = 2,
104 VK_FORMAT_COLORSPACE_ZS = 3
105 };
106
107 struct vk_format_channel_description {
108 unsigned type:5;
109 unsigned normalized:1;
110 unsigned pure_integer:1;
111 unsigned scaled:1;
112 unsigned size:8;
113 unsigned shift:16;
114 };
115
116 struct vk_format_description
117 {
118 VkFormat format;
119 const char *name;
120 const char *short_name;
121
122 struct vk_format_block block;
123 enum vk_format_layout layout;
124
125 unsigned nr_channels:3;
126 unsigned is_array:1;
127 unsigned is_bitmask:1;
128 unsigned is_mixed:1;
129
130 struct vk_format_channel_description channel[4];
131
132 unsigned char swizzle[4];
133
134 enum vk_format_colorspace colorspace;
135 };
136
137 extern const struct vk_format_description vk_format_description_table[];
138
139 const struct vk_format_description *vk_format_description(VkFormat format);
140
141 /**
142 * Return total bits needed for the pixel format per block.
143 */
144 static inline unsigned
145 vk_format_get_blocksizebits(VkFormat format)
146 {
147 const struct vk_format_description *desc = vk_format_description(format);
148
149 assert(desc);
150 if (!desc) {
151 return 0;
152 }
153
154 return desc->block.bits;
155 }
156
157 /**
158 * Return bytes per block (not pixel) for the given format.
159 */
160 static inline unsigned
161 vk_format_get_blocksize(VkFormat format)
162 {
163 unsigned bits = vk_format_get_blocksizebits(format);
164 unsigned bytes = bits / 8;
165
166 assert(bits % 8 == 0);
167 assert(bytes > 0);
168 if (bytes == 0) {
169 bytes = 1;
170 }
171
172 return bytes;
173 }
174
175 static inline unsigned
176 vk_format_get_blockwidth(VkFormat format)
177 {
178 const struct vk_format_description *desc = vk_format_description(format);
179
180 assert(desc);
181 if (!desc) {
182 return 1;
183 }
184
185 return desc->block.width;
186 }
187
188 static inline unsigned
189 vk_format_get_blockheight(VkFormat format)
190 {
191 const struct vk_format_description *desc = vk_format_description(format);
192
193 assert(desc);
194 if (!desc) {
195 return 1;
196 }
197
198 return desc->block.height;
199 }
200
201 /**
202 * Return the index of the first non-void channel
203 * -1 if no non-void channels
204 */
205 static inline int
206 vk_format_get_first_non_void_channel(VkFormat format)
207 {
208 const struct vk_format_description *desc = vk_format_description(format);
209 int i;
210
211 for (i = 0; i < 4; i++)
212 if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
213 break;
214
215 if (i == 4)
216 return -1;
217
218 return i;
219 }
220
221 enum vk_swizzle {
222 VK_SWIZZLE_X,
223 VK_SWIZZLE_Y,
224 VK_SWIZZLE_Z,
225 VK_SWIZZLE_W,
226 VK_SWIZZLE_0,
227 VK_SWIZZLE_1,
228 VK_SWIZZLE_NONE,
229 VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */
230 };
231
232 static inline VkImageAspectFlags
233 vk_format_aspects(VkFormat format)
234 {
235 switch (format) {
236 case VK_FORMAT_UNDEFINED:
237 return 0;
238
239 case VK_FORMAT_S8_UINT:
240 return VK_IMAGE_ASPECT_STENCIL_BIT;
241
242 case VK_FORMAT_D16_UNORM_S8_UINT:
243 case VK_FORMAT_D24_UNORM_S8_UINT:
244 case VK_FORMAT_D32_SFLOAT_S8_UINT:
245 return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
246
247 case VK_FORMAT_D16_UNORM:
248 case VK_FORMAT_X8_D24_UNORM_PACK32:
249 case VK_FORMAT_D32_SFLOAT:
250 return VK_IMAGE_ASPECT_DEPTH_BIT;
251
252 default:
253 return VK_IMAGE_ASPECT_COLOR_BIT;
254 }
255 }
256
257 static inline enum vk_swizzle
258 radv_swizzle_conv(VkComponentSwizzle component, const unsigned char chan[4], VkComponentSwizzle vk_swiz)
259 {
260 int x;
261
262 if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY)
263 vk_swiz = component;
264 switch (vk_swiz) {
265 case VK_COMPONENT_SWIZZLE_ZERO:
266 return VK_SWIZZLE_0;
267 case VK_COMPONENT_SWIZZLE_ONE:
268 return VK_SWIZZLE_1;
269 case VK_COMPONENT_SWIZZLE_R:
270 for (x = 0; x < 4; x++)
271 if (chan[x] == 0)
272 return x;
273 return VK_SWIZZLE_0;
274 case VK_COMPONENT_SWIZZLE_G:
275 for (x = 0; x < 4; x++)
276 if (chan[x] == 1)
277 return x;
278 return VK_SWIZZLE_0;
279 case VK_COMPONENT_SWIZZLE_B:
280 for (x = 0; x < 4; x++)
281 if (chan[x] == 2)
282 return x;
283 return VK_SWIZZLE_0;
284 case VK_COMPONENT_SWIZZLE_A:
285 for (x = 0; x < 4; x++)
286 if (chan[x] == 3)
287 return x;
288 return VK_SWIZZLE_1;
289 default:
290 unreachable("Illegal swizzle");
291 }
292 }
293
294 static inline void vk_format_compose_swizzles(const VkComponentMapping *mapping,
295 const unsigned char swz[4],
296 enum vk_swizzle dst[4])
297 {
298 dst[0] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_R, swz, mapping->r);
299 dst[1] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_G, swz, mapping->g);
300 dst[2] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_B, swz, mapping->b);
301 dst[3] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_A, swz, mapping->a);
302 }
303
304 static inline bool
305 vk_format_is_compressed(VkFormat format)
306 {
307 const struct vk_format_description *desc = vk_format_description(format);
308
309 assert(desc);
310 if (!desc) {
311 return false;
312 }
313
314 switch (desc->layout) {
315 case VK_FORMAT_LAYOUT_S3TC:
316 case VK_FORMAT_LAYOUT_RGTC:
317 case VK_FORMAT_LAYOUT_ETC:
318 case VK_FORMAT_LAYOUT_BPTC:
319 case VK_FORMAT_LAYOUT_ASTC:
320 /* XXX add other formats in the future */
321 return true;
322 default:
323 return false;
324 }
325 }
326
327 static inline bool
328 vk_format_has_depth(const struct vk_format_description *desc)
329 {
330 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
331 desc->swizzle[0] != VK_SWIZZLE_NONE;
332 }
333
334 static inline bool
335 vk_format_has_stencil(const struct vk_format_description *desc)
336 {
337 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
338 desc->swizzle[1] != VK_SWIZZLE_NONE;
339 }
340
341 static inline bool
342 vk_format_is_depth_or_stencil(VkFormat format)
343 {
344 const struct vk_format_description *desc = vk_format_description(format);
345
346 assert(desc);
347 if (!desc) {
348 return false;
349 }
350
351 return vk_format_has_depth(desc) ||
352 vk_format_has_stencil(desc);
353 }
354
355 static inline bool
356 vk_format_is_depth(VkFormat format)
357 {
358 const struct vk_format_description *desc = vk_format_description(format);
359
360 assert(desc);
361 if (!desc) {
362 return false;
363 }
364
365 return vk_format_has_depth(desc);
366 }
367
368 static inline bool
369 vk_format_is_color(VkFormat format)
370 {
371 return !vk_format_is_depth_or_stencil(format);
372 }
373
374 static inline VkFormat
375 vk_format_depth_only(VkFormat format)
376 {
377 switch (format) {
378 case VK_FORMAT_D16_UNORM_S8_UINT:
379 return VK_FORMAT_D16_UNORM;
380 case VK_FORMAT_D24_UNORM_S8_UINT:
381 return VK_FORMAT_X8_D24_UNORM_PACK32;
382 case VK_FORMAT_D32_SFLOAT_S8_UINT:
383 return VK_FORMAT_D32_SFLOAT;
384 default:
385 return format;
386 }
387 }
388
389 static inline bool
390 vk_format_is_int(VkFormat format)
391 {
392 const struct vk_format_description *desc = vk_format_description(format);
393 int channel = vk_format_get_first_non_void_channel(format);
394
395 return channel >= 0 && desc->channel[channel].pure_integer;
396 }
397
398 static inline VkFormat
399 vk_format_stencil_only(VkFormat format)
400 {
401 return VK_FORMAT_S8_UINT;
402 }
403
404 static inline unsigned
405 vk_format_get_component_bits(VkFormat format,
406 enum vk_format_colorspace colorspace,
407 unsigned component)
408 {
409 const struct vk_format_description *desc = vk_format_description(format);
410 enum vk_format_colorspace desc_colorspace;
411
412 assert(format);
413 if (!format) {
414 return 0;
415 }
416
417 assert(component < 4);
418
419 /* Treat RGB and SRGB as equivalent. */
420 if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
421 colorspace = VK_FORMAT_COLORSPACE_RGB;
422 }
423 if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
424 desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
425 } else {
426 desc_colorspace = desc->colorspace;
427 }
428
429 if (desc_colorspace != colorspace) {
430 return 0;
431 }
432
433 switch (desc->swizzle[component]) {
434 case VK_SWIZZLE_X:
435 return desc->channel[0].size;
436 case VK_SWIZZLE_Y:
437 return desc->channel[1].size;
438 case VK_SWIZZLE_Z:
439 return desc->channel[2].size;
440 case VK_SWIZZLE_W:
441 return desc->channel[3].size;
442 default:
443 return 0;
444 }
445 }