turnip: add format_is_uint/format_is_sint
[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 bool
418 vk_format_has_alpha(VkFormat format)
419 {
420 const struct vk_format_description *desc = vk_format_description(format);
421
422 return (desc->colorspace == VK_FORMAT_COLORSPACE_RGB ||
423 desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) &&
424 desc->swizzle[3] != VK_SWIZZLE_1;
425 }
426
427 static inline VkFormat
428 vk_format_depth_only(VkFormat format)
429 {
430 switch (format) {
431 case VK_FORMAT_D16_UNORM_S8_UINT:
432 return VK_FORMAT_D16_UNORM;
433 case VK_FORMAT_D24_UNORM_S8_UINT:
434 return VK_FORMAT_X8_D24_UNORM_PACK32;
435 case VK_FORMAT_D32_SFLOAT_S8_UINT:
436 return VK_FORMAT_D32_SFLOAT;
437 default:
438 return format;
439 }
440 }
441
442 static inline bool
443 vk_format_is_int(VkFormat format)
444 {
445 const struct vk_format_description *desc = vk_format_description(format);
446 int channel = vk_format_get_first_non_void_channel(format);
447
448 return channel >= 0 && desc->channel[channel].pure_integer;
449 }
450
451 static inline bool
452 vk_format_is_uint(VkFormat format)
453 {
454 const struct vk_format_description *desc = vk_format_description(format);
455 int channel = vk_format_get_first_non_void_channel(format);
456
457 return channel >= 0 &&
458 desc->channel[channel].pure_integer &&
459 desc->channel[channel].type != VK_FORMAT_TYPE_SIGNED;
460 }
461
462 static inline bool
463 vk_format_is_sint(VkFormat format)
464 {
465 const struct vk_format_description *desc = vk_format_description(format);
466 int channel = vk_format_get_first_non_void_channel(format);
467
468 return channel >= 0 &&
469 desc->channel[channel].pure_integer &&
470 desc->channel[channel].type == VK_FORMAT_TYPE_SIGNED;
471 }
472
473 static inline bool
474 vk_format_is_srgb(VkFormat format)
475 {
476 const struct vk_format_description *desc = vk_format_description(format);
477 return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
478 }
479
480 static inline VkFormat
481 vk_format_no_srgb(VkFormat format)
482 {
483 switch (format) {
484 case VK_FORMAT_R8_SRGB:
485 return VK_FORMAT_R8_UNORM;
486 case VK_FORMAT_R8G8_SRGB:
487 return VK_FORMAT_R8G8_UNORM;
488 case VK_FORMAT_R8G8B8_SRGB:
489 return VK_FORMAT_R8G8B8_UNORM;
490 case VK_FORMAT_B8G8R8_SRGB:
491 return VK_FORMAT_B8G8R8_UNORM;
492 case VK_FORMAT_R8G8B8A8_SRGB:
493 return VK_FORMAT_R8G8B8A8_UNORM;
494 case VK_FORMAT_B8G8R8A8_SRGB:
495 return VK_FORMAT_B8G8R8A8_UNORM;
496 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
497 return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
498 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
499 return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
500 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
501 return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
502 case VK_FORMAT_BC2_SRGB_BLOCK:
503 return VK_FORMAT_BC2_UNORM_BLOCK;
504 case VK_FORMAT_BC3_SRGB_BLOCK:
505 return VK_FORMAT_BC3_UNORM_BLOCK;
506 case VK_FORMAT_BC7_SRGB_BLOCK:
507 return VK_FORMAT_BC7_UNORM_BLOCK;
508 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
509 return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
510 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
511 return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
512 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
513 return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
514 default:
515 assert(!vk_format_is_srgb(format));
516 return format;
517 }
518 }
519
520 static inline VkFormat
521 vk_format_stencil_only(VkFormat format)
522 {
523 return VK_FORMAT_S8_UINT;
524 }
525
526 static inline unsigned
527 vk_format_get_component_bits(VkFormat format,
528 enum vk_format_colorspace colorspace,
529 unsigned component)
530 {
531 const struct vk_format_description *desc = vk_format_description(format);
532 enum vk_format_colorspace desc_colorspace;
533
534 assert(format);
535 if (!format) {
536 return 0;
537 }
538
539 assert(component < 4);
540
541 /* Treat RGB and SRGB as equivalent. */
542 if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
543 colorspace = VK_FORMAT_COLORSPACE_RGB;
544 }
545 if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
546 desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
547 } else {
548 desc_colorspace = desc->colorspace;
549 }
550
551 if (desc_colorspace != colorspace) {
552 return 0;
553 }
554
555 switch (desc->swizzle[component]) {
556 case VK_SWIZZLE_X:
557 return desc->channel[0].size;
558 case VK_SWIZZLE_Y:
559 return desc->channel[1].size;
560 case VK_SWIZZLE_Z:
561 return desc->channel[2].size;
562 case VK_SWIZZLE_W:
563 return desc->channel[3].size;
564 default:
565 return 0;
566 }
567 }
568
569 static inline VkFormat
570 vk_to_non_srgb_format(VkFormat format)
571 {
572 switch (format) {
573 case VK_FORMAT_R8_SRGB:
574 return VK_FORMAT_R8_UNORM;
575 case VK_FORMAT_R8G8_SRGB:
576 return VK_FORMAT_R8G8_UNORM;
577 case VK_FORMAT_R8G8B8_SRGB:
578 return VK_FORMAT_R8G8B8_UNORM;
579 case VK_FORMAT_B8G8R8_SRGB:
580 return VK_FORMAT_B8G8R8_UNORM;
581 case VK_FORMAT_R8G8B8A8_SRGB:
582 return VK_FORMAT_R8G8B8A8_UNORM;
583 case VK_FORMAT_B8G8R8A8_SRGB:
584 return VK_FORMAT_B8G8R8A8_UNORM;
585 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
586 return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
587 default:
588 return format;
589 }
590 }
591
592 static inline unsigned
593 vk_format_get_nr_components(VkFormat format)
594 {
595 const struct vk_format_description *desc = vk_format_description(format);
596 return desc->nr_channels;
597 }
598
599 #endif /* VK_FORMAT_H */