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