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