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