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