st/mesa: optionally apply texture swizzle to border color v2
[mesa.git] / src / gallium / auxiliary / util / u_format.h
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 "util/u_debug.h"
35
36 union pipe_color_union;
37
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43
44 /**
45 * Describe how to pack/unpack pixels into/from the prescribed format.
46 *
47 * XXX: This could be renamed to something like util_format_pack, or broke down
48 * in flags inside util_format_block that said exactly what we want.
49 */
50 enum util_format_layout {
51 /**
52 * Formats with util_format_block::width == util_format_block::height == 1
53 * that can be described as an ordinary data structure.
54 */
55 UTIL_FORMAT_LAYOUT_PLAIN = 0,
56
57 /**
58 * Formats with sub-sampled channels.
59 *
60 * This is for formats like YVYU where there is less than one sample per
61 * pixel.
62 */
63 UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
64
65 /**
66 * S3 Texture Compression formats.
67 */
68 UTIL_FORMAT_LAYOUT_S3TC = 4,
69
70 /**
71 * Red-Green Texture Compression formats.
72 */
73 UTIL_FORMAT_LAYOUT_RGTC = 5,
74
75 /**
76 * Ericsson Texture Compression
77 */
78 UTIL_FORMAT_LAYOUT_ETC = 6,
79
80 /**
81 * Everything else that doesn't fit in any of the above layouts.
82 */
83 UTIL_FORMAT_LAYOUT_OTHER = 7
84 };
85
86
87 struct util_format_block
88 {
89 /** Block width in pixels */
90 unsigned width;
91
92 /** Block height in pixels */
93 unsigned height;
94
95 /** Block size in bits */
96 unsigned bits;
97 };
98
99
100 enum util_format_type {
101 UTIL_FORMAT_TYPE_VOID = 0,
102 UTIL_FORMAT_TYPE_UNSIGNED = 1,
103 UTIL_FORMAT_TYPE_SIGNED = 2,
104 UTIL_FORMAT_TYPE_FIXED = 3,
105 UTIL_FORMAT_TYPE_FLOAT = 4
106 };
107
108
109 enum util_format_swizzle {
110 UTIL_FORMAT_SWIZZLE_X = 0,
111 UTIL_FORMAT_SWIZZLE_Y = 1,
112 UTIL_FORMAT_SWIZZLE_Z = 2,
113 UTIL_FORMAT_SWIZZLE_W = 3,
114 UTIL_FORMAT_SWIZZLE_0 = 4,
115 UTIL_FORMAT_SWIZZLE_1 = 5,
116 UTIL_FORMAT_SWIZZLE_NONE = 6,
117 UTIL_FORMAT_SWIZZLE_MAX = 7 /**< Number of enums counter (must be last) */
118 };
119
120
121 enum util_format_colorspace {
122 UTIL_FORMAT_COLORSPACE_RGB = 0,
123 UTIL_FORMAT_COLORSPACE_SRGB = 1,
124 UTIL_FORMAT_COLORSPACE_YUV = 2,
125 UTIL_FORMAT_COLORSPACE_ZS = 3
126 };
127
128
129 struct util_format_channel_description
130 {
131 unsigned type:5; /**< UTIL_FORMAT_TYPE_x */
132 unsigned normalized:1;
133 unsigned pure_integer:1;
134 unsigned size:9; /**< bits per channel */
135 };
136
137
138 struct util_format_description
139 {
140 enum pipe_format format;
141
142 const char *name;
143
144 /**
145 * Short name, striped of the prefix, lower case.
146 */
147 const char *short_name;
148
149 /**
150 * Pixel block dimensions.
151 */
152 struct util_format_block block;
153
154 enum util_format_layout layout;
155
156 /**
157 * The number of channels.
158 */
159 unsigned nr_channels:3;
160
161 /**
162 * Whether all channels have the same number of (whole) bytes and type.
163 */
164 unsigned is_array:1;
165
166 /**
167 * Whether the pixel format can be described as a bitfield structure.
168 *
169 * In particular:
170 * - pixel depth must be 8, 16, or 32 bits;
171 * - all channels must be unsigned, signed, or void
172 */
173 unsigned is_bitmask:1;
174
175 /**
176 * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
177 */
178 unsigned is_mixed:1;
179
180 /**
181 * Input channel description.
182 *
183 * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
184 */
185 struct util_format_channel_description channel[4];
186
187 /**
188 * Output channel swizzle.
189 *
190 * The order is either:
191 * - RGBA
192 * - YUV(A)
193 * - ZS
194 * depending on the colorspace.
195 */
196 unsigned char swizzle[4];
197
198 /**
199 * Colorspace transformation.
200 */
201 enum util_format_colorspace colorspace;
202
203 /**
204 * Unpack pixel blocks to R8G8B8A8_UNORM.
205 * Note: strides are in bytes.
206 *
207 * Only defined for non-depth-stencil formats.
208 */
209 void
210 (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
211 const uint8_t *src, unsigned src_stride,
212 unsigned width, unsigned height);
213
214 /**
215 * Pack pixel blocks from R8G8B8A8_UNORM.
216 * Note: strides are in bytes.
217 *
218 * Only defined for non-depth-stencil formats.
219 */
220 void
221 (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
222 const uint8_t *src, unsigned src_stride,
223 unsigned width, unsigned height);
224
225 /**
226 * Fetch a single pixel (i, j) from a block.
227 *
228 * XXX: Only defined for a very few select formats.
229 */
230 void
231 (*fetch_rgba_8unorm)(uint8_t *dst,
232 const uint8_t *src,
233 unsigned i, unsigned j);
234
235 /**
236 * Unpack pixel blocks to R32G32B32A32_FLOAT.
237 * Note: strides are in bytes.
238 *
239 * Only defined for non-depth-stencil formats.
240 */
241 void
242 (*unpack_rgba_float)(float *dst, unsigned dst_stride,
243 const uint8_t *src, unsigned src_stride,
244 unsigned width, unsigned height);
245
246 /**
247 * Pack pixel blocks from R32G32B32A32_FLOAT.
248 * Note: strides are in bytes.
249 *
250 * Only defined for non-depth-stencil formats.
251 */
252 void
253 (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride,
254 const float *src, unsigned src_stride,
255 unsigned width, unsigned height);
256
257 /**
258 * Fetch a single pixel (i, j) from a block.
259 *
260 * Only defined for non-depth-stencil and non-integer formats.
261 */
262 void
263 (*fetch_rgba_float)(float *dst,
264 const uint8_t *src,
265 unsigned i, unsigned j);
266
267 /**
268 * Unpack pixels to Z32_UNORM.
269 * Note: strides are in bytes.
270 *
271 * Only defined for depth formats.
272 */
273 void
274 (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride,
275 const uint8_t *src, unsigned src_stride,
276 unsigned width, unsigned height);
277
278 /**
279 * Pack pixels from Z32_FLOAT.
280 * Note: strides are in bytes.
281 *
282 * Only defined for depth formats.
283 */
284 void
285 (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride,
286 const uint32_t *src, unsigned src_stride,
287 unsigned width, unsigned height);
288
289 /**
290 * Unpack pixels to Z32_FLOAT.
291 * Note: strides are in bytes.
292 *
293 * Only defined for depth formats.
294 */
295 void
296 (*unpack_z_float)(float *dst, unsigned dst_stride,
297 const uint8_t *src, unsigned src_stride,
298 unsigned width, unsigned height);
299
300 /**
301 * Pack pixels from Z32_FLOAT.
302 * Note: strides are in bytes.
303 *
304 * Only defined for depth formats.
305 */
306 void
307 (*pack_z_float)(uint8_t *dst, unsigned dst_stride,
308 const float *src, unsigned src_stride,
309 unsigned width, unsigned height);
310
311 /**
312 * Unpack pixels to S8_UINT.
313 * Note: strides are in bytes.
314 *
315 * Only defined for stencil formats.
316 */
317 void
318 (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride,
319 const uint8_t *src, unsigned src_stride,
320 unsigned width, unsigned height);
321
322 /**
323 * Pack pixels from S8_UINT.
324 * Note: strides are in bytes.
325 *
326 * Only defined for stencil formats.
327 */
328 void
329 (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride,
330 const uint8_t *src, unsigned src_stride,
331 unsigned width, unsigned height);
332
333 /**
334 * Unpack pixel blocks to R32G32B32A32_UINT.
335 * Note: strides are in bytes.
336 *
337 * Only defined for INT formats.
338 */
339 void
340 (*unpack_rgba_uint)(unsigned *dst, unsigned dst_stride,
341 const uint8_t *src, unsigned src_stride,
342 unsigned width, unsigned height);
343
344 void
345 (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride,
346 const unsigned *src, unsigned src_stride,
347 unsigned width, unsigned height);
348
349 /**
350 * Unpack pixel blocks to R32G32B32A32_SINT.
351 * Note: strides are in bytes.
352 *
353 * Only defined for INT formats.
354 */
355 void
356 (*unpack_rgba_sint)(signed *dst, unsigned dst_stride,
357 const uint8_t *src, unsigned src_stride,
358 unsigned width, unsigned height);
359
360 void
361 (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride,
362 const int *src, unsigned src_stride,
363 unsigned width, unsigned height);
364
365 /**
366 * Fetch a single pixel (i, j) from a block.
367 *
368 * Only defined for unsigned (pure) integer formats.
369 */
370 void
371 (*fetch_rgba_uint)(uint32_t *dst,
372 const uint8_t *src,
373 unsigned i, unsigned j);
374
375 /**
376 * Fetch a single pixel (i, j) from a block.
377 *
378 * Only defined for signed (pure) integer formats.
379 */
380 void
381 (*fetch_rgba_sint)(int32_t *dst,
382 const uint8_t *src,
383 unsigned i, unsigned j);
384 };
385
386
387 extern const struct util_format_description
388 util_format_description_table[];
389
390
391 const struct util_format_description *
392 util_format_description(enum pipe_format format);
393
394
395 /*
396 * Format query functions.
397 */
398
399 static INLINE const char *
400 util_format_name(enum pipe_format format)
401 {
402 const struct util_format_description *desc = util_format_description(format);
403
404 assert(desc);
405 if (!desc) {
406 return "PIPE_FORMAT_???";
407 }
408
409 return desc->name;
410 }
411
412 static INLINE const char *
413 util_format_short_name(enum pipe_format format)
414 {
415 const struct util_format_description *desc = util_format_description(format);
416
417 assert(desc);
418 if (!desc) {
419 return "???";
420 }
421
422 return desc->short_name;
423 }
424
425 /**
426 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
427 */
428 static INLINE boolean
429 util_format_is_plain(enum pipe_format format)
430 {
431 const struct util_format_description *desc = util_format_description(format);
432
433 if (!format) {
434 return FALSE;
435 }
436
437 return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
438 }
439
440 static INLINE boolean
441 util_format_is_compressed(enum pipe_format format)
442 {
443 const struct util_format_description *desc = util_format_description(format);
444
445 assert(desc);
446 if (!desc) {
447 return FALSE;
448 }
449
450 switch (desc->layout) {
451 case UTIL_FORMAT_LAYOUT_S3TC:
452 case UTIL_FORMAT_LAYOUT_RGTC:
453 case UTIL_FORMAT_LAYOUT_ETC:
454 /* XXX add other formats in the future */
455 return TRUE;
456 default:
457 return FALSE;
458 }
459 }
460
461 static INLINE boolean
462 util_format_is_s3tc(enum pipe_format format)
463 {
464 const struct util_format_description *desc = util_format_description(format);
465
466 assert(desc);
467 if (!desc) {
468 return FALSE;
469 }
470
471 return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
472 }
473
474 static INLINE boolean
475 util_format_is_srgb(enum pipe_format format)
476 {
477 const struct util_format_description *desc = util_format_description(format);
478 return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
479 }
480
481 static INLINE boolean
482 util_format_has_depth(const struct util_format_description *desc)
483 {
484 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
485 desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE;
486 }
487
488 static INLINE boolean
489 util_format_has_stencil(const struct util_format_description *desc)
490 {
491 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
492 desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE;
493 }
494
495 static INLINE boolean
496 util_format_is_depth_or_stencil(enum pipe_format format)
497 {
498 const struct util_format_description *desc = util_format_description(format);
499
500 assert(desc);
501 if (!desc) {
502 return FALSE;
503 }
504
505 return util_format_has_depth(desc) ||
506 util_format_has_stencil(desc);
507 }
508
509 static INLINE boolean
510 util_format_is_depth_and_stencil(enum pipe_format format)
511 {
512 const struct util_format_description *desc = util_format_description(format);
513
514 assert(desc);
515 if (!desc) {
516 return FALSE;
517 }
518
519 return util_format_has_depth(desc) &&
520 util_format_has_stencil(desc);
521 }
522
523
524 /**
525 * Give the RGBA colormask of the channels that can be represented in this
526 * format.
527 *
528 * That is, the channels whose values are preserved.
529 */
530 static INLINE unsigned
531 util_format_colormask(const struct util_format_description *desc)
532 {
533 unsigned colormask;
534 unsigned chan;
535
536 switch (desc->colorspace) {
537 case UTIL_FORMAT_COLORSPACE_RGB:
538 case UTIL_FORMAT_COLORSPACE_SRGB:
539 case UTIL_FORMAT_COLORSPACE_YUV:
540 colormask = 0;
541 for (chan = 0; chan < 4; ++chan) {
542 if (desc->swizzle[chan] < 4) {
543 colormask |= (1 << chan);
544 }
545 }
546 return colormask;
547 case UTIL_FORMAT_COLORSPACE_ZS:
548 return 0;
549 default:
550 assert(0);
551 return 0;
552 }
553 }
554
555
556 /**
557 * Checks if color mask covers every channel for the specified format
558 *
559 * @param desc a format description to check colormask with
560 * @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA
561 */
562 static INLINE boolean
563 util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
564 {
565 return (~colormask & util_format_colormask(desc)) == 0;
566 }
567
568
569 boolean
570 util_format_is_float(enum pipe_format format);
571
572
573 boolean
574 util_format_has_alpha(enum pipe_format format);
575
576
577 boolean
578 util_format_is_luminance(enum pipe_format format);
579
580
581 boolean
582 util_format_is_luminance_alpha(enum pipe_format format);
583
584
585 boolean
586 util_format_is_intensity(enum pipe_format format);
587
588 boolean
589 util_format_is_pure_integer(enum pipe_format format);
590
591 boolean
592 util_format_is_pure_sint(enum pipe_format format);
593
594 boolean
595 util_format_is_pure_uint(enum pipe_format format);
596
597 /**
598 * Check if the src format can be blitted to the destination format with
599 * a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not
600 * the reverse.
601 */
602 boolean
603 util_is_format_compatible(const struct util_format_description *src_desc,
604 const struct util_format_description *dst_desc);
605
606 /**
607 * Whether the format is supported by Gallium for the given bindings.
608 * This covers S3TC textures and floating-point render targets.
609 */
610 boolean
611 util_format_is_supported(enum pipe_format format, unsigned bind);
612
613 /**
614 * Whether this format is a rgab8 variant.
615 *
616 * That is, any format that matches the
617 *
618 * PIPE_FORMAT_?8?8?8?8_UNORM
619 */
620 static INLINE boolean
621 util_format_is_rgba8_variant(const struct util_format_description *desc)
622 {
623 unsigned chan;
624
625 if(desc->block.width != 1 ||
626 desc->block.height != 1 ||
627 desc->block.bits != 32)
628 return FALSE;
629
630 for(chan = 0; chan < 4; ++chan) {
631 if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
632 desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
633 return FALSE;
634 if(desc->channel[chan].size != 8)
635 return FALSE;
636 }
637
638 return TRUE;
639 }
640
641
642 /**
643 * Return total bits needed for the pixel format per block.
644 */
645 static INLINE uint
646 util_format_get_blocksizebits(enum pipe_format format)
647 {
648 const struct util_format_description *desc = util_format_description(format);
649
650 assert(desc);
651 if (!desc) {
652 return 0;
653 }
654
655 return desc->block.bits;
656 }
657
658 /**
659 * Return bytes per block (not pixel) for the given format.
660 */
661 static INLINE uint
662 util_format_get_blocksize(enum pipe_format format)
663 {
664 uint bits = util_format_get_blocksizebits(format);
665
666 assert(bits % 8 == 0);
667
668 return bits / 8;
669 }
670
671 static INLINE uint
672 util_format_get_blockwidth(enum pipe_format format)
673 {
674 const struct util_format_description *desc = util_format_description(format);
675
676 assert(desc);
677 if (!desc) {
678 return 1;
679 }
680
681 return desc->block.width;
682 }
683
684 static INLINE uint
685 util_format_get_blockheight(enum pipe_format format)
686 {
687 const struct util_format_description *desc = util_format_description(format);
688
689 assert(desc);
690 if (!desc) {
691 return 1;
692 }
693
694 return desc->block.height;
695 }
696
697 static INLINE unsigned
698 util_format_get_nblocksx(enum pipe_format format,
699 unsigned x)
700 {
701 unsigned blockwidth = util_format_get_blockwidth(format);
702 return (x + blockwidth - 1) / blockwidth;
703 }
704
705 static INLINE unsigned
706 util_format_get_nblocksy(enum pipe_format format,
707 unsigned y)
708 {
709 unsigned blockheight = util_format_get_blockheight(format);
710 return (y + blockheight - 1) / blockheight;
711 }
712
713 static INLINE unsigned
714 util_format_get_nblocks(enum pipe_format format,
715 unsigned width,
716 unsigned height)
717 {
718 return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
719 }
720
721 static INLINE size_t
722 util_format_get_stride(enum pipe_format format,
723 unsigned width)
724 {
725 return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
726 }
727
728 static INLINE size_t
729 util_format_get_2d_size(enum pipe_format format,
730 size_t stride,
731 unsigned height)
732 {
733 return util_format_get_nblocksy(format, height) * stride;
734 }
735
736 static INLINE uint
737 util_format_get_component_bits(enum pipe_format format,
738 enum util_format_colorspace colorspace,
739 uint component)
740 {
741 const struct util_format_description *desc = util_format_description(format);
742 enum util_format_colorspace desc_colorspace;
743
744 assert(format);
745 if (!format) {
746 return 0;
747 }
748
749 assert(component < 4);
750
751 /* Treat RGB and SRGB as equivalent. */
752 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
753 colorspace = UTIL_FORMAT_COLORSPACE_RGB;
754 }
755 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
756 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
757 } else {
758 desc_colorspace = desc->colorspace;
759 }
760
761 if (desc_colorspace != colorspace) {
762 return 0;
763 }
764
765 switch (desc->swizzle[component]) {
766 case UTIL_FORMAT_SWIZZLE_X:
767 return desc->channel[0].size;
768 case UTIL_FORMAT_SWIZZLE_Y:
769 return desc->channel[1].size;
770 case UTIL_FORMAT_SWIZZLE_Z:
771 return desc->channel[2].size;
772 case UTIL_FORMAT_SWIZZLE_W:
773 return desc->channel[3].size;
774 default:
775 return 0;
776 }
777 }
778
779 /**
780 * Given a linear RGB colorspace format, return the corresponding SRGB
781 * format, or PIPE_FORMAT_NONE if none.
782 */
783 static INLINE enum pipe_format
784 util_format_srgb(enum pipe_format format)
785 {
786 switch (format) {
787 case PIPE_FORMAT_L8_UNORM:
788 return PIPE_FORMAT_L8_SRGB;
789 case PIPE_FORMAT_L8A8_UNORM:
790 return PIPE_FORMAT_L8A8_SRGB;
791 case PIPE_FORMAT_R8G8B8_UNORM:
792 return PIPE_FORMAT_R8G8B8_SRGB;
793 case PIPE_FORMAT_A8B8G8R8_UNORM:
794 return PIPE_FORMAT_A8B8G8R8_SRGB;
795 case PIPE_FORMAT_X8B8G8R8_UNORM:
796 return PIPE_FORMAT_X8B8G8R8_SRGB;
797 case PIPE_FORMAT_B8G8R8A8_UNORM:
798 return PIPE_FORMAT_B8G8R8A8_SRGB;
799 case PIPE_FORMAT_B8G8R8X8_UNORM:
800 return PIPE_FORMAT_B8G8R8X8_SRGB;
801 case PIPE_FORMAT_A8R8G8B8_UNORM:
802 return PIPE_FORMAT_A8R8G8B8_SRGB;
803 case PIPE_FORMAT_X8R8G8B8_UNORM:
804 return PIPE_FORMAT_X8R8G8B8_SRGB;
805 case PIPE_FORMAT_R8G8B8A8_UNORM:
806 return PIPE_FORMAT_R8G8B8A8_SRGB;
807 case PIPE_FORMAT_R8G8B8X8_UNORM:
808 return PIPE_FORMAT_R8G8B8X8_SRGB;
809 case PIPE_FORMAT_DXT1_RGB:
810 return PIPE_FORMAT_DXT1_SRGB;
811 case PIPE_FORMAT_DXT1_RGBA:
812 return PIPE_FORMAT_DXT1_SRGBA;
813 case PIPE_FORMAT_DXT3_RGBA:
814 return PIPE_FORMAT_DXT3_SRGBA;
815 case PIPE_FORMAT_DXT5_RGBA:
816 return PIPE_FORMAT_DXT5_SRGBA;
817 default:
818 return PIPE_FORMAT_NONE;
819 }
820 }
821
822 /**
823 * Given an sRGB format, return the corresponding linear colorspace format.
824 * For non sRGB formats, return the format unchanged.
825 */
826 static INLINE enum pipe_format
827 util_format_linear(enum pipe_format format)
828 {
829 switch (format) {
830 case PIPE_FORMAT_L8_SRGB:
831 return PIPE_FORMAT_L8_UNORM;
832 case PIPE_FORMAT_L8A8_SRGB:
833 return PIPE_FORMAT_L8A8_UNORM;
834 case PIPE_FORMAT_R8G8B8_SRGB:
835 return PIPE_FORMAT_R8G8B8_UNORM;
836 case PIPE_FORMAT_A8B8G8R8_SRGB:
837 return PIPE_FORMAT_A8B8G8R8_UNORM;
838 case PIPE_FORMAT_X8B8G8R8_SRGB:
839 return PIPE_FORMAT_X8B8G8R8_UNORM;
840 case PIPE_FORMAT_B8G8R8A8_SRGB:
841 return PIPE_FORMAT_B8G8R8A8_UNORM;
842 case PIPE_FORMAT_B8G8R8X8_SRGB:
843 return PIPE_FORMAT_B8G8R8X8_UNORM;
844 case PIPE_FORMAT_A8R8G8B8_SRGB:
845 return PIPE_FORMAT_A8R8G8B8_UNORM;
846 case PIPE_FORMAT_X8R8G8B8_SRGB:
847 return PIPE_FORMAT_X8R8G8B8_UNORM;
848 case PIPE_FORMAT_R8G8B8A8_SRGB:
849 return PIPE_FORMAT_R8G8B8A8_UNORM;
850 case PIPE_FORMAT_R8G8B8X8_SRGB:
851 return PIPE_FORMAT_R8G8B8X8_UNORM;
852 case PIPE_FORMAT_DXT1_SRGB:
853 return PIPE_FORMAT_DXT1_RGB;
854 case PIPE_FORMAT_DXT1_SRGBA:
855 return PIPE_FORMAT_DXT1_RGBA;
856 case PIPE_FORMAT_DXT3_SRGBA:
857 return PIPE_FORMAT_DXT3_RGBA;
858 case PIPE_FORMAT_DXT5_SRGBA:
859 return PIPE_FORMAT_DXT5_RGBA;
860 default:
861 return format;
862 }
863 }
864
865 /**
866 * Given a depth-stencil format, return the corresponding stencil-only format.
867 * For stencil-only formats, return the format unchanged.
868 */
869 static INLINE enum pipe_format
870 util_format_stencil_only(enum pipe_format format)
871 {
872 switch (format) {
873 /* mask out the depth component */
874 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
875 return PIPE_FORMAT_X24S8_UINT;
876 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
877 return PIPE_FORMAT_S8X24_UINT;
878 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
879 return PIPE_FORMAT_X32_S8X24_UINT;
880
881 /* stencil only formats */
882 case PIPE_FORMAT_X24S8_UINT:
883 case PIPE_FORMAT_S8X24_UINT:
884 case PIPE_FORMAT_X32_S8X24_UINT:
885 case PIPE_FORMAT_S8_UINT:
886 return format;
887
888 default:
889 assert(0);
890 return PIPE_FORMAT_NONE;
891 }
892 }
893
894 /**
895 * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.
896 * This is identity for non-intensity formats.
897 */
898 static INLINE enum pipe_format
899 util_format_intensity_to_red(enum pipe_format format)
900 {
901 switch (format) {
902 case PIPE_FORMAT_I8_UNORM:
903 return PIPE_FORMAT_R8_UNORM;
904 case PIPE_FORMAT_I8_SNORM:
905 return PIPE_FORMAT_R8_SNORM;
906 case PIPE_FORMAT_I16_UNORM:
907 return PIPE_FORMAT_R16_UNORM;
908 case PIPE_FORMAT_I16_SNORM:
909 return PIPE_FORMAT_R16_SNORM;
910 case PIPE_FORMAT_I16_FLOAT:
911 return PIPE_FORMAT_R16_FLOAT;
912 case PIPE_FORMAT_I32_FLOAT:
913 return PIPE_FORMAT_R32_FLOAT;
914 case PIPE_FORMAT_I8_UINT:
915 return PIPE_FORMAT_R8_UINT;
916 case PIPE_FORMAT_I8_SINT:
917 return PIPE_FORMAT_R8_SINT;
918 case PIPE_FORMAT_I16_UINT:
919 return PIPE_FORMAT_R16_UINT;
920 case PIPE_FORMAT_I16_SINT:
921 return PIPE_FORMAT_R16_SINT;
922 case PIPE_FORMAT_I32_UINT:
923 return PIPE_FORMAT_R32_UINT;
924 case PIPE_FORMAT_I32_SINT:
925 return PIPE_FORMAT_R32_SINT;
926 default:
927 assert(!util_format_is_intensity(format));
928 return format;
929 }
930 }
931
932 /**
933 * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.
934 * This is identity for non-luminance formats.
935 */
936 static INLINE enum pipe_format
937 util_format_luminance_to_red(enum pipe_format format)
938 {
939 switch (format) {
940 case PIPE_FORMAT_L8_UNORM:
941 return PIPE_FORMAT_R8_UNORM;
942 case PIPE_FORMAT_L8_SNORM:
943 return PIPE_FORMAT_R8_SNORM;
944 case PIPE_FORMAT_L16_UNORM:
945 return PIPE_FORMAT_R16_UNORM;
946 case PIPE_FORMAT_L16_SNORM:
947 return PIPE_FORMAT_R16_SNORM;
948 case PIPE_FORMAT_L16_FLOAT:
949 return PIPE_FORMAT_R16_FLOAT;
950 case PIPE_FORMAT_L32_FLOAT:
951 return PIPE_FORMAT_R32_FLOAT;
952 case PIPE_FORMAT_L8_UINT:
953 return PIPE_FORMAT_R8_UINT;
954 case PIPE_FORMAT_L8_SINT:
955 return PIPE_FORMAT_R8_SINT;
956 case PIPE_FORMAT_L16_UINT:
957 return PIPE_FORMAT_R16_UINT;
958 case PIPE_FORMAT_L16_SINT:
959 return PIPE_FORMAT_R16_SINT;
960 case PIPE_FORMAT_L32_UINT:
961 return PIPE_FORMAT_R32_UINT;
962 case PIPE_FORMAT_L32_SINT:
963 return PIPE_FORMAT_R32_SINT;
964
965 case PIPE_FORMAT_LATC1_UNORM:
966 return PIPE_FORMAT_RGTC1_UNORM;
967 case PIPE_FORMAT_LATC1_SNORM:
968 return PIPE_FORMAT_RGTC1_SNORM;
969
970 case PIPE_FORMAT_L4A4_UNORM:
971 /* XXX A4R4 is defined as x00y in u_format.csv */
972 return PIPE_FORMAT_A4R4_UNORM;
973
974 case PIPE_FORMAT_L8A8_UNORM:
975 return PIPE_FORMAT_R8A8_UNORM;
976 case PIPE_FORMAT_L8A8_SNORM:
977 return PIPE_FORMAT_R8A8_SNORM;
978 case PIPE_FORMAT_L16A16_UNORM:
979 return PIPE_FORMAT_R16A16_UNORM;
980 case PIPE_FORMAT_L16A16_SNORM:
981 return PIPE_FORMAT_R16A16_SNORM;
982 case PIPE_FORMAT_L16A16_FLOAT:
983 return PIPE_FORMAT_R16A16_FLOAT;
984 case PIPE_FORMAT_L32A32_FLOAT:
985 return PIPE_FORMAT_R32A32_FLOAT;
986 case PIPE_FORMAT_L8A8_UINT:
987 return PIPE_FORMAT_R8A8_UINT;
988 case PIPE_FORMAT_L8A8_SINT:
989 return PIPE_FORMAT_R8A8_SINT;
990 case PIPE_FORMAT_L16A16_UINT:
991 return PIPE_FORMAT_R16A16_UINT;
992 case PIPE_FORMAT_L16A16_SINT:
993 return PIPE_FORMAT_R16A16_SINT;
994 case PIPE_FORMAT_L32A32_UINT:
995 return PIPE_FORMAT_R32A32_UINT;
996 case PIPE_FORMAT_L32A32_SINT:
997 return PIPE_FORMAT_R32A32_SINT;
998
999 /* We don't have compressed red-alpha variants for these. */
1000 case PIPE_FORMAT_LATC2_UNORM:
1001 case PIPE_FORMAT_LATC2_SNORM:
1002 return PIPE_FORMAT_NONE;
1003
1004 default:
1005 assert(!util_format_is_luminance(format) &&
1006 !util_format_is_luminance_alpha(format));
1007 return format;
1008 }
1009 }
1010
1011 /**
1012 * Return the number of components stored.
1013 * Formats with block size != 1x1 will always have 1 component (the block).
1014 */
1015 static INLINE unsigned
1016 util_format_get_nr_components(enum pipe_format format)
1017 {
1018 const struct util_format_description *desc = util_format_description(format);
1019 return desc->nr_channels;
1020 }
1021
1022 /**
1023 * Return the index of the first non-void channel
1024 * -1 if no non-void channels
1025 */
1026 static INLINE int
1027 util_format_get_first_non_void_channel(enum pipe_format format)
1028 {
1029 const struct util_format_description *desc = util_format_description(format);
1030 int i;
1031
1032 for (i = 0; i < 4; i++)
1033 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
1034 break;
1035
1036 if (i == 4)
1037 return -1;
1038
1039 return i;
1040 }
1041
1042 /*
1043 * Format access functions.
1044 */
1045
1046 void
1047 util_format_read_4f(enum pipe_format format,
1048 float *dst, unsigned dst_stride,
1049 const void *src, unsigned src_stride,
1050 unsigned x, unsigned y, unsigned w, unsigned h);
1051
1052 void
1053 util_format_write_4f(enum pipe_format format,
1054 const float *src, unsigned src_stride,
1055 void *dst, unsigned dst_stride,
1056 unsigned x, unsigned y, unsigned w, unsigned h);
1057
1058 void
1059 util_format_read_4ub(enum pipe_format format,
1060 uint8_t *dst, unsigned dst_stride,
1061 const void *src, unsigned src_stride,
1062 unsigned x, unsigned y, unsigned w, unsigned h);
1063
1064 void
1065 util_format_write_4ub(enum pipe_format format,
1066 const uint8_t *src, unsigned src_stride,
1067 void *dst, unsigned dst_stride,
1068 unsigned x, unsigned y, unsigned w, unsigned h);
1069
1070 void
1071 util_format_read_4ui(enum pipe_format format,
1072 unsigned *dst, unsigned dst_stride,
1073 const void *src, unsigned src_stride,
1074 unsigned x, unsigned y, unsigned w, unsigned h);
1075
1076 void
1077 util_format_write_4ui(enum pipe_format format,
1078 const unsigned int *src, unsigned src_stride,
1079 void *dst, unsigned dst_stride,
1080 unsigned x, unsigned y, unsigned w, unsigned h);
1081
1082 void
1083 util_format_read_4i(enum pipe_format format,
1084 int *dst, unsigned dst_stride,
1085 const void *src, unsigned src_stride,
1086 unsigned x, unsigned y, unsigned w, unsigned h);
1087
1088 void
1089 util_format_write_4i(enum pipe_format format,
1090 const int *src, unsigned src_stride,
1091 void *dst, unsigned dst_stride,
1092 unsigned x, unsigned y, unsigned w, unsigned h);
1093
1094 /*
1095 * Generic format conversion;
1096 */
1097
1098 boolean
1099 util_format_fits_8unorm(const struct util_format_description *format_desc);
1100
1101 void
1102 util_format_translate(enum pipe_format dst_format,
1103 void *dst, unsigned dst_stride,
1104 unsigned dst_x, unsigned dst_y,
1105 enum pipe_format src_format,
1106 const void *src, unsigned src_stride,
1107 unsigned src_x, unsigned src_y,
1108 unsigned width, unsigned height);
1109
1110 /*
1111 * Swizzle operations.
1112 */
1113
1114 /* Compose two sets of swizzles.
1115 * If V is a 4D vector and the function parameters represent functions that
1116 * swizzle vector components, this holds:
1117 * swz2(swz1(V)) = dst(V)
1118 */
1119 void util_format_compose_swizzles(const unsigned char swz1[4],
1120 const unsigned char swz2[4],
1121 unsigned char dst[4]);
1122
1123 /* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
1124 * to \param src and store the result in \param dst.
1125 * \param is_integer determines the value written for PIPE_SWIZZLE_ONE.
1126 */
1127 void util_format_apply_color_swizzle(union pipe_color_union *dst,
1128 const union pipe_color_union *src,
1129 const unsigned char swz[4],
1130 const boolean is_integer);
1131
1132 void util_format_swizzle_4f(float *dst, const float *src,
1133 const unsigned char swz[4]);
1134
1135 void util_format_unswizzle_4f(float *dst, const float *src,
1136 const unsigned char swz[4]);
1137
1138 #ifdef __cplusplus
1139 } // extern "C" {
1140 #endif
1141
1142 #endif /* ! U_FORMAT_H */