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