turnip: add .clang-format
[mesa.git] / src / freedreno / 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
24 * DEALINGS IN THE SOFTWARE.
25 */
26
27 #ifndef VK_FORMAT_H
28 #define VK_FORMAT_H
29
30 #include <assert.h>
31 #include <util/macros.h>
32
33 #include <vulkan/vulkan.h>
34
35 enum vk_format_layout
36 {
37 /**
38 * Formats with vk_format_block::width == vk_format_block::height == 1
39 * that can be described as an ordinary data structure.
40 */
41 VK_FORMAT_LAYOUT_PLAIN = 0,
42
43 /**
44 * Formats with sub-sampled channels.
45 *
46 * This is for formats like YVYU where there is less than one sample per
47 * pixel.
48 */
49 VK_FORMAT_LAYOUT_SUBSAMPLED = 3,
50
51 /**
52 * S3 Texture Compression formats.
53 */
54 VK_FORMAT_LAYOUT_S3TC = 4,
55
56 /**
57 * Red-Green Texture Compression formats.
58 */
59 VK_FORMAT_LAYOUT_RGTC = 5,
60
61 /**
62 * Ericsson Texture Compression
63 */
64 VK_FORMAT_LAYOUT_ETC = 6,
65
66 /**
67 * BC6/7 Texture Compression
68 */
69 VK_FORMAT_LAYOUT_BPTC = 7,
70
71 /**
72 * ASTC
73 */
74 VK_FORMAT_LAYOUT_ASTC = 8,
75
76 /**
77 * Everything else that doesn't fit in any of the above layouts.
78 */
79 VK_FORMAT_LAYOUT_OTHER = 9
80 };
81
82 struct vk_format_block
83 {
84 /** Block width in pixels */
85 unsigned width;
86
87 /** Block height in pixels */
88 unsigned height;
89
90 /** Block size in bits */
91 unsigned bits;
92 };
93
94 enum vk_format_type
95 {
96 VK_FORMAT_TYPE_VOID = 0,
97 VK_FORMAT_TYPE_UNSIGNED = 1,
98 VK_FORMAT_TYPE_SIGNED = 2,
99 VK_FORMAT_TYPE_FIXED = 3,
100 VK_FORMAT_TYPE_FLOAT = 4
101 };
102
103 enum vk_format_colorspace
104 {
105 VK_FORMAT_COLORSPACE_RGB = 0,
106 VK_FORMAT_COLORSPACE_SRGB = 1,
107 VK_FORMAT_COLORSPACE_YUV = 2,
108 VK_FORMAT_COLORSPACE_ZS = 3
109 };
110
111 struct vk_format_channel_description
112 {
113 unsigned type : 5;
114 unsigned normalized : 1;
115 unsigned pure_integer : 1;
116 unsigned scaled : 1;
117 unsigned size : 8;
118 unsigned shift : 16;
119 };
120
121 struct vk_format_description
122 {
123 VkFormat format;
124 const char *name;
125 const char *short_name;
126
127 struct vk_format_block block;
128 enum vk_format_layout layout;
129
130 unsigned nr_channels : 3;
131 unsigned is_array : 1;
132 unsigned is_bitmask : 1;
133 unsigned is_mixed : 1;
134
135 struct vk_format_channel_description channel[4];
136
137 unsigned char swizzle[4];
138
139 enum vk_format_colorspace colorspace;
140 };
141
142 extern const struct vk_format_description vk_format_description_table[];
143
144 const struct vk_format_description *
145 vk_format_description(VkFormat format);
146
147 /**
148 * Return total bits needed for the pixel format per block.
149 */
150 static inline unsigned
151 vk_format_get_blocksizebits(VkFormat format)
152 {
153 const struct vk_format_description *desc = vk_format_description(format);
154
155 assert(desc);
156 if (!desc) {
157 return 0;
158 }
159
160 return desc->block.bits;
161 }
162
163 /**
164 * Return bytes per block (not pixel) for the given format.
165 */
166 static inline unsigned
167 vk_format_get_blocksize(VkFormat format)
168 {
169 unsigned bits = vk_format_get_blocksizebits(format);
170 unsigned bytes = bits / 8;
171
172 assert(bits % 8 == 0);
173 assert(bytes > 0);
174 if (bytes == 0) {
175 bytes = 1;
176 }
177
178 return bytes;
179 }
180
181 static inline unsigned
182 vk_format_get_blockwidth(VkFormat format)
183 {
184 const struct vk_format_description *desc = vk_format_description(format);
185
186 assert(desc);
187 if (!desc) {
188 return 1;
189 }
190
191 return desc->block.width;
192 }
193
194 static inline unsigned
195 vk_format_get_blockheight(VkFormat format)
196 {
197 const struct vk_format_description *desc = vk_format_description(format);
198
199 assert(desc);
200 if (!desc) {
201 return 1;
202 }
203
204 return desc->block.height;
205 }
206
207 static inline unsigned
208 vk_format_get_block_count_width(VkFormat format, unsigned width)
209 {
210 unsigned blockwidth = vk_format_get_blockwidth(format);
211 return (width + blockwidth - 1) / blockwidth;
212 }
213
214 static inline unsigned
215 vk_format_get_block_count_height(VkFormat format, unsigned height)
216 {
217 unsigned blockheight = vk_format_get_blockheight(format);
218 return (height + blockheight - 1) / blockheight;
219 }
220
221 static inline unsigned
222 vk_format_get_block_count(VkFormat format, unsigned width, unsigned height)
223 {
224 return vk_format_get_block_count_width(format, width) *
225 vk_format_get_block_count_height(format, height);
226 }
227
228 /**
229 * Return the index of the first non-void channel
230 * -1 if no non-void channels
231 */
232 static inline int
233 vk_format_get_first_non_void_channel(VkFormat format)
234 {
235 const struct vk_format_description *desc = vk_format_description(format);
236 int i;
237
238 for (i = 0; i < 4; i++)
239 if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
240 break;
241
242 if (i == 4)
243 return -1;
244
245 return i;
246 }
247
248 enum vk_swizzle
249 {
250 VK_SWIZZLE_X,
251 VK_SWIZZLE_Y,
252 VK_SWIZZLE_Z,
253 VK_SWIZZLE_W,
254 VK_SWIZZLE_0,
255 VK_SWIZZLE_1,
256 VK_SWIZZLE_NONE,
257 VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */
258 };
259
260 static inline VkImageAspectFlags
261 vk_format_aspects(VkFormat format)
262 {
263 switch (format) {
264 case VK_FORMAT_UNDEFINED:
265 return 0;
266
267 case VK_FORMAT_S8_UINT:
268 return VK_IMAGE_ASPECT_STENCIL_BIT;
269
270 case VK_FORMAT_D16_UNORM_S8_UINT:
271 case VK_FORMAT_D24_UNORM_S8_UINT:
272 case VK_FORMAT_D32_SFLOAT_S8_UINT:
273 return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
274
275 case VK_FORMAT_D16_UNORM:
276 case VK_FORMAT_X8_D24_UNORM_PACK32:
277 case VK_FORMAT_D32_SFLOAT:
278 return VK_IMAGE_ASPECT_DEPTH_BIT;
279
280 default:
281 return VK_IMAGE_ASPECT_COLOR_BIT;
282 }
283 }
284
285 static inline enum vk_swizzle
286 tu_swizzle_conv(VkComponentSwizzle component,
287 const unsigned char chan[4],
288 VkComponentSwizzle vk_swiz)
289 {
290 int x;
291
292 if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY)
293 vk_swiz = component;
294 switch (vk_swiz) {
295 case VK_COMPONENT_SWIZZLE_ZERO:
296 return VK_SWIZZLE_0;
297 case VK_COMPONENT_SWIZZLE_ONE:
298 return VK_SWIZZLE_1;
299 case VK_COMPONENT_SWIZZLE_R:
300 for (x = 0; x < 4; x++)
301 if (chan[x] == 0)
302 return x;
303 return VK_SWIZZLE_0;
304 case VK_COMPONENT_SWIZZLE_G:
305 for (x = 0; x < 4; x++)
306 if (chan[x] == 1)
307 return x;
308 return VK_SWIZZLE_0;
309 case VK_COMPONENT_SWIZZLE_B:
310 for (x = 0; x < 4; x++)
311 if (chan[x] == 2)
312 return x;
313 return VK_SWIZZLE_0;
314 case VK_COMPONENT_SWIZZLE_A:
315 for (x = 0; x < 4; x++)
316 if (chan[x] == 3)
317 return x;
318 return VK_SWIZZLE_1;
319 default:
320 unreachable("Illegal swizzle");
321 }
322 }
323
324 static inline void
325 vk_format_compose_swizzles(const VkComponentMapping *mapping,
326 const unsigned char swz[4],
327 enum vk_swizzle dst[4])
328 {
329 dst[0] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_R, swz, mapping->r);
330 dst[1] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_G, swz, mapping->g);
331 dst[2] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_B, swz, mapping->b);
332 dst[3] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_A, swz, mapping->a);
333 }
334
335 static inline bool
336 vk_format_is_compressed(VkFormat format)
337 {
338 const struct vk_format_description *desc = vk_format_description(format);
339
340 assert(desc);
341 if (!desc) {
342 return false;
343 }
344
345 switch (desc->layout) {
346 case VK_FORMAT_LAYOUT_S3TC:
347 case VK_FORMAT_LAYOUT_RGTC:
348 case VK_FORMAT_LAYOUT_ETC:
349 case VK_FORMAT_LAYOUT_BPTC:
350 case VK_FORMAT_LAYOUT_ASTC:
351 /* XXX add other formats in the future */
352 return true;
353 default:
354 return false;
355 }
356 }
357
358 static inline bool
359 vk_format_has_depth(const struct vk_format_description *desc)
360 {
361 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
362 desc->swizzle[0] != VK_SWIZZLE_NONE;
363 }
364
365 static inline bool
366 vk_format_has_stencil(const struct vk_format_description *desc)
367 {
368 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
369 desc->swizzle[1] != VK_SWIZZLE_NONE;
370 }
371
372 static inline bool
373 vk_format_is_depth_or_stencil(VkFormat format)
374 {
375 const struct vk_format_description *desc = vk_format_description(format);
376
377 assert(desc);
378 if (!desc) {
379 return false;
380 }
381
382 return vk_format_has_depth(desc) || vk_format_has_stencil(desc);
383 }
384
385 static inline bool
386 vk_format_is_depth(VkFormat format)
387 {
388 const struct vk_format_description *desc = vk_format_description(format);
389
390 assert(desc);
391 if (!desc) {
392 return false;
393 }
394
395 return vk_format_has_depth(desc);
396 }
397
398 static inline bool
399 vk_format_is_stencil(VkFormat format)
400 {
401 const struct vk_format_description *desc = vk_format_description(format);
402
403 assert(desc);
404 if (!desc) {
405 return false;
406 }
407
408 return vk_format_has_stencil(desc);
409 }
410
411 static inline bool
412 vk_format_is_color(VkFormat format)
413 {
414 return !vk_format_is_depth_or_stencil(format);
415 }
416
417 static inline VkFormat
418 vk_format_depth_only(VkFormat format)
419 {
420 switch (format) {
421 case VK_FORMAT_D16_UNORM_S8_UINT:
422 return VK_FORMAT_D16_UNORM;
423 case VK_FORMAT_D24_UNORM_S8_UINT:
424 return VK_FORMAT_X8_D24_UNORM_PACK32;
425 case VK_FORMAT_D32_SFLOAT_S8_UINT:
426 return VK_FORMAT_D32_SFLOAT;
427 default:
428 return format;
429 }
430 }
431
432 static inline bool
433 vk_format_is_int(VkFormat format)
434 {
435 const struct vk_format_description *desc = vk_format_description(format);
436 int channel = vk_format_get_first_non_void_channel(format);
437
438 return channel >= 0 && desc->channel[channel].pure_integer;
439 }
440
441 static inline bool
442 vk_format_is_srgb(VkFormat format)
443 {
444 const struct vk_format_description *desc = vk_format_description(format);
445 return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
446 }
447
448 static inline VkFormat
449 vk_format_no_srgb(VkFormat format)
450 {
451 switch (format) {
452 case VK_FORMAT_R8_SRGB:
453 return VK_FORMAT_R8_UNORM;
454 case VK_FORMAT_R8G8_SRGB:
455 return VK_FORMAT_R8G8_UNORM;
456 case VK_FORMAT_R8G8B8_SRGB:
457 return VK_FORMAT_R8G8B8_UNORM;
458 case VK_FORMAT_B8G8R8_SRGB:
459 return VK_FORMAT_B8G8R8_UNORM;
460 case VK_FORMAT_R8G8B8A8_SRGB:
461 return VK_FORMAT_R8G8B8A8_UNORM;
462 case VK_FORMAT_B8G8R8A8_SRGB:
463 return VK_FORMAT_B8G8R8A8_UNORM;
464 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
465 return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
466 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
467 return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
468 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
469 return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
470 case VK_FORMAT_BC2_SRGB_BLOCK:
471 return VK_FORMAT_BC2_UNORM_BLOCK;
472 case VK_FORMAT_BC3_SRGB_BLOCK:
473 return VK_FORMAT_BC3_UNORM_BLOCK;
474 case VK_FORMAT_BC7_SRGB_BLOCK:
475 return VK_FORMAT_BC7_UNORM_BLOCK;
476 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
477 return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
478 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
479 return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
480 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
481 return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
482 default:
483 assert(!vk_format_is_srgb(format));
484 return format;
485 }
486 }
487
488 static inline VkFormat
489 vk_format_stencil_only(VkFormat format)
490 {
491 return VK_FORMAT_S8_UINT;
492 }
493
494 static inline unsigned
495 vk_format_get_component_bits(VkFormat format,
496 enum vk_format_colorspace colorspace,
497 unsigned component)
498 {
499 const struct vk_format_description *desc = vk_format_description(format);
500 enum vk_format_colorspace desc_colorspace;
501
502 assert(format);
503 if (!format) {
504 return 0;
505 }
506
507 assert(component < 4);
508
509 /* Treat RGB and SRGB as equivalent. */
510 if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
511 colorspace = VK_FORMAT_COLORSPACE_RGB;
512 }
513 if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
514 desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
515 } else {
516 desc_colorspace = desc->colorspace;
517 }
518
519 if (desc_colorspace != colorspace) {
520 return 0;
521 }
522
523 switch (desc->swizzle[component]) {
524 case VK_SWIZZLE_X:
525 return desc->channel[0].size;
526 case VK_SWIZZLE_Y:
527 return desc->channel[1].size;
528 case VK_SWIZZLE_Z:
529 return desc->channel[2].size;
530 case VK_SWIZZLE_W:
531 return desc->channel[3].size;
532 default:
533 return 0;
534 }
535 }
536
537 static inline VkFormat
538 vk_to_non_srgb_format(VkFormat format)
539 {
540 switch (format) {
541 case VK_FORMAT_R8_SRGB:
542 return VK_FORMAT_R8_UNORM;
543 case VK_FORMAT_R8G8_SRGB:
544 return VK_FORMAT_R8G8_UNORM;
545 case VK_FORMAT_R8G8B8_SRGB:
546 return VK_FORMAT_R8G8B8_UNORM;
547 case VK_FORMAT_B8G8R8_SRGB:
548 return VK_FORMAT_B8G8R8_UNORM;
549 case VK_FORMAT_R8G8B8A8_SRGB:
550 return VK_FORMAT_R8G8B8A8_UNORM;
551 case VK_FORMAT_B8G8R8A8_SRGB:
552 return VK_FORMAT_B8G8R8A8_UNORM;
553 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
554 return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
555 default:
556 return format;
557 }
558 }
559
560 static inline unsigned
561 vk_format_get_nr_components(VkFormat format)
562 {
563 const struct vk_format_description *desc = vk_format_description(format);
564 return desc->nr_channels;
565 }
566
567 #endif /* VK_FORMAT_H */