1 /**************************************************************************
2 *
3 * Copyright 2009-2010 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #ifndef U_FORMAT_H
30 #define U_FORMAT_H
31
32
33 #include "util/format/u_formats.h"
34 #include "util/u_debug.h"
35
36 #include "c99_compat.h"
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42
43 /**
44 * Describe how to pack/unpack pixels into/from the prescribed format.
45 *
46 * XXX: This could be renamed to something like util_format_pack, or broke down
47 * in flags inside util_format_block that said exactly what we want.
48 */
49 enum util_format_layout {
50 /**
51 * Formats with util_format_block::width == util_format_block::height == 1
52 * that can be described as an ordinary data structure.
53 */
54 UTIL_FORMAT_LAYOUT_PLAIN,
55
56 /**
57 * Formats with sub-sampled channels.
58 *
59 * This is for formats like YVYU where there is less than one sample per
60 * pixel.
61 */
62 UTIL_FORMAT_LAYOUT_SUBSAMPLED,
63
64 /**
65 * S3 Texture Compression formats.
66 */
67 UTIL_FORMAT_LAYOUT_S3TC,
68
69 /**
70 * Red-Green Texture Compression formats.
71 */
72 UTIL_FORMAT_LAYOUT_RGTC,
73
74 /**
75 * Ericsson Texture Compression
76 */
77 UTIL_FORMAT_LAYOUT_ETC,
78
79 /**
80 * BC6/7 Texture Compression
81 */
82 UTIL_FORMAT_LAYOUT_BPTC,
83
84 UTIL_FORMAT_LAYOUT_ASTC,
85
86 UTIL_FORMAT_LAYOUT_ATC,
87
88 /** Formats with 2 or more planes. */
89 UTIL_FORMAT_LAYOUT_PLANAR2,
90 UTIL_FORMAT_LAYOUT_PLANAR3,
91
92 UTIL_FORMAT_LAYOUT_FXT1 = 10,
93
94 /**
95 * Everything else that doesn't fit in any of the above layouts.
96 */
97 UTIL_FORMAT_LAYOUT_OTHER,
98 };
99
100
101 struct util_format_block
102 {
103 /** Block width in pixels */
104 unsigned width;
105
106 /** Block height in pixels */
107 unsigned height;
108
109 /** Block depth in pixels */
110 unsigned depth;
111
112 /** Block size in bits */
113 unsigned bits;
114 };
115
116
117 enum util_format_type {
118 UTIL_FORMAT_TYPE_VOID = 0,
119 UTIL_FORMAT_TYPE_UNSIGNED = 1,
120 UTIL_FORMAT_TYPE_SIGNED = 2,
121 UTIL_FORMAT_TYPE_FIXED = 3,
122 UTIL_FORMAT_TYPE_FLOAT = 4
123 };
124
125
126 enum util_format_colorspace {
127 UTIL_FORMAT_COLORSPACE_RGB = 0,
128 UTIL_FORMAT_COLORSPACE_SRGB = 1,
129 UTIL_FORMAT_COLORSPACE_YUV = 2,
130 UTIL_FORMAT_COLORSPACE_ZS = 3
131 };
132
133
134 struct util_format_channel_description
135 {
136 unsigned type:5; /**< UTIL_FORMAT_TYPE_x */
137 unsigned normalized:1;
138 unsigned pure_integer:1;
139 unsigned size:9; /**< bits per channel */
140 unsigned shift:16; /** number of bits from lsb */
141 };
142
143
144 struct util_format_description
145 {
146 enum pipe_format format;
147
148 const char *name;
149
150 /**
151 * Short name, striped of the prefix, lower case.
152 */
153 const char *short_name;
154
155 /**
156 * Pixel block dimensions.
157 */
158 struct util_format_block block;
159
160 enum util_format_layout layout;
161
162 /**
163 * The number of channels.
164 */
165 unsigned nr_channels:3;
166
167 /**
168 * Whether all channels have the same number of (whole) bytes and type.
169 */
170 unsigned is_array:1;
171
172 /**
173 * Whether the pixel format can be described as a bitfield structure.
174 *
175 * In particular:
176 * - pixel depth must be 8, 16, or 32 bits;
177 * - all channels must be unsigned, signed, or void
178 */
179 unsigned is_bitmask:1;
180
181 /**
182 * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
183 */
184 unsigned is_mixed:1;
185
186 /**
187 * Whether the format contains UNORM channels
188 */
189 unsigned is_unorm:1;
190
191 /**
192 * Whether the format contains SNORM channels
193 */
194 unsigned is_snorm:1;
195
196 /**
197 * Input channel description, in the order XYZW.
198 *
199 * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
200 *
201 * If each channel is accessed as an individual N-byte value, X is always
202 * at the lowest address in memory, Y is always next, and so on. For all
203 * currently-defined formats, the N-byte value has native endianness.
204 *
205 * If instead a group of channels is accessed as a single N-byte value,
206 * the order of the channels within that value depends on endianness.
207 * For big-endian targets, X is the most significant subvalue,
208 * otherwise it is the least significant one.
209 *
210 * For example, if X is 8 bits and Y is 24 bits, the memory order is:
211 *
212 * 0 1 2 3
213 * little-endian: X Yl Ym Yu (l = lower, m = middle, u = upper)
214 * big-endian: X Yu Ym Yl
215 *
216 * If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is:
217 *
218 * 0 1
219 * msb lsb msb lsb
220 * little-endian: YYYXXXXX WZZZZZYY
221 * big-endian: XXXXXYYY YYZZZZZW
222 */
223 struct util_format_channel_description channel[4];
224
225 /**
226 * Output channel swizzle.
227 *
228 * The order is either:
229 * - RGBA
230 * - YUV(A)
231 * - ZS
232 * depending on the colorspace.
233 */
234 unsigned char swizzle[4];
235
236 /**
237 * Colorspace transformation.
238 */
239 enum util_format_colorspace colorspace;
240
241 /**
242 * For sRGB formats, equivalent linear format; for linear formats,
243 * equivalent sRGB format
244 */
245 union {
246 enum pipe_format srgb_equivalent;
247 enum pipe_format linear_equivalent;
248 };
249 };
250
251 struct util_format_pack_description {
252 /**
253 * Pack pixel blocks from R8G8B8A8_UNORM.
254 * Note: strides are in bytes.
255 *
256 * Only defined for non-depth-stencil formats.
257 */
258 void
259 (*pack_rgba_8unorm)(uint8_t *restrict dst, unsigned dst_stride,
260 const uint8_t *restrict src, unsigned src_stride,
261 unsigned width, unsigned height);
262
263 /**
264 * Pack pixel blocks from R32G32B32A32_FLOAT.
265 * Note: strides are in bytes.
266 *
267 * Only defined for non-depth-stencil formats.
268 */
269 void
270 (*pack_rgba_float)(uint8_t *restrict dst, unsigned dst_stride,
271 const float *restrict src, unsigned src_stride,
272 unsigned width, unsigned height);
273
274 /**
275 * Pack pixels from Z32_UNORM.
276 * Note: strides are in bytes.
277 *
278 * Only defined for depth formats.
279 */
280 void
281 (*pack_z_32unorm)(uint8_t *restrict dst, unsigned dst_stride,
282 const uint32_t *restrict src, unsigned src_stride,
283 unsigned width, unsigned height);
284
285 /**
286 * Pack pixels from Z32_FLOAT.
287 * Note: strides are in bytes.
288 *
289 * Only defined for depth formats.
290 */
291 void
292 (*pack_z_float)(uint8_t *restrict dst, unsigned dst_stride,
293 const float *restrict src, unsigned src_stride,
294 unsigned width, unsigned height);
295
296 /**
297 * Pack pixels from S8_UINT.
298 * Note: strides are in bytes.
299 *
300 * Only defined for stencil formats.
301 */
302 void
303 (*pack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,
304 const uint8_t *restrict src, unsigned src_stride,
305 unsigned width, unsigned height);
306
307 void
308 (*pack_rgba_uint)(uint8_t *restrict dst, unsigned dst_stride,
309 const uint32_t *restrict src, unsigned src_stride,
310 unsigned width, unsigned height);
311
312 void
313 (*pack_rgba_sint)(uint8_t *restrict dst, unsigned dst_stride,
314 const int32_t *restrict src, unsigned src_stride,
315 unsigned width, unsigned height);
316 };
317
318
319 struct util_format_unpack_description {
320 /**
321 * Unpack pixel blocks to R8G8B8A8_UNORM.
322 * Note: strides are in bytes.
323 *
324 * Only defined for non-block non-depth-stencil formats.
325 */
326 void
327 (*unpack_rgba_8unorm)(uint8_t *restrict dst, const uint8_t *restrict src,
328 unsigned width);
329
330 /**
331 * Unpack pixel blocks to R8G8B8A8_UNORM.
332 * Note: strides are in bytes.
333 *
334 * Only defined for block non-depth-stencil formats.
335 */
336 void
337 (*unpack_rgba_8unorm_rect)(uint8_t *restrict dst, unsigned dst_stride,
338 const uint8_t *restrict src, unsigned src_stride,
339 unsigned width, unsigned height);
340
341 /**
342 * Fetch a single pixel (i, j) from a block.
343 *
344 * XXX: Only defined for a very few select formats.
345 */
346 void
347 (*fetch_rgba_8unorm)(uint8_t *restrict dst,
348 const uint8_t *restrict src,
349 unsigned i, unsigned j);
350
351 /**
352 * Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the
353 * type is pure uint, int, or other.
354 *
355 * Note: strides are in bytes.
356 *
357 * Only defined for non-block non-depth-stencil formats.
358 */
359 void
360 (*unpack_rgba)(void *restrict dst, const uint8_t *restrict src,
361 unsigned width);
362
363 /**
364 * Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the
365 * type is pure uint, int, or other.
366 *
367 * Note: strides are in bytes.
368 *
369 * Only defined for block non-depth-stencil formats.
370 */
371 void
372 (*unpack_rgba_rect)(void *restrict dst, unsigned dst_stride,
373 const uint8_t *restrict src, unsigned src_stride,
374 unsigned width, unsigned height);
375
376 /**
377 * Unpack pixels to Z32_UNORM.
378 * Note: strides are in bytes.
379 *
380 * Only defined for depth formats.
381 */
382 void
383 (*unpack_z_32unorm)(uint32_t *restrict dst, unsigned dst_stride,
384 const uint8_t *restrict src, unsigned src_stride,
385 unsigned width, unsigned height);
386
387 /**
388 * Unpack pixels to Z32_FLOAT.
389 * Note: strides are in bytes.
390 *
391 * Only defined for depth formats.
392 */
393 void
394 (*unpack_z_float)(float *restrict dst, unsigned dst_stride,
395 const uint8_t *restrict src, unsigned src_stride,
396 unsigned width, unsigned height);
397
398 /**
399 * Unpack pixels to S8_UINT.
400 * Note: strides are in bytes.
401 *
402 * Only defined for stencil formats.
403 */
404 void
405 (*unpack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,
406 const uint8_t *restrict src, unsigned src_stride,
407 unsigned width, unsigned height);
408 };
409
410 typedef void (*util_format_fetch_rgba_func_ptr)(void *restrict dst, const uint8_t *restrict src,
411 unsigned i, unsigned j);
412
413 /* Silence warnings triggered by sharing function/struct names */
414 #ifdef __GNUC__
415 #pragma GCC diagnostic push
416 #pragma GCC diagnostic ignored "-Wshadow"
417 #endif
418 const struct util_format_description *
419 util_format_description(enum pipe_format format) ATTRIBUTE_CONST;
420
421 const struct util_format_pack_description *
422 util_format_pack_description(enum pipe_format format) ATTRIBUTE_CONST;
423
424 /* Lookup with CPU detection for choosing optimized paths. */
425 const struct util_format_unpack_description *
426 util_format_unpack_description(enum pipe_format format) ATTRIBUTE_CONST;
427
428 /* Codegenned table of CPU-agnostic unpack code. */
429 const struct util_format_unpack_description *
430 util_format_unpack_description_generic(enum pipe_format format) ATTRIBUTE_CONST;
431
432 const struct util_format_unpack_description *
433 util_format_unpack_description_neon(enum pipe_format format) ATTRIBUTE_CONST;
434
435 #ifdef __GNUC__
436 #pragma GCC diagnostic pop
437 #endif
438
439 /**
440 * Returns a function to fetch a single pixel (i, j) from a block.
441 *
442 * Only defined for non-depth-stencil and non-integer formats.
443 */
444 util_format_fetch_rgba_func_ptr
445 util_format_fetch_rgba_func(enum pipe_format format) ATTRIBUTE_CONST;
446
447 /*
448 * Format query functions.
449 */
450
451 static inline const char *
util_format_name(enum pipe_format format)452 util_format_name(enum pipe_format format)
453 {
454 const struct util_format_description *desc = util_format_description(format);
455
456 assert(desc);
457 if (!desc) {
458 return "PIPE_FORMAT_???";
459 }
460
461 return desc->name;
462 }
463
464 static inline const char *
util_format_short_name(enum pipe_format format)465 util_format_short_name(enum pipe_format format)
466 {
467 const struct util_format_description *desc = util_format_description(format);
468
469 assert(desc);
470 if (!desc) {
471 return "???";
472 }
473
474 return desc->short_name;
475 }
476
477 static inline const char *
util_chroma_format_name(enum pipe_video_chroma_format chroma_format)478 util_chroma_format_name(enum pipe_video_chroma_format chroma_format)
479 {
480 switch (chroma_format) {
481 case PIPE_VIDEO_CHROMA_FORMAT_400:
482 return "PIPE_VIDEO_CHROMA_FORMAT_400";
483 case PIPE_VIDEO_CHROMA_FORMAT_420:
484 return "PIPE_VIDEO_CHROMA_FORMAT_420";
485 case PIPE_VIDEO_CHROMA_FORMAT_422:
486 return "PIPE_VIDEO_CHROMA_FORMAT_422";
487 case PIPE_VIDEO_CHROMA_FORMAT_444:
488 return "PIPE_VIDEO_CHROMA_FORMAT_444";
489 case PIPE_VIDEO_CHROMA_FORMAT_NONE:
490 return "PIPE_VIDEO_CHROMA_FORMAT_NONE";
491 default:
492 return "PIPE_VIDEO_CHROMA_FORMAT_???";
493 }
494 }
495
496 /**
497 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
498 */
499 static inline bool
util_format_is_plain(enum pipe_format format)500 util_format_is_plain(enum pipe_format format)
501 {
502 const struct util_format_description *desc = util_format_description(format);
503
504 if (!format) {
505 return false;
506 }
507
508 return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? true : false;
509 }
510
511 static inline bool
util_format_is_compressed(enum pipe_format format)512 util_format_is_compressed(enum pipe_format format)
513 {
514 const struct util_format_description *desc = util_format_description(format);
515
516 assert(desc);
517 if (!desc) {
518 return false;
519 }
520
521 switch (desc->layout) {
522 case UTIL_FORMAT_LAYOUT_S3TC:
523 case UTIL_FORMAT_LAYOUT_RGTC:
524 case UTIL_FORMAT_LAYOUT_ETC:
525 case UTIL_FORMAT_LAYOUT_BPTC:
526 case UTIL_FORMAT_LAYOUT_ASTC:
527 case UTIL_FORMAT_LAYOUT_ATC:
528 case UTIL_FORMAT_LAYOUT_FXT1:
529 /* XXX add other formats in the future */
530 return true;
531 default:
532 return false;
533 }
534 }
535
536 static inline bool
util_format_is_s3tc(enum pipe_format format)537 util_format_is_s3tc(enum pipe_format format)
538 {
539 const struct util_format_description *desc = util_format_description(format);
540
541 assert(desc);
542 if (!desc) {
543 return false;
544 }
545
546 return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? true : false;
547 }
548
549 static inline bool
util_format_is_etc(enum pipe_format format)550 util_format_is_etc(enum pipe_format format)
551 {
552 const struct util_format_description *desc = util_format_description(format);
553
554 assert(desc);
555 if (!desc) {
556 return false;
557 }
558
559 return desc->layout == UTIL_FORMAT_LAYOUT_ETC ? true : false;
560 }
561
562 static inline bool
util_format_is_srgb(enum pipe_format format)563 util_format_is_srgb(enum pipe_format format)
564 {
565 const struct util_format_description *desc = util_format_description(format);
566
567 assert(desc);
568 if (!desc) {
569 return false;
570 }
571
572 return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
573 }
574
575 static inline bool
util_format_has_depth(const struct util_format_description * desc)576 util_format_has_depth(const struct util_format_description *desc)
577 {
578 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
579 desc->swizzle[0] != PIPE_SWIZZLE_NONE;
580 }
581
582 static inline bool
util_format_has_stencil(const struct util_format_description * desc)583 util_format_has_stencil(const struct util_format_description *desc)
584 {
585 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
586 desc->swizzle[1] != PIPE_SWIZZLE_NONE;
587 }
588
589 static inline bool
util_format_is_depth_or_stencil(enum pipe_format format)590 util_format_is_depth_or_stencil(enum pipe_format format)
591 {
592 const struct util_format_description *desc = util_format_description(format);
593
594 assert(desc);
595 if (!desc) {
596 return false;
597 }
598
599 return util_format_has_depth(desc) ||
600 util_format_has_stencil(desc);
601 }
602
603 static inline bool
util_format_is_depth_and_stencil(enum pipe_format format)604 util_format_is_depth_and_stencil(enum pipe_format format)
605 {
606 const struct util_format_description *desc = util_format_description(format);
607
608 assert(desc);
609 if (!desc) {
610 return false;
611 }
612
613 return util_format_has_depth(desc) &&
614 util_format_has_stencil(desc);
615 }
616
617 /**
618 * For depth-stencil formats, return the equivalent depth-only format.
619 */
620 static inline enum pipe_format
util_format_get_depth_only(enum pipe_format format)621 util_format_get_depth_only(enum pipe_format format)
622 {
623 switch (format) {
624 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
625 return PIPE_FORMAT_Z24X8_UNORM;
626
627 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
628 return PIPE_FORMAT_X8Z24_UNORM;
629
630 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
631 return PIPE_FORMAT_Z32_FLOAT;
632
633 default:
634 return format;
635 }
636 }
637
638 static inline bool
util_format_is_yuv(enum pipe_format format)639 util_format_is_yuv(enum pipe_format format)
640 {
641 const struct util_format_description *desc = util_format_description(format);
642
643 assert(desc);
644 if (!desc) {
645 return false;
646 }
647
648 return desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV;
649 }
650
651 /**
652 * Calculates the depth format type based upon the incoming format description.
653 */
654 static inline unsigned
util_get_depth_format_type(const struct util_format_description * desc)655 util_get_depth_format_type(const struct util_format_description *desc)
656 {
657 unsigned depth_channel = desc->swizzle[0];
658 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
659 depth_channel != PIPE_SWIZZLE_NONE) {
660 return desc->channel[depth_channel].type;
661 } else {
662 return UTIL_FORMAT_TYPE_VOID;
663 }
664 }
665
666
667 /**
668 * Calculates the MRD for the depth format. MRD is used in depth bias
669 * for UNORM and unbound depth buffers. When the depth buffer is floating
670 * point, the depth bias calculation does not use the MRD. However, the
671 * default MRD will be 1.0 / ((1 << 24) - 1).
672 */
673 double
674 util_get_depth_format_mrd(const struct util_format_description *desc);
675
676
677 /**
678 * Return whether this is an RGBA, Z, S, or combined ZS format.
679 * Useful for initializing pipe_blit_info::mask.
680 */
681 static inline unsigned
util_format_get_mask(enum pipe_format format)682 util_format_get_mask(enum pipe_format format)
683 {
684 const struct util_format_description *desc =
685 util_format_description(format);
686
687 if (!desc)
688 return 0;
689
690 if (util_format_has_depth(desc)) {
691 if (util_format_has_stencil(desc)) {
692 return PIPE_MASK_ZS;
693 } else {
694 return PIPE_MASK_Z;
695 }
696 } else {
697 if (util_format_has_stencil(desc)) {
698 return PIPE_MASK_S;
699 } else {
700 return PIPE_MASK_RGBA;
701 }
702 }
703 }
704
705 /**
706 * Give the RGBA colormask of the channels that can be represented in this
707 * format.
708 *
709 * That is, the channels whose values are preserved.
710 */
711 static inline unsigned
util_format_colormask(const struct util_format_description * desc)712 util_format_colormask(const struct util_format_description *desc)
713 {
714 unsigned colormask;
715 unsigned chan;
716
717 switch (desc->colorspace) {
718 case UTIL_FORMAT_COLORSPACE_RGB:
719 case UTIL_FORMAT_COLORSPACE_SRGB:
720 case UTIL_FORMAT_COLORSPACE_YUV:
721 colormask = 0;
722 for (chan = 0; chan < 4; ++chan) {
723 if (desc->swizzle[chan] < 4) {
724 colormask |= (1 << chan);
725 }
726 }
727 return colormask;
728 case UTIL_FORMAT_COLORSPACE_ZS:
729 return 0;
730 default:
731 assert(0);
732 return 0;
733 }
734 }
735
736
737 /**
738 * Checks if color mask covers every channel for the specified format
739 *
740 * @param desc a format description to check colormask with
741 * @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA
742 */
743 static inline bool
util_format_colormask_full(const struct util_format_description * desc,unsigned colormask)744 util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
745 {
746 return (~colormask & util_format_colormask(desc)) == 0;
747 }
748
749
750 bool
751 util_format_is_float(enum pipe_format format) ATTRIBUTE_CONST;
752
753
754 bool
755 util_format_has_alpha(enum pipe_format format) ATTRIBUTE_CONST;
756
757 bool
758 util_format_has_alpha1(enum pipe_format format) ATTRIBUTE_CONST;
759
760 bool
761 util_format_is_luminance(enum pipe_format format) ATTRIBUTE_CONST;
762
763 bool
764 util_format_is_alpha(enum pipe_format format) ATTRIBUTE_CONST;
765
766 bool
767 util_format_is_luminance_alpha(enum pipe_format format) ATTRIBUTE_CONST;
768
769 bool
770 util_format_is_red_alpha(enum pipe_format format) ATTRIBUTE_CONST;
771
772 bool
773 util_format_is_red_green(enum pipe_format format) ATTRIBUTE_CONST;
774
775 bool
776 util_format_is_intensity(enum pipe_format format) ATTRIBUTE_CONST;
777
778 bool
779 util_format_is_subsampled_422(enum pipe_format format) ATTRIBUTE_CONST;
780
781 bool
782 util_format_is_pure_integer(enum pipe_format format) ATTRIBUTE_CONST;
783
784 bool
785 util_format_is_pure_sint(enum pipe_format format) ATTRIBUTE_CONST;
786
787 bool
788 util_format_is_pure_uint(enum pipe_format format) ATTRIBUTE_CONST;
789
790 bool
791 util_format_is_snorm(enum pipe_format format) ATTRIBUTE_CONST;
792
793 bool
794 util_format_is_unorm(enum pipe_format format) ATTRIBUTE_CONST;
795
796 bool
797 util_format_is_snorm8(enum pipe_format format) ATTRIBUTE_CONST;
798
799 bool
800 util_format_is_scaled(enum pipe_format format) ATTRIBUTE_CONST;
801 /**
802 * Check if the src format can be blitted to the destination format with
803 * a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not
804 * the reverse.
805 */
806 bool
807 util_is_format_compatible(const struct util_format_description *src_desc,
808 const struct util_format_description *dst_desc) ATTRIBUTE_CONST;
809
810 /**
811 * Whether this format is a rgab8 variant.
812 *
813 * That is, any format that matches the
814 *
815 * PIPE_FORMAT_?8?8?8?8_UNORM
816 */
817 static inline bool
util_format_is_rgba8_variant(const struct util_format_description * desc)818 util_format_is_rgba8_variant(const struct util_format_description *desc)
819 {
820 unsigned chan;
821
822 if(desc->block.width != 1 ||
823 desc->block.height != 1 ||
824 desc->block.bits != 32)
825 return false;
826
827 for(chan = 0; chan < 4; ++chan) {
828 if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
829 desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
830 return false;
831 if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED &&
832 !desc->channel[chan].normalized)
833 return false;
834 if(desc->channel[chan].size != 8)
835 return false;
836 }
837
838 return true;
839 }
840
841
842 static inline bool
util_format_is_rgbx_or_bgrx(enum pipe_format format)843 util_format_is_rgbx_or_bgrx(enum pipe_format format)
844 {
845 const struct util_format_description *desc = util_format_description(format);
846 return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
847 desc->nr_channels == 4 &&
848 (desc->swizzle[0] == PIPE_SWIZZLE_X || desc->swizzle[0] == PIPE_SWIZZLE_Z) &&
849 desc->swizzle[1] == PIPE_SWIZZLE_Y &&
850 (desc->swizzle[2] == PIPE_SWIZZLE_Z || desc->swizzle[2] == PIPE_SWIZZLE_X) &&
851 desc->swizzle[3] == PIPE_SWIZZLE_1;
852 }
853
854 /**
855 * Return total bits needed for the pixel format per block.
856 */
857 static inline unsigned
util_format_get_blocksizebits(enum pipe_format format)858 util_format_get_blocksizebits(enum pipe_format format)
859 {
860 const struct util_format_description *desc = util_format_description(format);
861
862 assert(desc);
863 if (!desc) {
864 return 0;
865 }
866
867 return desc->block.bits;
868 }
869
870 /**
871 * Return bytes per block (not pixel) for the given format.
872 */
873 static inline unsigned
util_format_get_blocksize(enum pipe_format format)874 util_format_get_blocksize(enum pipe_format format)
875 {
876 unsigned bits = util_format_get_blocksizebits(format);
877 unsigned bytes = bits / 8;
878
879 assert(bits % 8 == 0);
880 /* Some formats have bits set to 0, let's default to 1.*/
881 if (bytes == 0) {
882 bytes = 1;
883 }
884
885 return bytes;
886 }
887
888 static inline unsigned
util_format_get_blockwidth(enum pipe_format format)889 util_format_get_blockwidth(enum pipe_format format)
890 {
891 const struct util_format_description *desc = util_format_description(format);
892
893 assert(desc);
894 if (!desc) {
895 return 1;
896 }
897
898 return desc->block.width;
899 }
900
901 static inline unsigned
util_format_get_blockheight(enum pipe_format format)902 util_format_get_blockheight(enum pipe_format format)
903 {
904 const struct util_format_description *desc = util_format_description(format);
905
906 assert(desc);
907 if (!desc) {
908 return 1;
909 }
910
911 return desc->block.height;
912 }
913
914 static inline unsigned
util_format_get_blockdepth(enum pipe_format format)915 util_format_get_blockdepth(enum pipe_format format)
916 {
917 const struct util_format_description *desc = util_format_description(format);
918
919 assert(desc);
920 if (!desc) {
921 return 1;
922 }
923
924 return desc->block.depth;
925 }
926
927 static inline unsigned
util_format_get_nblocksx(enum pipe_format format,unsigned x)928 util_format_get_nblocksx(enum pipe_format format,
929 unsigned x)
930 {
931 unsigned blockwidth = util_format_get_blockwidth(format);
932 return (x + blockwidth - 1) / blockwidth;
933 }
934
935 static inline unsigned
util_format_get_nblocksy(enum pipe_format format,unsigned y)936 util_format_get_nblocksy(enum pipe_format format,
937 unsigned y)
938 {
939 unsigned blockheight = util_format_get_blockheight(format);
940 return (y + blockheight - 1) / blockheight;
941 }
942
943 static inline unsigned
util_format_get_nblocksz(enum pipe_format format,unsigned z)944 util_format_get_nblocksz(enum pipe_format format,
945 unsigned z)
946 {
947 unsigned blockdepth = util_format_get_blockdepth(format);
948 return (z + blockdepth - 1) / blockdepth;
949 }
950
951 static inline uint64_t
util_format_get_nblocks(enum pipe_format format,unsigned width,unsigned height)952 util_format_get_nblocks(enum pipe_format format,
953 unsigned width,
954 unsigned height)
955 {
956 assert(util_format_get_blockdepth(format) == 1);
957 return (uint64_t)util_format_get_nblocksx(format, width) *
958 util_format_get_nblocksy(format, height);
959 }
960
961 static inline unsigned
util_format_get_stride(enum pipe_format format,unsigned width)962 util_format_get_stride(enum pipe_format format,
963 unsigned width)
964 {
965 return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
966 }
967
968 static inline uint64_t
util_format_get_2d_size(enum pipe_format format,unsigned stride,unsigned height)969 util_format_get_2d_size(enum pipe_format format, unsigned stride,
970 unsigned height)
971 {
972 return (uint64_t)util_format_get_nblocksy(format, height) * stride;
973 }
974
975 static inline unsigned
util_format_get_component_bits(enum pipe_format format,enum util_format_colorspace colorspace,unsigned component)976 util_format_get_component_bits(enum pipe_format format,
977 enum util_format_colorspace colorspace,
978 unsigned component)
979 {
980 const struct util_format_description *desc = util_format_description(format);
981 enum util_format_colorspace desc_colorspace;
982
983 assert(format);
984 if (!format) {
985 return 0;
986 }
987
988 assert(component < 4);
989
990 /* Treat RGB and SRGB as equivalent. */
991 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
992 colorspace = UTIL_FORMAT_COLORSPACE_RGB;
993 }
994 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
995 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
996 } else {
997 desc_colorspace = desc->colorspace;
998 }
999
1000 if (desc_colorspace != colorspace) {
1001 return 0;
1002 }
1003
1004 switch (desc->swizzle[component]) {
1005 case PIPE_SWIZZLE_X:
1006 return desc->channel[0].size;
1007 case PIPE_SWIZZLE_Y:
1008 return desc->channel[1].size;
1009 case PIPE_SWIZZLE_Z:
1010 return desc->channel[2].size;
1011 case PIPE_SWIZZLE_W:
1012 return desc->channel[3].size;
1013 default:
1014 return 0;
1015 }
1016 }
1017
1018 static inline unsigned
util_format_get_component_shift(enum pipe_format format,enum util_format_colorspace colorspace,unsigned component)1019 util_format_get_component_shift(enum pipe_format format,
1020 enum util_format_colorspace colorspace,
1021 unsigned component)
1022 {
1023 const struct util_format_description *desc = util_format_description(format);
1024 enum util_format_colorspace desc_colorspace;
1025
1026 assert(format);
1027 if (!format) {
1028 return 0;
1029 }
1030
1031 assert(component < 4);
1032
1033 /* Treat RGB and SRGB as equivalent. */
1034 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
1035 colorspace = UTIL_FORMAT_COLORSPACE_RGB;
1036 }
1037 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
1038 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
1039 } else {
1040 desc_colorspace = desc->colorspace;
1041 }
1042
1043 if (desc_colorspace != colorspace) {
1044 return 0;
1045 }
1046
1047 switch (desc->swizzle[component]) {
1048 case PIPE_SWIZZLE_X:
1049 return desc->channel[0].shift;
1050 case PIPE_SWIZZLE_Y:
1051 return desc->channel[1].shift;
1052 case PIPE_SWIZZLE_Z:
1053 return desc->channel[2].shift;
1054 case PIPE_SWIZZLE_W:
1055 return desc->channel[3].shift;
1056 default:
1057 return 0;
1058 }
1059 }
1060
1061 /**
1062 * Given a linear RGB colorspace format, return the corresponding SRGB
1063 * format, or PIPE_FORMAT_NONE if none.
1064 */
1065 static inline enum pipe_format
util_format_srgb(enum pipe_format format)1066 util_format_srgb(enum pipe_format format)
1067 {
1068 if (util_format_is_srgb(format))
1069 return format;
1070
1071 return util_format_description(format)->srgb_equivalent;
1072 }
1073
1074 /**
1075 * Given an sRGB format, return the corresponding linear colorspace format.
1076 * For non sRGB formats, return the format unchanged.
1077 */
1078 static inline enum pipe_format
util_format_linear(enum pipe_format format)1079 util_format_linear(enum pipe_format format)
1080 {
1081 if (!util_format_is_srgb(format))
1082 return format;
1083
1084 return util_format_description(format)->linear_equivalent;
1085 }
1086
1087 /**
1088 * Given a depth-stencil format, return the corresponding stencil-only format.
1089 * For stencil-only formats, return the format unchanged.
1090 */
1091 static inline enum pipe_format
util_format_stencil_only(enum pipe_format format)1092 util_format_stencil_only(enum pipe_format format)
1093 {
1094 switch (format) {
1095 /* mask out the depth component */
1096 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
1097 return PIPE_FORMAT_X24S8_UINT;
1098 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
1099 return PIPE_FORMAT_S8X24_UINT;
1100 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
1101 return PIPE_FORMAT_X32_S8X24_UINT;
1102
1103 /* stencil only formats */
1104 case PIPE_FORMAT_X24S8_UINT:
1105 case PIPE_FORMAT_S8X24_UINT:
1106 case PIPE_FORMAT_X32_S8X24_UINT:
1107 case PIPE_FORMAT_S8_UINT:
1108 return format;
1109
1110 default:
1111 assert(0);
1112 return PIPE_FORMAT_NONE;
1113 }
1114 }
1115
1116 static inline enum pipe_format
util_format_as_renderable(enum pipe_format format)1117 util_format_as_renderable(enum pipe_format format)
1118 {
1119 switch (util_format_get_blocksizebits(format)) {
1120 case 128:
1121 return PIPE_FORMAT_R32G32B32A32_UINT;
1122 case 96:
1123 return PIPE_FORMAT_R32G32B32_UINT;
1124 case 64:
1125 return PIPE_FORMAT_R32G32_UINT;
1126 case 48:
1127 return PIPE_FORMAT_R16G16B16_UINT;
1128 case 32:
1129 return PIPE_FORMAT_R32_UINT;
1130 case 24:
1131 return PIPE_FORMAT_R8G8B8_UINT;
1132 case 16:
1133 return PIPE_FORMAT_R16_UINT;
1134 case 8:
1135 return PIPE_FORMAT_R8_UINT;
1136 default:
1137 return PIPE_FORMAT_NONE;
1138 }
1139 }
1140
1141 /**
1142 * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.
1143 * This is identity for non-intensity formats.
1144 */
1145 static inline enum pipe_format
util_format_intensity_to_red(enum pipe_format format)1146 util_format_intensity_to_red(enum pipe_format format)
1147 {
1148 switch (format) {
1149 case PIPE_FORMAT_I8_UNORM:
1150 return PIPE_FORMAT_R8_UNORM;
1151 case PIPE_FORMAT_I8_SNORM:
1152 return PIPE_FORMAT_R8_SNORM;
1153 case PIPE_FORMAT_I16_UNORM:
1154 return PIPE_FORMAT_R16_UNORM;
1155 case PIPE_FORMAT_I16_SNORM:
1156 return PIPE_FORMAT_R16_SNORM;
1157 case PIPE_FORMAT_I16_FLOAT:
1158 return PIPE_FORMAT_R16_FLOAT;
1159 case PIPE_FORMAT_I32_FLOAT:
1160 return PIPE_FORMAT_R32_FLOAT;
1161 case PIPE_FORMAT_I8_UINT:
1162 return PIPE_FORMAT_R8_UINT;
1163 case PIPE_FORMAT_I8_SINT:
1164 return PIPE_FORMAT_R8_SINT;
1165 case PIPE_FORMAT_I16_UINT:
1166 return PIPE_FORMAT_R16_UINT;
1167 case PIPE_FORMAT_I16_SINT:
1168 return PIPE_FORMAT_R16_SINT;
1169 case PIPE_FORMAT_I32_UINT:
1170 return PIPE_FORMAT_R32_UINT;
1171 case PIPE_FORMAT_I32_SINT:
1172 return PIPE_FORMAT_R32_SINT;
1173 default:
1174 assert(!util_format_is_intensity(format));
1175 return format;
1176 }
1177 }
1178
1179 /**
1180 * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.
1181 * This is identity for non-luminance formats.
1182 */
1183 static inline enum pipe_format
util_format_luminance_to_red(enum pipe_format format)1184 util_format_luminance_to_red(enum pipe_format format)
1185 {
1186 switch (format) {
1187 case PIPE_FORMAT_L8_UNORM:
1188 return PIPE_FORMAT_R8_UNORM;
1189 case PIPE_FORMAT_L8_SNORM:
1190 return PIPE_FORMAT_R8_SNORM;
1191 case PIPE_FORMAT_L16_UNORM:
1192 return PIPE_FORMAT_R16_UNORM;
1193 case PIPE_FORMAT_L16_SNORM:
1194 return PIPE_FORMAT_R16_SNORM;
1195 case PIPE_FORMAT_L16_FLOAT:
1196 return PIPE_FORMAT_R16_FLOAT;
1197 case PIPE_FORMAT_L32_FLOAT:
1198 return PIPE_FORMAT_R32_FLOAT;
1199 case PIPE_FORMAT_L8_UINT:
1200 return PIPE_FORMAT_R8_UINT;
1201 case PIPE_FORMAT_L8_SINT:
1202 return PIPE_FORMAT_R8_SINT;
1203 case PIPE_FORMAT_L16_UINT:
1204 return PIPE_FORMAT_R16_UINT;
1205 case PIPE_FORMAT_L16_SINT:
1206 return PIPE_FORMAT_R16_SINT;
1207 case PIPE_FORMAT_L32_UINT:
1208 return PIPE_FORMAT_R32_UINT;
1209 case PIPE_FORMAT_L32_SINT:
1210 return PIPE_FORMAT_R32_SINT;
1211
1212 case PIPE_FORMAT_LATC1_UNORM:
1213 return PIPE_FORMAT_RGTC1_UNORM;
1214 case PIPE_FORMAT_LATC1_SNORM:
1215 return PIPE_FORMAT_RGTC1_SNORM;
1216
1217 case PIPE_FORMAT_L4A4_UNORM:
1218 return PIPE_FORMAT_R4A4_UNORM;
1219
1220 case PIPE_FORMAT_L8A8_UNORM:
1221 return PIPE_FORMAT_R8A8_UNORM;
1222 case PIPE_FORMAT_L8A8_SNORM:
1223 return PIPE_FORMAT_R8A8_SNORM;
1224 case PIPE_FORMAT_L16A16_UNORM:
1225 return PIPE_FORMAT_R16A16_UNORM;
1226 case PIPE_FORMAT_L16A16_SNORM:
1227 return PIPE_FORMAT_R16A16_SNORM;
1228 case PIPE_FORMAT_L16A16_FLOAT:
1229 return PIPE_FORMAT_R16A16_FLOAT;
1230 case PIPE_FORMAT_L32A32_FLOAT:
1231 return PIPE_FORMAT_R32A32_FLOAT;
1232 case PIPE_FORMAT_L8A8_UINT:
1233 return PIPE_FORMAT_R8A8_UINT;
1234 case PIPE_FORMAT_L8A8_SINT:
1235 return PIPE_FORMAT_R8A8_SINT;
1236 case PIPE_FORMAT_L16A16_UINT:
1237 return PIPE_FORMAT_R16A16_UINT;
1238 case PIPE_FORMAT_L16A16_SINT:
1239 return PIPE_FORMAT_R16A16_SINT;
1240 case PIPE_FORMAT_L32A32_UINT:
1241 return PIPE_FORMAT_R32A32_UINT;
1242 case PIPE_FORMAT_L32A32_SINT:
1243 return PIPE_FORMAT_R32A32_SINT;
1244
1245 case PIPE_FORMAT_L8_SRGB:
1246 return PIPE_FORMAT_R8_SRGB;
1247
1248 case PIPE_FORMAT_L8A8_SRGB:
1249 return PIPE_FORMAT_R8G8_SRGB;
1250
1251 /* We don't have compressed red-alpha variants for these. */
1252 case PIPE_FORMAT_LATC2_UNORM:
1253 case PIPE_FORMAT_LATC2_SNORM:
1254 return PIPE_FORMAT_NONE;
1255
1256 default:
1257 assert(!util_format_is_luminance(format) &&
1258 !util_format_is_luminance_alpha(format));
1259 return format;
1260 }
1261 }
1262
1263 static inline unsigned
util_format_get_num_planes(enum pipe_format format)1264 util_format_get_num_planes(enum pipe_format format)
1265 {
1266 switch (util_format_description(format)->layout) {
1267 case UTIL_FORMAT_LAYOUT_PLANAR3:
1268 return 3;
1269 case UTIL_FORMAT_LAYOUT_PLANAR2:
1270 return 2;
1271 default:
1272 return 1;
1273 }
1274 }
1275
1276 static inline enum pipe_format
util_format_get_plane_format(enum pipe_format format,unsigned plane)1277 util_format_get_plane_format(enum pipe_format format, unsigned plane)
1278 {
1279 switch (format) {
1280 case PIPE_FORMAT_YV12:
1281 case PIPE_FORMAT_YV16:
1282 case PIPE_FORMAT_IYUV:
1283 case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
1284 case PIPE_FORMAT_Y8_U8_V8_444_UNORM:
1285 case PIPE_FORMAT_Y8_400_UNORM:
1286 case PIPE_FORMAT_R8_G8_B8_UNORM:
1287 case PIPE_FORMAT_Y8_U8_V8_440_UNORM:
1288 return PIPE_FORMAT_R8_UNORM;
1289 case PIPE_FORMAT_NV12:
1290 case PIPE_FORMAT_Y8_U8V8_422_UNORM:
1291 return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_RG88_UNORM;
1292 case PIPE_FORMAT_NV21:
1293 return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_GR88_UNORM;
1294 case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1295 case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
1296 case PIPE_FORMAT_Y16_U16_V16_444_UNORM:
1297 return PIPE_FORMAT_R16_UNORM;
1298 case PIPE_FORMAT_P010:
1299 case PIPE_FORMAT_P012:
1300 case PIPE_FORMAT_P016:
1301 case PIPE_FORMAT_P030:
1302 case PIPE_FORMAT_Y16_U16V16_422_UNORM:
1303 return !plane ? PIPE_FORMAT_R16_UNORM : PIPE_FORMAT_R16G16_UNORM;
1304 default:
1305 return format;
1306 }
1307 }
1308
1309 static inline unsigned
util_format_get_plane_width(enum pipe_format format,unsigned plane,unsigned width)1310 util_format_get_plane_width(enum pipe_format format, unsigned plane,
1311 unsigned width)
1312 {
1313 switch (format) {
1314 case PIPE_FORMAT_YV12:
1315 case PIPE_FORMAT_YV16:
1316 case PIPE_FORMAT_IYUV:
1317 case PIPE_FORMAT_NV12:
1318 case PIPE_FORMAT_NV21:
1319 case PIPE_FORMAT_P010:
1320 case PIPE_FORMAT_P012:
1321 case PIPE_FORMAT_P016:
1322 case PIPE_FORMAT_P030:
1323 case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
1324 case PIPE_FORMAT_Y8_U8V8_422_UNORM:
1325 case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1326 case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
1327 case PIPE_FORMAT_Y16_U16V16_422_UNORM:
1328 return !plane ? width : (width + 1) / 2;
1329 default:
1330 return width;
1331 }
1332 }
1333
1334 static inline unsigned
util_format_get_plane_height(enum pipe_format format,unsigned plane,unsigned height)1335 util_format_get_plane_height(enum pipe_format format, unsigned plane,
1336 unsigned height)
1337 {
1338 switch (format) {
1339 case PIPE_FORMAT_YV12:
1340 case PIPE_FORMAT_IYUV:
1341 case PIPE_FORMAT_NV12:
1342 case PIPE_FORMAT_NV21:
1343 case PIPE_FORMAT_P010:
1344 case PIPE_FORMAT_P012:
1345 case PIPE_FORMAT_P016:
1346 case PIPE_FORMAT_P030:
1347 case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1348 case PIPE_FORMAT_Y8_U8_V8_440_UNORM:
1349 return !plane ? height : (height + 1) / 2;
1350 case PIPE_FORMAT_YV16:
1351 default:
1352 return height;
1353 }
1354 }
1355
1356 /**
1357 * Return the number of components stored.
1358 * Formats with block size != 1x1 will always have 1 component (the block).
1359 */
1360 static inline unsigned
util_format_get_nr_components(enum pipe_format format)1361 util_format_get_nr_components(enum pipe_format format)
1362 {
1363 const struct util_format_description *desc = util_format_description(format);
1364 return desc->nr_channels;
1365 }
1366
1367 /**
1368 * Return the index of the first non-void channel
1369 * -1 if no non-void channels
1370 */
1371 static inline int
util_format_get_first_non_void_channel(enum pipe_format format)1372 util_format_get_first_non_void_channel(enum pipe_format format)
1373 {
1374 const struct util_format_description *desc = util_format_description(format);
1375 int i;
1376
1377 for (i = 0; i < 4; i++)
1378 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
1379 return i;
1380
1381 return -1;
1382 }
1383
1384 /**
1385 * Whether this format is any 8-bit UNORM variant. Looser than
1386 * util_is_rgba8_variant (also includes alpha textures, for instance).
1387 */
1388
1389 static inline bool
util_format_is_unorm8(const struct util_format_description * desc)1390 util_format_is_unorm8(const struct util_format_description *desc)
1391 {
1392 int c = util_format_get_first_non_void_channel(desc->format);
1393
1394 if (c == -1)
1395 return false;
1396
1397 return desc->is_unorm && desc->is_array && desc->channel[c].size == 8;
1398 }
1399
1400 static inline void
util_format_unpack_z_float(enum pipe_format format,float * dst,const void * src,unsigned w)1401 util_format_unpack_z_float(enum pipe_format format, float *dst,
1402 const void *src, unsigned w)
1403 {
1404 const struct util_format_unpack_description *desc =
1405 util_format_unpack_description(format);
1406
1407 desc->unpack_z_float(dst, 0, (const uint8_t *)src, 0, w, 1);
1408 }
1409
1410 static inline void
util_format_unpack_z_32unorm(enum pipe_format format,uint32_t * dst,const void * src,unsigned w)1411 util_format_unpack_z_32unorm(enum pipe_format format, uint32_t *dst,
1412 const void *src, unsigned w)
1413 {
1414 const struct util_format_unpack_description *desc =
1415 util_format_unpack_description(format);
1416
1417 desc->unpack_z_32unorm(dst, 0, (const uint8_t *)src, 0, w, 1);
1418 }
1419
1420 static inline void
util_format_unpack_s_8uint(enum pipe_format format,uint8_t * dst,const void * src,unsigned w)1421 util_format_unpack_s_8uint(enum pipe_format format, uint8_t *dst,
1422 const void *src, unsigned w)
1423 {
1424 const struct util_format_unpack_description *desc =
1425 util_format_unpack_description(format);
1426
1427 desc->unpack_s_8uint(dst, 0, (const uint8_t *)src, 0, w, 1);
1428 }
1429
1430 /**
1431 * Unpacks a row of color data to 32-bit RGBA, either integers for pure
1432 * integer formats (sign-extended for signed data), or 32-bit floats.
1433 */
1434 static inline void
util_format_unpack_rgba(enum pipe_format format,void * dst,const void * src,unsigned w)1435 util_format_unpack_rgba(enum pipe_format format, void *dst,
1436 const void *src, unsigned w)
1437 {
1438 const struct util_format_unpack_description *desc =
1439 util_format_unpack_description(format);
1440
1441 desc->unpack_rgba(dst, (const uint8_t *)src, w);
1442 }
1443
1444 static inline void
util_format_pack_z_float(enum pipe_format format,void * dst,const float * src,unsigned w)1445 util_format_pack_z_float(enum pipe_format format, void *dst,
1446 const float *src, unsigned w)
1447 {
1448 const struct util_format_pack_description *desc =
1449 util_format_pack_description(format);
1450
1451 desc->pack_z_float((uint8_t *)dst, 0, src, 0, w, 1);
1452 }
1453
1454 static inline void
util_format_pack_z_32unorm(enum pipe_format format,void * dst,const uint32_t * src,unsigned w)1455 util_format_pack_z_32unorm(enum pipe_format format, void *dst,
1456 const uint32_t *src, unsigned w)
1457 {
1458 const struct util_format_pack_description *desc =
1459 util_format_pack_description(format);
1460
1461 desc->pack_z_32unorm((uint8_t *)dst, 0, src, 0, w, 1);
1462 }
1463
1464 static inline void
util_format_pack_s_8uint(enum pipe_format format,void * dst,const uint8_t * src,unsigned w)1465 util_format_pack_s_8uint(enum pipe_format format, void *dst,
1466 const uint8_t *src, unsigned w)
1467 {
1468 const struct util_format_pack_description *desc =
1469 util_format_pack_description(format);
1470
1471 desc->pack_s_8uint((uint8_t *)dst, 0, src, 0, w, 1);
1472 }
1473
1474 /**
1475 * Packs a row of color data from 32-bit RGBA, either integers for pure
1476 * integer formats, or 32-bit floats. Values are clamped to the packed
1477 * representation's range.
1478 */
1479 static inline void
util_format_pack_rgba(enum pipe_format format,void * dst,const void * src,unsigned w)1480 util_format_pack_rgba(enum pipe_format format, void *dst,
1481 const void *src, unsigned w)
1482 {
1483 const struct util_format_pack_description *desc =
1484 util_format_pack_description(format);
1485
1486 if (util_format_is_pure_uint(format))
1487 desc->pack_rgba_uint((uint8_t *)dst, 0, (const uint32_t *)src, 0, w, 1);
1488 else if (util_format_is_pure_sint(format))
1489 desc->pack_rgba_sint((uint8_t *)dst, 0, (const int32_t *)src, 0, w, 1);
1490 else
1491 desc->pack_rgba_float((uint8_t *)dst, 0, (const float *)src, 0, w, 1);
1492 }
1493
1494 /*
1495 * Format access functions for subrectangles
1496 */
1497
1498 void
1499 util_format_read_4(enum pipe_format format,
1500 void *dst, unsigned dst_stride,
1501 const void *src, unsigned src_stride,
1502 unsigned x, unsigned y, unsigned w, unsigned h);
1503
1504 void
1505 util_format_write_4(enum pipe_format format,
1506 const void *src, unsigned src_stride,
1507 void *dst, unsigned dst_stride,
1508 unsigned x, unsigned y, unsigned w, unsigned h);
1509
1510 void
1511 util_format_read_4ub(enum pipe_format format,
1512 uint8_t *dst, unsigned dst_stride,
1513 const void *src, unsigned src_stride,
1514 unsigned x, unsigned y, unsigned w, unsigned h);
1515
1516 void
1517 util_format_write_4ub(enum pipe_format format,
1518 const uint8_t *src, unsigned src_stride,
1519 void *dst, unsigned dst_stride,
1520 unsigned x, unsigned y, unsigned w, unsigned h);
1521
1522 void
1523 util_format_unpack_rgba_rect(enum pipe_format format,
1524 void *dst, unsigned dst_stride,
1525 const void *src, unsigned src_stride,
1526 unsigned w, unsigned h);
1527
1528 void
1529 util_format_unpack_rgba_8unorm_rect(enum pipe_format format,
1530 void *dst, unsigned dst_stride,
1531 const void *src, unsigned src_stride,
1532 unsigned w, unsigned h);
1533
1534 /*
1535 * Generic format conversion;
1536 */
1537
1538 bool
1539 util_format_fits_8unorm(const struct util_format_description *format_desc) ATTRIBUTE_CONST;
1540
1541 bool
1542 util_format_translate(enum pipe_format dst_format,
1543 void *dst, unsigned dst_stride,
1544 unsigned dst_x, unsigned dst_y,
1545 enum pipe_format src_format,
1546 const void *src, unsigned src_stride,
1547 unsigned src_x, unsigned src_y,
1548 unsigned width, unsigned height);
1549
1550 bool
1551 util_format_translate_3d(enum pipe_format dst_format,
1552 void *dst, unsigned dst_stride,
1553 uint64_t dst_slice_stride,
1554 unsigned dst_x, unsigned dst_y,
1555 unsigned dst_z,
1556 enum pipe_format src_format,
1557 const void *src, unsigned src_stride,
1558 uint64_t src_slice_stride,
1559 unsigned src_x, unsigned src_y,
1560 unsigned src_z, unsigned width,
1561 unsigned height, unsigned depth);
1562
1563 /*
1564 * Swizzle operations.
1565 */
1566
1567 /* Compose two sets of swizzles.
1568 * If V is a 4D vector and the function parameters represent functions that
1569 * swizzle vector components, this holds:
1570 * swz2(swz1(V)) = dst(V)
1571 */
1572 void util_format_compose_swizzles(const unsigned char swz1[4],
1573 const unsigned char swz2[4],
1574 unsigned char dst[4]);
1575
1576 /* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
1577 * to \param src and store the result in \param dst.
1578 * \param is_integer determines the value written for PIPE_SWIZZLE_1.
1579 */
1580 void util_format_apply_color_swizzle(union pipe_color_union *dst,
1581 const union pipe_color_union *src,
1582 const unsigned char swz[4],
1583 const bool is_integer);
1584
1585 void pipe_swizzle_4f(float *dst, const float *src,
1586 const unsigned char swz[4]);
1587
1588 void util_format_unswizzle_4f(float *dst, const float *src,
1589 const unsigned char swz[4]);
1590
1591 enum pipe_format
1592 util_format_snorm_to_sint(enum pipe_format format) ATTRIBUTE_CONST;
1593
1594 extern void
1595 util_copy_rect(void * dst, enum pipe_format format,
1596 unsigned dst_stride, unsigned dst_x, unsigned dst_y,
1597 unsigned width, unsigned height, const void * src,
1598 int src_stride, unsigned src_x, unsigned src_y);
1599
1600 /**
1601 * If the format is RGB, return BGR. If the format is BGR, return RGB.
1602 * This may fail by returning PIPE_FORMAT_NONE.
1603 */
1604 enum pipe_format
1605 util_format_rgb_to_bgr(enum pipe_format format);
1606
1607 /* Returns the pipe format with SNORM formats cast to UNORM, otherwise the original pipe format. */
1608 enum pipe_format
1609 util_format_snorm_to_unorm(enum pipe_format format);
1610
1611 enum pipe_format
1612 util_format_rgbx_to_rgba(enum pipe_format format);
1613
1614 /* Returns the pipe format for the given array type, bitsize and component count. */
1615 enum pipe_format
1616 util_format_get_array(const enum util_format_type type, const unsigned bits,
1617 const unsigned nr_components, const bool normalized,
1618 const bool pure_integer);
1619
1620 unsigned util_format_get_last_component(enum pipe_format format);
1621 int util_format_get_largest_non_void_channel(enum pipe_format format);
1622 unsigned util_format_get_max_channel_size(enum pipe_format format);
1623
1624 uint32_t util_format_get_tilesize(enum pipe_format format, uint32_t dimensions, uint32_t samples, uint32_t axis);
1625
1626 #ifdef __cplusplus
1627 } // extern "C" {
1628 #endif
1629
1630 #endif /* ! U_FORMAT_H */
1631