• 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 bool
755 util_format_is_red_alpha(enum pipe_format format) ATTRIBUTE_CONST;
756 
757 bool
758 util_format_is_red_green(enum pipe_format format) ATTRIBUTE_CONST;
759 
760 bool
761 util_format_is_intensity(enum pipe_format format) ATTRIBUTE_CONST;
762 
763 bool
764 util_format_is_subsampled_422(enum pipe_format format) ATTRIBUTE_CONST;
765 
766 bool
767 util_format_is_pure_integer(enum pipe_format format) ATTRIBUTE_CONST;
768 
769 bool
770 util_format_is_pure_sint(enum pipe_format format) ATTRIBUTE_CONST;
771 
772 bool
773 util_format_is_pure_uint(enum pipe_format format) ATTRIBUTE_CONST;
774 
775 bool
776 util_format_is_snorm(enum pipe_format format) ATTRIBUTE_CONST;
777 
778 bool
779 util_format_is_unorm(enum pipe_format format) ATTRIBUTE_CONST;
780 
781 bool
782 util_format_is_snorm8(enum pipe_format format) ATTRIBUTE_CONST;
783 
784 bool
785 util_format_is_scaled(enum pipe_format format) ATTRIBUTE_CONST;
786 /**
787  * Check if the src format can be blitted to the destination format with
788  * a simple memcpy.  For example, blitting from RGBA to RGBx is OK, but not
789  * the reverse.
790  */
791 bool
792 util_is_format_compatible(const struct util_format_description *src_desc,
793                           const struct util_format_description *dst_desc) ATTRIBUTE_CONST;
794 
795 /**
796  * Whether this format is a rgab8 variant.
797  *
798  * That is, any format that matches the
799  *
800  *   PIPE_FORMAT_?8?8?8?8_UNORM
801  */
802 static inline bool
util_format_is_rgba8_variant(const struct util_format_description * desc)803 util_format_is_rgba8_variant(const struct util_format_description *desc)
804 {
805    unsigned chan;
806 
807    if(desc->block.width != 1 ||
808       desc->block.height != 1 ||
809       desc->block.bits != 32)
810       return false;
811 
812    for(chan = 0; chan < 4; ++chan) {
813       if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
814          desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
815          return false;
816       if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED &&
817          !desc->channel[chan].normalized)
818          return false;
819       if(desc->channel[chan].size != 8)
820          return false;
821    }
822 
823    return true;
824 }
825 
826 
827 static inline bool
util_format_is_rgbx_or_bgrx(enum pipe_format format)828 util_format_is_rgbx_or_bgrx(enum pipe_format format)
829 {
830    const struct util_format_description *desc = util_format_description(format);
831    return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
832           desc->nr_channels == 4 &&
833           (desc->swizzle[0] == PIPE_SWIZZLE_X || desc->swizzle[0] == PIPE_SWIZZLE_Z) &&
834           desc->swizzle[1] == PIPE_SWIZZLE_Y &&
835           (desc->swizzle[2] == PIPE_SWIZZLE_Z || desc->swizzle[2] == PIPE_SWIZZLE_X) &&
836           desc->swizzle[3] == PIPE_SWIZZLE_1;
837 }
838 
839 /**
840  * Return total bits needed for the pixel format per block.
841  */
842 static inline unsigned
util_format_get_blocksizebits(enum pipe_format format)843 util_format_get_blocksizebits(enum pipe_format format)
844 {
845    const struct util_format_description *desc = util_format_description(format);
846 
847    assert(desc);
848    if (!desc) {
849       return 0;
850    }
851 
852    return desc->block.bits;
853 }
854 
855 /**
856  * Return bytes per block (not pixel) for the given format.
857  */
858 static inline unsigned
util_format_get_blocksize(enum pipe_format format)859 util_format_get_blocksize(enum pipe_format format)
860 {
861    unsigned bits = util_format_get_blocksizebits(format);
862    unsigned bytes = bits / 8;
863 
864    assert(bits % 8 == 0);
865    /* Some formats have bits set to 0, let's default to 1.*/
866    if (bytes == 0) {
867       bytes = 1;
868    }
869 
870    return bytes;
871 }
872 
873 static inline unsigned
util_format_get_blockwidth(enum pipe_format format)874 util_format_get_blockwidth(enum pipe_format format)
875 {
876    const struct util_format_description *desc = util_format_description(format);
877 
878    assert(desc);
879    if (!desc) {
880       return 1;
881    }
882 
883    return desc->block.width;
884 }
885 
886 static inline unsigned
util_format_get_blockheight(enum pipe_format format)887 util_format_get_blockheight(enum pipe_format format)
888 {
889    const struct util_format_description *desc = util_format_description(format);
890 
891    assert(desc);
892    if (!desc) {
893       return 1;
894    }
895 
896    return desc->block.height;
897 }
898 
899 static inline unsigned
util_format_get_blockdepth(enum pipe_format format)900 util_format_get_blockdepth(enum pipe_format format)
901 {
902    const struct util_format_description *desc = util_format_description(format);
903 
904    assert(desc);
905    if (!desc) {
906       return 1;
907    }
908 
909    return desc->block.depth;
910 }
911 
912 static inline unsigned
util_format_get_nblocksx(enum pipe_format format,unsigned x)913 util_format_get_nblocksx(enum pipe_format format,
914                          unsigned x)
915 {
916    unsigned blockwidth = util_format_get_blockwidth(format);
917    return (x + blockwidth - 1) / blockwidth;
918 }
919 
920 static inline unsigned
util_format_get_nblocksy(enum pipe_format format,unsigned y)921 util_format_get_nblocksy(enum pipe_format format,
922                          unsigned y)
923 {
924    unsigned blockheight = util_format_get_blockheight(format);
925    return (y + blockheight - 1) / blockheight;
926 }
927 
928 static inline unsigned
util_format_get_nblocksz(enum pipe_format format,unsigned z)929 util_format_get_nblocksz(enum pipe_format format,
930                          unsigned z)
931 {
932    unsigned blockdepth = util_format_get_blockdepth(format);
933    return (z + blockdepth - 1) / blockdepth;
934 }
935 
936 static inline uint64_t
util_format_get_nblocks(enum pipe_format format,unsigned width,unsigned height)937 util_format_get_nblocks(enum pipe_format format,
938                         unsigned width,
939                         unsigned height)
940 {
941    assert(util_format_get_blockdepth(format) == 1);
942    return (uint64_t)util_format_get_nblocksx(format, width) *
943           util_format_get_nblocksy(format, height);
944 }
945 
946 static inline unsigned
util_format_get_stride(enum pipe_format format,unsigned width)947 util_format_get_stride(enum pipe_format format,
948                        unsigned width)
949 {
950    return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
951 }
952 
953 static inline uint64_t
util_format_get_2d_size(enum pipe_format format,unsigned stride,unsigned height)954 util_format_get_2d_size(enum pipe_format format, unsigned stride,
955                         unsigned height)
956 {
957    return (uint64_t)util_format_get_nblocksy(format, height) * stride;
958 }
959 
960 static inline unsigned
util_format_get_component_bits(enum pipe_format format,enum util_format_colorspace colorspace,unsigned component)961 util_format_get_component_bits(enum pipe_format format,
962                                enum util_format_colorspace colorspace,
963                                unsigned component)
964 {
965    const struct util_format_description *desc = util_format_description(format);
966    enum util_format_colorspace desc_colorspace;
967 
968    assert(format);
969    if (!format) {
970       return 0;
971    }
972 
973    assert(component < 4);
974 
975    /* Treat RGB and SRGB as equivalent. */
976    if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
977       colorspace = UTIL_FORMAT_COLORSPACE_RGB;
978    }
979    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
980       desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
981    } else {
982       desc_colorspace = desc->colorspace;
983    }
984 
985    if (desc_colorspace != colorspace) {
986       return 0;
987    }
988 
989    switch (desc->swizzle[component]) {
990    case PIPE_SWIZZLE_X:
991       return desc->channel[0].size;
992    case PIPE_SWIZZLE_Y:
993       return desc->channel[1].size;
994    case PIPE_SWIZZLE_Z:
995       return desc->channel[2].size;
996    case PIPE_SWIZZLE_W:
997       return desc->channel[3].size;
998    default:
999       return 0;
1000    }
1001 }
1002 
1003 static inline unsigned
util_format_get_component_shift(enum pipe_format format,enum util_format_colorspace colorspace,unsigned component)1004 util_format_get_component_shift(enum pipe_format format,
1005                                 enum util_format_colorspace colorspace,
1006                                 unsigned component)
1007 {
1008    const struct util_format_description *desc = util_format_description(format);
1009    enum util_format_colorspace desc_colorspace;
1010 
1011    assert(format);
1012    if (!format) {
1013       return 0;
1014    }
1015 
1016    assert(component < 4);
1017 
1018    /* Treat RGB and SRGB as equivalent. */
1019    if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
1020       colorspace = UTIL_FORMAT_COLORSPACE_RGB;
1021    }
1022    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
1023       desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
1024    } else {
1025       desc_colorspace = desc->colorspace;
1026    }
1027 
1028    if (desc_colorspace != colorspace) {
1029       return 0;
1030    }
1031 
1032    switch (desc->swizzle[component]) {
1033    case PIPE_SWIZZLE_X:
1034       return desc->channel[0].shift;
1035    case PIPE_SWIZZLE_Y:
1036       return desc->channel[1].shift;
1037    case PIPE_SWIZZLE_Z:
1038       return desc->channel[2].shift;
1039    case PIPE_SWIZZLE_W:
1040       return desc->channel[3].shift;
1041    default:
1042       return 0;
1043    }
1044 }
1045 
1046 /**
1047  * Given a linear RGB colorspace format, return the corresponding SRGB
1048  * format, or PIPE_FORMAT_NONE if none.
1049  */
1050 static inline enum pipe_format
util_format_srgb(enum pipe_format format)1051 util_format_srgb(enum pipe_format format)
1052 {
1053    if (util_format_is_srgb(format))
1054       return format;
1055 
1056    switch (format) {
1057    case PIPE_FORMAT_L8_UNORM:
1058       return PIPE_FORMAT_L8_SRGB;
1059    case PIPE_FORMAT_R8_UNORM:
1060       return PIPE_FORMAT_R8_SRGB;
1061    case PIPE_FORMAT_L8A8_UNORM:
1062       return PIPE_FORMAT_L8A8_SRGB;
1063    case PIPE_FORMAT_R8G8_UNORM:
1064       return PIPE_FORMAT_R8G8_SRGB;
1065    case PIPE_FORMAT_R8G8B8_UNORM:
1066       return PIPE_FORMAT_R8G8B8_SRGB;
1067    case PIPE_FORMAT_B8G8R8_UNORM:
1068       return PIPE_FORMAT_B8G8R8_SRGB;
1069    case PIPE_FORMAT_A8B8G8R8_UNORM:
1070       return PIPE_FORMAT_A8B8G8R8_SRGB;
1071    case PIPE_FORMAT_X8B8G8R8_UNORM:
1072       return PIPE_FORMAT_X8B8G8R8_SRGB;
1073    case PIPE_FORMAT_B8G8R8A8_UNORM:
1074       return PIPE_FORMAT_B8G8R8A8_SRGB;
1075    case PIPE_FORMAT_B8G8R8X8_UNORM:
1076       return PIPE_FORMAT_B8G8R8X8_SRGB;
1077    case PIPE_FORMAT_A8R8G8B8_UNORM:
1078       return PIPE_FORMAT_A8R8G8B8_SRGB;
1079    case PIPE_FORMAT_X8R8G8B8_UNORM:
1080       return PIPE_FORMAT_X8R8G8B8_SRGB;
1081    case PIPE_FORMAT_R8G8B8A8_UNORM:
1082       return PIPE_FORMAT_R8G8B8A8_SRGB;
1083    case PIPE_FORMAT_R8G8B8X8_UNORM:
1084       return PIPE_FORMAT_R8G8B8X8_SRGB;
1085    case PIPE_FORMAT_DXT1_RGB:
1086       return PIPE_FORMAT_DXT1_SRGB;
1087    case PIPE_FORMAT_DXT1_RGBA:
1088       return PIPE_FORMAT_DXT1_SRGBA;
1089    case PIPE_FORMAT_DXT3_RGBA:
1090       return PIPE_FORMAT_DXT3_SRGBA;
1091    case PIPE_FORMAT_DXT5_RGBA:
1092       return PIPE_FORMAT_DXT5_SRGBA;
1093    case PIPE_FORMAT_R5G6B5_UNORM:
1094       return PIPE_FORMAT_R5G6B5_SRGB;
1095    case PIPE_FORMAT_B5G6R5_UNORM:
1096       return PIPE_FORMAT_B5G6R5_SRGB;
1097    case PIPE_FORMAT_BPTC_RGBA_UNORM:
1098       return PIPE_FORMAT_BPTC_SRGBA;
1099    case PIPE_FORMAT_ETC2_RGB8:
1100       return PIPE_FORMAT_ETC2_SRGB8;
1101    case PIPE_FORMAT_ETC2_RGB8A1:
1102       return PIPE_FORMAT_ETC2_SRGB8A1;
1103    case PIPE_FORMAT_ETC2_RGBA8:
1104       return PIPE_FORMAT_ETC2_SRGBA8;
1105    case PIPE_FORMAT_ASTC_4x4:
1106       return PIPE_FORMAT_ASTC_4x4_SRGB;
1107    case PIPE_FORMAT_ASTC_5x4:
1108       return PIPE_FORMAT_ASTC_5x4_SRGB;
1109    case PIPE_FORMAT_ASTC_5x5:
1110       return PIPE_FORMAT_ASTC_5x5_SRGB;
1111    case PIPE_FORMAT_ASTC_6x5:
1112       return PIPE_FORMAT_ASTC_6x5_SRGB;
1113    case PIPE_FORMAT_ASTC_6x6:
1114       return PIPE_FORMAT_ASTC_6x6_SRGB;
1115    case PIPE_FORMAT_ASTC_8x5:
1116       return PIPE_FORMAT_ASTC_8x5_SRGB;
1117    case PIPE_FORMAT_ASTC_8x6:
1118       return PIPE_FORMAT_ASTC_8x6_SRGB;
1119    case PIPE_FORMAT_ASTC_8x8:
1120       return PIPE_FORMAT_ASTC_8x8_SRGB;
1121    case PIPE_FORMAT_ASTC_10x5:
1122       return PIPE_FORMAT_ASTC_10x5_SRGB;
1123    case PIPE_FORMAT_ASTC_10x6:
1124       return PIPE_FORMAT_ASTC_10x6_SRGB;
1125    case PIPE_FORMAT_ASTC_10x8:
1126       return PIPE_FORMAT_ASTC_10x8_SRGB;
1127    case PIPE_FORMAT_ASTC_10x10:
1128       return PIPE_FORMAT_ASTC_10x10_SRGB;
1129    case PIPE_FORMAT_ASTC_12x10:
1130       return PIPE_FORMAT_ASTC_12x10_SRGB;
1131    case PIPE_FORMAT_ASTC_12x12:
1132       return PIPE_FORMAT_ASTC_12x12_SRGB;
1133    case PIPE_FORMAT_ASTC_3x3x3:
1134       return PIPE_FORMAT_ASTC_3x3x3_SRGB;
1135    case PIPE_FORMAT_ASTC_4x3x3:
1136       return PIPE_FORMAT_ASTC_4x3x3_SRGB;
1137    case PIPE_FORMAT_ASTC_4x4x3:
1138       return PIPE_FORMAT_ASTC_4x4x3_SRGB;
1139    case PIPE_FORMAT_ASTC_4x4x4:
1140       return PIPE_FORMAT_ASTC_4x4x4_SRGB;
1141    case PIPE_FORMAT_ASTC_5x4x4:
1142       return PIPE_FORMAT_ASTC_5x4x4_SRGB;
1143    case PIPE_FORMAT_ASTC_5x5x4:
1144       return PIPE_FORMAT_ASTC_5x5x4_SRGB;
1145    case PIPE_FORMAT_ASTC_5x5x5:
1146       return PIPE_FORMAT_ASTC_5x5x5_SRGB;
1147    case PIPE_FORMAT_ASTC_6x5x5:
1148       return PIPE_FORMAT_ASTC_6x5x5_SRGB;
1149    case PIPE_FORMAT_ASTC_6x6x5:
1150       return PIPE_FORMAT_ASTC_6x6x5_SRGB;
1151    case PIPE_FORMAT_ASTC_6x6x6:
1152       return PIPE_FORMAT_ASTC_6x6x6_SRGB;
1153 
1154    default:
1155       return PIPE_FORMAT_NONE;
1156    }
1157 }
1158 
1159 /**
1160  * Given an sRGB format, return the corresponding linear colorspace format.
1161  * For non sRGB formats, return the format unchanged.
1162  */
1163 static inline enum pipe_format
util_format_linear(enum pipe_format format)1164 util_format_linear(enum pipe_format format)
1165 {
1166    switch (format) {
1167    case PIPE_FORMAT_L8_SRGB:
1168       return PIPE_FORMAT_L8_UNORM;
1169    case PIPE_FORMAT_R8_SRGB:
1170       return PIPE_FORMAT_R8_UNORM;
1171    case PIPE_FORMAT_L8A8_SRGB:
1172       return PIPE_FORMAT_L8A8_UNORM;
1173    case PIPE_FORMAT_R8G8_SRGB:
1174       return PIPE_FORMAT_R8G8_UNORM;
1175    case PIPE_FORMAT_R8G8B8_SRGB:
1176       return PIPE_FORMAT_R8G8B8_UNORM;
1177    case PIPE_FORMAT_B8G8R8_SRGB:
1178       return PIPE_FORMAT_B8G8R8_UNORM;
1179    case PIPE_FORMAT_A8B8G8R8_SRGB:
1180       return PIPE_FORMAT_A8B8G8R8_UNORM;
1181    case PIPE_FORMAT_X8B8G8R8_SRGB:
1182       return PIPE_FORMAT_X8B8G8R8_UNORM;
1183    case PIPE_FORMAT_B8G8R8A8_SRGB:
1184       return PIPE_FORMAT_B8G8R8A8_UNORM;
1185    case PIPE_FORMAT_B8G8R8X8_SRGB:
1186       return PIPE_FORMAT_B8G8R8X8_UNORM;
1187    case PIPE_FORMAT_A8R8G8B8_SRGB:
1188       return PIPE_FORMAT_A8R8G8B8_UNORM;
1189    case PIPE_FORMAT_X8R8G8B8_SRGB:
1190       return PIPE_FORMAT_X8R8G8B8_UNORM;
1191    case PIPE_FORMAT_R8G8B8A8_SRGB:
1192       return PIPE_FORMAT_R8G8B8A8_UNORM;
1193    case PIPE_FORMAT_R8G8B8X8_SRGB:
1194       return PIPE_FORMAT_R8G8B8X8_UNORM;
1195    case PIPE_FORMAT_DXT1_SRGB:
1196       return PIPE_FORMAT_DXT1_RGB;
1197    case PIPE_FORMAT_DXT1_SRGBA:
1198       return PIPE_FORMAT_DXT1_RGBA;
1199    case PIPE_FORMAT_DXT3_SRGBA:
1200       return PIPE_FORMAT_DXT3_RGBA;
1201    case PIPE_FORMAT_DXT5_SRGBA:
1202       return PIPE_FORMAT_DXT5_RGBA;
1203    case PIPE_FORMAT_R5G6B5_SRGB:
1204       return PIPE_FORMAT_R5G6B5_UNORM;
1205    case PIPE_FORMAT_B5G6R5_SRGB:
1206       return PIPE_FORMAT_B5G6R5_UNORM;
1207    case PIPE_FORMAT_BPTC_SRGBA:
1208       return PIPE_FORMAT_BPTC_RGBA_UNORM;
1209    case PIPE_FORMAT_ETC2_SRGB8:
1210       return PIPE_FORMAT_ETC2_RGB8;
1211    case PIPE_FORMAT_ETC2_SRGB8A1:
1212       return PIPE_FORMAT_ETC2_RGB8A1;
1213    case PIPE_FORMAT_ETC2_SRGBA8:
1214       return PIPE_FORMAT_ETC2_RGBA8;
1215    case PIPE_FORMAT_ASTC_4x4_SRGB:
1216       return PIPE_FORMAT_ASTC_4x4;
1217    case PIPE_FORMAT_ASTC_5x4_SRGB:
1218       return PIPE_FORMAT_ASTC_5x4;
1219    case PIPE_FORMAT_ASTC_5x5_SRGB:
1220       return PIPE_FORMAT_ASTC_5x5;
1221    case PIPE_FORMAT_ASTC_6x5_SRGB:
1222       return PIPE_FORMAT_ASTC_6x5;
1223    case PIPE_FORMAT_ASTC_6x6_SRGB:
1224       return PIPE_FORMAT_ASTC_6x6;
1225    case PIPE_FORMAT_ASTC_8x5_SRGB:
1226       return PIPE_FORMAT_ASTC_8x5;
1227    case PIPE_FORMAT_ASTC_8x6_SRGB:
1228       return PIPE_FORMAT_ASTC_8x6;
1229    case PIPE_FORMAT_ASTC_8x8_SRGB:
1230       return PIPE_FORMAT_ASTC_8x8;
1231    case PIPE_FORMAT_ASTC_10x5_SRGB:
1232       return PIPE_FORMAT_ASTC_10x5;
1233    case PIPE_FORMAT_ASTC_10x6_SRGB:
1234       return PIPE_FORMAT_ASTC_10x6;
1235    case PIPE_FORMAT_ASTC_10x8_SRGB:
1236       return PIPE_FORMAT_ASTC_10x8;
1237    case PIPE_FORMAT_ASTC_10x10_SRGB:
1238       return PIPE_FORMAT_ASTC_10x10;
1239    case PIPE_FORMAT_ASTC_12x10_SRGB:
1240       return PIPE_FORMAT_ASTC_12x10;
1241    case PIPE_FORMAT_ASTC_12x12_SRGB:
1242       return PIPE_FORMAT_ASTC_12x12;
1243    case PIPE_FORMAT_ASTC_3x3x3_SRGB:
1244       return PIPE_FORMAT_ASTC_3x3x3;
1245    case PIPE_FORMAT_ASTC_4x3x3_SRGB:
1246       return PIPE_FORMAT_ASTC_4x3x3;
1247    case PIPE_FORMAT_ASTC_4x4x3_SRGB:
1248       return PIPE_FORMAT_ASTC_4x4x3;
1249    case PIPE_FORMAT_ASTC_4x4x4_SRGB:
1250       return PIPE_FORMAT_ASTC_4x4x4;
1251    case PIPE_FORMAT_ASTC_5x4x4_SRGB:
1252       return PIPE_FORMAT_ASTC_5x4x4;
1253    case PIPE_FORMAT_ASTC_5x5x4_SRGB:
1254       return PIPE_FORMAT_ASTC_5x5x4;
1255    case PIPE_FORMAT_ASTC_5x5x5_SRGB:
1256       return PIPE_FORMAT_ASTC_5x5x5;
1257    case PIPE_FORMAT_ASTC_6x5x5_SRGB:
1258       return PIPE_FORMAT_ASTC_6x5x5;
1259    case PIPE_FORMAT_ASTC_6x6x5_SRGB:
1260       return PIPE_FORMAT_ASTC_6x6x5;
1261    case PIPE_FORMAT_ASTC_6x6x6_SRGB:
1262       return PIPE_FORMAT_ASTC_6x6x6;
1263    default:
1264       assert(!util_format_is_srgb(format));
1265       return format;
1266    }
1267 }
1268 
1269 /**
1270  * Given a depth-stencil format, return the corresponding stencil-only format.
1271  * For stencil-only formats, return the format unchanged.
1272  */
1273 static inline enum pipe_format
util_format_stencil_only(enum pipe_format format)1274 util_format_stencil_only(enum pipe_format format)
1275 {
1276    switch (format) {
1277    /* mask out the depth component */
1278    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
1279       return PIPE_FORMAT_X24S8_UINT;
1280    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
1281       return PIPE_FORMAT_S8X24_UINT;
1282    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
1283       return PIPE_FORMAT_X32_S8X24_UINT;
1284 
1285    /* stencil only formats */
1286    case PIPE_FORMAT_X24S8_UINT:
1287    case PIPE_FORMAT_S8X24_UINT:
1288    case PIPE_FORMAT_X32_S8X24_UINT:
1289    case PIPE_FORMAT_S8_UINT:
1290       return format;
1291 
1292    default:
1293       assert(0);
1294       return PIPE_FORMAT_NONE;
1295    }
1296 }
1297 
1298 static inline enum pipe_format
util_format_as_renderable(enum pipe_format format)1299 util_format_as_renderable(enum pipe_format format)
1300 {
1301    switch (util_format_get_blocksizebits(format)) {
1302    case 128:
1303       return PIPE_FORMAT_R32G32B32A32_UINT;
1304    case 96:
1305       return PIPE_FORMAT_R32G32B32_UINT;
1306    case 64:
1307       return PIPE_FORMAT_R32G32_UINT;
1308    case 48:
1309       return PIPE_FORMAT_R16G16B16_UINT;
1310    case 32:
1311       return PIPE_FORMAT_R32_UINT;
1312    case 24:
1313       return PIPE_FORMAT_R8G8B8_UINT;
1314    case 16:
1315       return PIPE_FORMAT_R16_UINT;
1316    case 8:
1317       return PIPE_FORMAT_R8_UINT;
1318    default:
1319       return PIPE_FORMAT_NONE;
1320    }
1321 }
1322 
1323 /**
1324  * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.
1325  * This is identity for non-intensity formats.
1326  */
1327 static inline enum pipe_format
util_format_intensity_to_red(enum pipe_format format)1328 util_format_intensity_to_red(enum pipe_format format)
1329 {
1330    switch (format) {
1331    case PIPE_FORMAT_I8_UNORM:
1332       return PIPE_FORMAT_R8_UNORM;
1333    case PIPE_FORMAT_I8_SNORM:
1334       return PIPE_FORMAT_R8_SNORM;
1335    case PIPE_FORMAT_I16_UNORM:
1336       return PIPE_FORMAT_R16_UNORM;
1337    case PIPE_FORMAT_I16_SNORM:
1338       return PIPE_FORMAT_R16_SNORM;
1339    case PIPE_FORMAT_I16_FLOAT:
1340       return PIPE_FORMAT_R16_FLOAT;
1341    case PIPE_FORMAT_I32_FLOAT:
1342       return PIPE_FORMAT_R32_FLOAT;
1343    case PIPE_FORMAT_I8_UINT:
1344       return PIPE_FORMAT_R8_UINT;
1345    case PIPE_FORMAT_I8_SINT:
1346       return PIPE_FORMAT_R8_SINT;
1347    case PIPE_FORMAT_I16_UINT:
1348       return PIPE_FORMAT_R16_UINT;
1349    case PIPE_FORMAT_I16_SINT:
1350       return PIPE_FORMAT_R16_SINT;
1351    case PIPE_FORMAT_I32_UINT:
1352       return PIPE_FORMAT_R32_UINT;
1353    case PIPE_FORMAT_I32_SINT:
1354       return PIPE_FORMAT_R32_SINT;
1355    default:
1356       assert(!util_format_is_intensity(format));
1357       return format;
1358    }
1359 }
1360 
1361 /**
1362  * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.
1363  * This is identity for non-luminance formats.
1364  */
1365 static inline enum pipe_format
util_format_luminance_to_red(enum pipe_format format)1366 util_format_luminance_to_red(enum pipe_format format)
1367 {
1368    switch (format) {
1369    case PIPE_FORMAT_L8_UNORM:
1370       return PIPE_FORMAT_R8_UNORM;
1371    case PIPE_FORMAT_L8_SNORM:
1372       return PIPE_FORMAT_R8_SNORM;
1373    case PIPE_FORMAT_L16_UNORM:
1374       return PIPE_FORMAT_R16_UNORM;
1375    case PIPE_FORMAT_L16_SNORM:
1376       return PIPE_FORMAT_R16_SNORM;
1377    case PIPE_FORMAT_L16_FLOAT:
1378       return PIPE_FORMAT_R16_FLOAT;
1379    case PIPE_FORMAT_L32_FLOAT:
1380       return PIPE_FORMAT_R32_FLOAT;
1381    case PIPE_FORMAT_L8_UINT:
1382       return PIPE_FORMAT_R8_UINT;
1383    case PIPE_FORMAT_L8_SINT:
1384       return PIPE_FORMAT_R8_SINT;
1385    case PIPE_FORMAT_L16_UINT:
1386       return PIPE_FORMAT_R16_UINT;
1387    case PIPE_FORMAT_L16_SINT:
1388       return PIPE_FORMAT_R16_SINT;
1389    case PIPE_FORMAT_L32_UINT:
1390       return PIPE_FORMAT_R32_UINT;
1391    case PIPE_FORMAT_L32_SINT:
1392       return PIPE_FORMAT_R32_SINT;
1393 
1394    case PIPE_FORMAT_LATC1_UNORM:
1395       return PIPE_FORMAT_RGTC1_UNORM;
1396    case PIPE_FORMAT_LATC1_SNORM:
1397       return PIPE_FORMAT_RGTC1_SNORM;
1398 
1399    case PIPE_FORMAT_L4A4_UNORM:
1400       return PIPE_FORMAT_R4A4_UNORM;
1401 
1402    case PIPE_FORMAT_L8A8_UNORM:
1403       return PIPE_FORMAT_R8A8_UNORM;
1404    case PIPE_FORMAT_L8A8_SNORM:
1405       return PIPE_FORMAT_R8A8_SNORM;
1406    case PIPE_FORMAT_L16A16_UNORM:
1407       return PIPE_FORMAT_R16A16_UNORM;
1408    case PIPE_FORMAT_L16A16_SNORM:
1409       return PIPE_FORMAT_R16A16_SNORM;
1410    case PIPE_FORMAT_L16A16_FLOAT:
1411       return PIPE_FORMAT_R16A16_FLOAT;
1412    case PIPE_FORMAT_L32A32_FLOAT:
1413       return PIPE_FORMAT_R32A32_FLOAT;
1414    case PIPE_FORMAT_L8A8_UINT:
1415       return PIPE_FORMAT_R8A8_UINT;
1416    case PIPE_FORMAT_L8A8_SINT:
1417       return PIPE_FORMAT_R8A8_SINT;
1418    case PIPE_FORMAT_L16A16_UINT:
1419       return PIPE_FORMAT_R16A16_UINT;
1420    case PIPE_FORMAT_L16A16_SINT:
1421       return PIPE_FORMAT_R16A16_SINT;
1422    case PIPE_FORMAT_L32A32_UINT:
1423       return PIPE_FORMAT_R32A32_UINT;
1424    case PIPE_FORMAT_L32A32_SINT:
1425       return PIPE_FORMAT_R32A32_SINT;
1426 
1427    case PIPE_FORMAT_L8_SRGB:
1428       return PIPE_FORMAT_R8_SRGB;
1429 
1430    case PIPE_FORMAT_L8A8_SRGB:
1431       return PIPE_FORMAT_R8G8_SRGB;
1432 
1433    /* We don't have compressed red-alpha variants for these. */
1434    case PIPE_FORMAT_LATC2_UNORM:
1435    case PIPE_FORMAT_LATC2_SNORM:
1436       return PIPE_FORMAT_NONE;
1437 
1438    default:
1439       assert(!util_format_is_luminance(format) &&
1440 	     !util_format_is_luminance_alpha(format));
1441       return format;
1442    }
1443 }
1444 
1445 static inline unsigned
util_format_get_num_planes(enum pipe_format format)1446 util_format_get_num_planes(enum pipe_format format)
1447 {
1448    switch (util_format_description(format)->layout) {
1449    case UTIL_FORMAT_LAYOUT_PLANAR3:
1450       return 3;
1451    case UTIL_FORMAT_LAYOUT_PLANAR2:
1452       return 2;
1453    default:
1454       return 1;
1455    }
1456 }
1457 
1458 static inline enum pipe_format
util_format_get_plane_format(enum pipe_format format,unsigned plane)1459 util_format_get_plane_format(enum pipe_format format, unsigned plane)
1460 {
1461    switch (format) {
1462    case PIPE_FORMAT_YV12:
1463    case PIPE_FORMAT_YV16:
1464    case PIPE_FORMAT_IYUV:
1465    case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
1466    case PIPE_FORMAT_Y8_U8_V8_444_UNORM:
1467    case PIPE_FORMAT_Y8_400_UNORM:
1468    case PIPE_FORMAT_R8_G8_B8_UNORM:
1469       return PIPE_FORMAT_R8_UNORM;
1470    case PIPE_FORMAT_NV12:
1471    case PIPE_FORMAT_Y8_U8V8_422_UNORM:
1472       return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_RG88_UNORM;
1473    case PIPE_FORMAT_NV21:
1474       return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_GR88_UNORM;
1475    case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1476    case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
1477    case PIPE_FORMAT_Y16_U16_V16_444_UNORM:
1478       return PIPE_FORMAT_R16_UNORM;
1479    case PIPE_FORMAT_P010:
1480    case PIPE_FORMAT_P012:
1481    case PIPE_FORMAT_P016:
1482    case PIPE_FORMAT_P030:
1483    case PIPE_FORMAT_Y16_U16V16_422_UNORM:
1484       return !plane ? PIPE_FORMAT_R16_UNORM : PIPE_FORMAT_R16G16_UNORM;
1485    default:
1486       return format;
1487    }
1488 }
1489 
1490 static inline unsigned
util_format_get_plane_width(enum pipe_format format,unsigned plane,unsigned width)1491 util_format_get_plane_width(enum pipe_format format, unsigned plane,
1492                             unsigned width)
1493 {
1494    switch (format) {
1495    case PIPE_FORMAT_YV12:
1496    case PIPE_FORMAT_YV16:
1497    case PIPE_FORMAT_IYUV:
1498    case PIPE_FORMAT_NV12:
1499    case PIPE_FORMAT_NV21:
1500    case PIPE_FORMAT_P010:
1501    case PIPE_FORMAT_P012:
1502    case PIPE_FORMAT_P016:
1503    case PIPE_FORMAT_P030:
1504    case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
1505    case PIPE_FORMAT_Y8_U8V8_422_UNORM:
1506    case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1507    case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
1508    case PIPE_FORMAT_Y16_U16V16_422_UNORM:
1509       return !plane ? width : (width + 1) / 2;
1510    default:
1511       return width;
1512    }
1513 }
1514 
1515 static inline unsigned
util_format_get_plane_height(enum pipe_format format,unsigned plane,unsigned height)1516 util_format_get_plane_height(enum pipe_format format, unsigned plane,
1517                              unsigned height)
1518 {
1519    switch (format) {
1520    case PIPE_FORMAT_YV12:
1521    case PIPE_FORMAT_IYUV:
1522    case PIPE_FORMAT_NV12:
1523    case PIPE_FORMAT_NV21:
1524    case PIPE_FORMAT_P010:
1525    case PIPE_FORMAT_P012:
1526    case PIPE_FORMAT_P016:
1527    case PIPE_FORMAT_P030:
1528    case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1529       return !plane ? height : (height + 1) / 2;
1530    case PIPE_FORMAT_YV16:
1531    default:
1532       return height;
1533    }
1534 }
1535 
1536 /**
1537  * Return the number of components stored.
1538  * Formats with block size != 1x1 will always have 1 component (the block).
1539  */
1540 static inline unsigned
util_format_get_nr_components(enum pipe_format format)1541 util_format_get_nr_components(enum pipe_format format)
1542 {
1543    const struct util_format_description *desc = util_format_description(format);
1544    return desc->nr_channels;
1545 }
1546 
1547 /**
1548  * Return the index of the first non-void channel
1549  * -1 if no non-void channels
1550  */
1551 static inline int
util_format_get_first_non_void_channel(enum pipe_format format)1552 util_format_get_first_non_void_channel(enum pipe_format format)
1553 {
1554    const struct util_format_description *desc = util_format_description(format);
1555    int i;
1556 
1557    for (i = 0; i < 4; i++)
1558       if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
1559          break;
1560 
1561    if (i == 4)
1562        return -1;
1563 
1564    return i;
1565 }
1566 
1567 /**
1568  * Whether this format is any 8-bit UNORM variant. Looser than
1569  * util_is_rgba8_variant (also includes alpha textures, for instance).
1570  */
1571 
1572 static inline bool
util_format_is_unorm8(const struct util_format_description * desc)1573 util_format_is_unorm8(const struct util_format_description *desc)
1574 {
1575    int c = util_format_get_first_non_void_channel(desc->format);
1576 
1577    if (c == -1)
1578       return false;
1579 
1580    return desc->is_unorm && desc->is_array && desc->channel[c].size == 8;
1581 }
1582 
1583 static inline void
util_format_unpack_z_float(enum pipe_format format,float * dst,const void * src,unsigned w)1584 util_format_unpack_z_float(enum pipe_format format, float *dst,
1585                            const void *src, unsigned w)
1586 {
1587    const struct util_format_unpack_description *desc =
1588       util_format_unpack_description(format);
1589 
1590    desc->unpack_z_float(dst, 0, (const uint8_t *)src, 0, w, 1);
1591 }
1592 
1593 static inline void
util_format_unpack_z_32unorm(enum pipe_format format,uint32_t * dst,const void * src,unsigned w)1594 util_format_unpack_z_32unorm(enum pipe_format format, uint32_t *dst,
1595                              const void *src, unsigned w)
1596 {
1597    const struct util_format_unpack_description *desc =
1598       util_format_unpack_description(format);
1599 
1600    desc->unpack_z_32unorm(dst, 0, (const uint8_t *)src, 0, w, 1);
1601 }
1602 
1603 static inline void
util_format_unpack_s_8uint(enum pipe_format format,uint8_t * dst,const void * src,unsigned w)1604 util_format_unpack_s_8uint(enum pipe_format format, uint8_t *dst,
1605                            const void *src, unsigned w)
1606 {
1607    const struct util_format_unpack_description *desc =
1608       util_format_unpack_description(format);
1609 
1610    desc->unpack_s_8uint(dst, 0, (const uint8_t *)src, 0, w, 1);
1611 }
1612 
1613 /**
1614  * Unpacks a row of color data to 32-bit RGBA, either integers for pure
1615  * integer formats (sign-extended for signed data), or 32-bit floats.
1616  */
1617 static inline void
util_format_unpack_rgba(enum pipe_format format,void * dst,const void * src,unsigned w)1618 util_format_unpack_rgba(enum pipe_format format, void *dst,
1619                         const void *src, unsigned w)
1620 {
1621    const struct util_format_unpack_description *desc =
1622       util_format_unpack_description(format);
1623 
1624    desc->unpack_rgba(dst, (const uint8_t *)src, w);
1625 }
1626 
1627 static inline void
util_format_pack_z_float(enum pipe_format format,void * dst,const float * src,unsigned w)1628 util_format_pack_z_float(enum pipe_format format, void *dst,
1629                          const float *src, unsigned w)
1630 {
1631    const struct util_format_pack_description *desc =
1632       util_format_pack_description(format);
1633 
1634    desc->pack_z_float((uint8_t *)dst, 0, src, 0, w, 1);
1635 }
1636 
1637 static inline void
util_format_pack_z_32unorm(enum pipe_format format,void * dst,const uint32_t * src,unsigned w)1638 util_format_pack_z_32unorm(enum pipe_format format, void *dst,
1639                            const uint32_t *src, unsigned w)
1640 {
1641    const struct util_format_pack_description *desc =
1642       util_format_pack_description(format);
1643 
1644    desc->pack_z_32unorm((uint8_t *)dst, 0, src, 0, w, 1);
1645 }
1646 
1647 static inline void
util_format_pack_s_8uint(enum pipe_format format,void * dst,const uint8_t * src,unsigned w)1648 util_format_pack_s_8uint(enum pipe_format format, void *dst,
1649                          const uint8_t *src, unsigned w)
1650 {
1651    const struct util_format_pack_description *desc =
1652       util_format_pack_description(format);
1653 
1654    desc->pack_s_8uint((uint8_t *)dst, 0, src, 0, w, 1);
1655 }
1656 
1657 /**
1658  * Packs a row of color data from 32-bit RGBA, either integers for pure
1659  * integer formats, or 32-bit floats.  Values are clamped to the packed
1660  * representation's range.
1661  */
1662 static inline void
util_format_pack_rgba(enum pipe_format format,void * dst,const void * src,unsigned w)1663 util_format_pack_rgba(enum pipe_format format, void *dst,
1664                         const void *src, unsigned w)
1665 {
1666    const struct util_format_pack_description *desc =
1667       util_format_pack_description(format);
1668 
1669    if (util_format_is_pure_uint(format))
1670       desc->pack_rgba_uint((uint8_t *)dst, 0, (const uint32_t *)src, 0, w, 1);
1671    else if (util_format_is_pure_sint(format))
1672       desc->pack_rgba_sint((uint8_t *)dst, 0, (const int32_t *)src, 0, w, 1);
1673    else
1674       desc->pack_rgba_float((uint8_t *)dst, 0, (const float *)src, 0, w, 1);
1675 }
1676 
1677 /*
1678  * Format access functions for subrectangles
1679  */
1680 
1681 void
1682 util_format_read_4(enum pipe_format format,
1683                    void *dst, unsigned dst_stride,
1684                    const void *src, unsigned src_stride,
1685                    unsigned x, unsigned y, unsigned w, unsigned h);
1686 
1687 void
1688 util_format_write_4(enum pipe_format format,
1689                     const void *src, unsigned src_stride,
1690                     void *dst, unsigned dst_stride,
1691                     unsigned x, unsigned y, unsigned w, unsigned h);
1692 
1693 void
1694 util_format_read_4ub(enum pipe_format format,
1695                      uint8_t *dst, unsigned dst_stride,
1696                      const void *src, unsigned src_stride,
1697                      unsigned x, unsigned y, unsigned w, unsigned h);
1698 
1699 void
1700 util_format_write_4ub(enum pipe_format format,
1701                       const uint8_t *src, unsigned src_stride,
1702                       void *dst, unsigned dst_stride,
1703                       unsigned x, unsigned y, unsigned w, unsigned h);
1704 
1705 void
1706 util_format_unpack_rgba_rect(enum pipe_format format,
1707                              void *dst, unsigned dst_stride,
1708                              const void *src, unsigned src_stride,
1709                              unsigned w, unsigned h);
1710 
1711 void
1712 util_format_unpack_rgba_8unorm_rect(enum pipe_format format,
1713                                     void *dst, unsigned dst_stride,
1714                                     const void *src, unsigned src_stride,
1715                                     unsigned w, unsigned h);
1716 
1717 /*
1718  * Generic format conversion;
1719  */
1720 
1721 bool
1722 util_format_fits_8unorm(const struct util_format_description *format_desc) ATTRIBUTE_CONST;
1723 
1724 bool
1725 util_format_translate(enum pipe_format dst_format,
1726                       void *dst, unsigned dst_stride,
1727                       unsigned dst_x, unsigned dst_y,
1728                       enum pipe_format src_format,
1729                       const void *src, unsigned src_stride,
1730                       unsigned src_x, unsigned src_y,
1731                       unsigned width, unsigned height);
1732 
1733 bool
1734 util_format_translate_3d(enum pipe_format dst_format,
1735                          void *dst, unsigned dst_stride,
1736                          uint64_t dst_slice_stride,
1737                          unsigned dst_x, unsigned dst_y,
1738                          unsigned dst_z,
1739                          enum pipe_format src_format,
1740                          const void *src, unsigned src_stride,
1741                          uint64_t src_slice_stride,
1742                          unsigned src_x, unsigned src_y,
1743                          unsigned src_z, unsigned width,
1744                          unsigned height, unsigned depth);
1745 
1746 /*
1747  * Swizzle operations.
1748  */
1749 
1750 /* Compose two sets of swizzles.
1751  * If V is a 4D vector and the function parameters represent functions that
1752  * swizzle vector components, this holds:
1753  *     swz2(swz1(V)) = dst(V)
1754  */
1755 void util_format_compose_swizzles(const unsigned char swz1[4],
1756                                   const unsigned char swz2[4],
1757                                   unsigned char dst[4]);
1758 
1759 /* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
1760  * to \param src and store the result in \param dst.
1761  * \param is_integer determines the value written for PIPE_SWIZZLE_1.
1762  */
1763 void util_format_apply_color_swizzle(union pipe_color_union *dst,
1764                                      const union pipe_color_union *src,
1765                                      const unsigned char swz[4],
1766                                      const bool is_integer);
1767 
1768 void pipe_swizzle_4f(float *dst, const float *src,
1769                             const unsigned char swz[4]);
1770 
1771 void util_format_unswizzle_4f(float *dst, const float *src,
1772                               const unsigned char swz[4]);
1773 
1774 enum pipe_format
1775 util_format_snorm_to_sint(enum pipe_format format) ATTRIBUTE_CONST;
1776 
1777 extern void
1778 util_copy_rect(void * dst, enum pipe_format format,
1779                unsigned dst_stride, unsigned dst_x, unsigned dst_y,
1780                unsigned width, unsigned height, const void * src,
1781                int src_stride, unsigned src_x, unsigned src_y);
1782 
1783 /**
1784  * If the format is RGB, return BGR. If the format is BGR, return RGB.
1785  * This may fail by returning PIPE_FORMAT_NONE.
1786  */
1787 enum pipe_format
1788 util_format_rgb_to_bgr(enum pipe_format format);
1789 
1790 /* Returns the pipe format with SNORM formats cast to UNORM, otherwise the original pipe format. */
1791 enum pipe_format
1792 util_format_snorm_to_unorm(enum pipe_format format);
1793 
1794 enum pipe_format
1795 util_format_rgbx_to_rgba(enum pipe_format format);
1796 
1797 /* Returns the pipe format for the given array type, bitsize and component count. */
1798 enum pipe_format
1799 util_format_get_array(const enum util_format_type type, const unsigned bits,
1800                       const unsigned nr_components, const bool normalized,
1801                       const bool pure_integer);
1802 
1803 #ifdef __cplusplus
1804 } // extern "C" {
1805 #endif
1806 
1807 #endif /* ! U_FORMAT_H */
1808