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 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 45 /** 46 * Describe how to pack/unpack pixels into/from the prescribed format. 47 * 48 * XXX: This could be renamed to something like util_format_pack, or broke down 49 * in flags inside util_format_block that said exactly what we want. 50 */ 51 enum util_format_layout { 52 /** 53 * Formats with util_format_block::width == util_format_block::height == 1 54 * that can be described as an ordinary data structure. 55 */ 56 UTIL_FORMAT_LAYOUT_PLAIN = 0, 57 58 /** 59 * Formats with sub-sampled channels. 60 * 61 * This is for formats like YVYU where there is less than one sample per 62 * pixel. 63 */ 64 UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, 65 66 /** 67 * S3 Texture Compression formats. 68 */ 69 UTIL_FORMAT_LAYOUT_S3TC = 4, 70 71 /** 72 * Red-Green Texture Compression formats. 73 */ 74 UTIL_FORMAT_LAYOUT_RGTC = 5, 75 76 /** 77 * Ericsson Texture Compression 78 */ 79 UTIL_FORMAT_LAYOUT_ETC = 6, 80 81 /** 82 * BC6/7 Texture Compression 83 */ 84 UTIL_FORMAT_LAYOUT_BPTC = 7, 85 86 /** 87 * ASTC 88 */ 89 UTIL_FORMAT_LAYOUT_ASTC = 8, 90 91 /** 92 * Everything else that doesn't fit in any of the above layouts. 93 */ 94 UTIL_FORMAT_LAYOUT_OTHER = 9 95 }; 96 97 98 struct util_format_block 99 { 100 /** Block width in pixels */ 101 unsigned width; 102 103 /** Block height in pixels */ 104 unsigned height; 105 106 /** Block size in bits */ 107 unsigned bits; 108 }; 109 110 111 enum util_format_type { 112 UTIL_FORMAT_TYPE_VOID = 0, 113 UTIL_FORMAT_TYPE_UNSIGNED = 1, 114 UTIL_FORMAT_TYPE_SIGNED = 2, 115 UTIL_FORMAT_TYPE_FIXED = 3, 116 UTIL_FORMAT_TYPE_FLOAT = 4 117 }; 118 119 120 enum util_format_colorspace { 121 UTIL_FORMAT_COLORSPACE_RGB = 0, 122 UTIL_FORMAT_COLORSPACE_SRGB = 1, 123 UTIL_FORMAT_COLORSPACE_YUV = 2, 124 UTIL_FORMAT_COLORSPACE_ZS = 3 125 }; 126 127 128 struct util_format_channel_description 129 { 130 unsigned type:5; /**< UTIL_FORMAT_TYPE_x */ 131 unsigned normalized:1; 132 unsigned pure_integer:1; 133 unsigned size:9; /**< bits per channel */ 134 unsigned shift:16; /** number of bits from lsb */ 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, in the order XYZW. 182 * 183 * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats. 184 * 185 * If each channel is accessed as an individual N-byte value, X is always 186 * at the lowest address in memory, Y is always next, and so on. For all 187 * currently-defined formats, the N-byte value has native endianness. 188 * 189 * If instead a group of channels is accessed as a single N-byte value, 190 * the order of the channels within that value depends on endianness. 191 * For big-endian targets, X is the most significant subvalue, 192 * otherwise it is the least significant one. 193 * 194 * For example, if X is 8 bits and Y is 24 bits, the memory order is: 195 * 196 * 0 1 2 3 197 * little-endian: X Yl Ym Yu (l = lower, m = middle, u = upper) 198 * big-endian: X Yu Ym Yl 199 * 200 * If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is: 201 * 202 * 0 1 203 * msb lsb msb lsb 204 * little-endian: YYYXXXXX WZZZZZYY 205 * big-endian: XXXXXYYY YYZZZZZW 206 */ 207 struct util_format_channel_description channel[4]; 208 209 /** 210 * Output channel swizzle. 211 * 212 * The order is either: 213 * - RGBA 214 * - YUV(A) 215 * - ZS 216 * depending on the colorspace. 217 */ 218 unsigned char swizzle[4]; 219 220 /** 221 * Colorspace transformation. 222 */ 223 enum util_format_colorspace colorspace; 224 225 /** 226 * Unpack pixel blocks to R8G8B8A8_UNORM. 227 * Note: strides are in bytes. 228 * 229 * Only defined for non-depth-stencil formats. 230 */ 231 void 232 (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, 233 const uint8_t *src, unsigned src_stride, 234 unsigned width, unsigned height); 235 236 /** 237 * Pack pixel blocks from R8G8B8A8_UNORM. 238 * Note: strides are in bytes. 239 * 240 * Only defined for non-depth-stencil formats. 241 */ 242 void 243 (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, 244 const uint8_t *src, unsigned src_stride, 245 unsigned width, unsigned height); 246 247 /** 248 * Fetch a single pixel (i, j) from a block. 249 * 250 * XXX: Only defined for a very few select formats. 251 */ 252 void 253 (*fetch_rgba_8unorm)(uint8_t *dst, 254 const uint8_t *src, 255 unsigned i, unsigned j); 256 257 /** 258 * Unpack pixel blocks to R32G32B32A32_FLOAT. 259 * Note: strides are in bytes. 260 * 261 * Only defined for non-depth-stencil formats. 262 */ 263 void 264 (*unpack_rgba_float)(float *dst, unsigned dst_stride, 265 const uint8_t *src, unsigned src_stride, 266 unsigned width, unsigned height); 267 268 /** 269 * Pack pixel blocks from R32G32B32A32_FLOAT. 270 * Note: strides are in bytes. 271 * 272 * Only defined for non-depth-stencil formats. 273 */ 274 void 275 (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride, 276 const float *src, unsigned src_stride, 277 unsigned width, unsigned height); 278 279 /** 280 * Fetch a single pixel (i, j) from a block. 281 * 282 * Only defined for non-depth-stencil and non-integer formats. 283 */ 284 void 285 (*fetch_rgba_float)(float *dst, 286 const uint8_t *src, 287 unsigned i, unsigned j); 288 289 /** 290 * Unpack pixels to Z32_UNORM. 291 * Note: strides are in bytes. 292 * 293 * Only defined for depth formats. 294 */ 295 void 296 (*unpack_z_32unorm)(uint32_t *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_32unorm)(uint8_t *dst, unsigned dst_stride, 308 const uint32_t *src, unsigned src_stride, 309 unsigned width, unsigned height); 310 311 /** 312 * Unpack pixels to Z32_FLOAT. 313 * Note: strides are in bytes. 314 * 315 * Only defined for depth formats. 316 */ 317 void 318 (*unpack_z_float)(float *dst, unsigned dst_stride, 319 const uint8_t *src, unsigned src_stride, 320 unsigned width, unsigned height); 321 322 /** 323 * Pack pixels from Z32_FLOAT. 324 * Note: strides are in bytes. 325 * 326 * Only defined for depth formats. 327 */ 328 void 329 (*pack_z_float)(uint8_t *dst, unsigned dst_stride, 330 const float *src, unsigned src_stride, 331 unsigned width, unsigned height); 332 333 /** 334 * Unpack pixels to S8_UINT. 335 * Note: strides are in bytes. 336 * 337 * Only defined for stencil formats. 338 */ 339 void 340 (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride, 341 const uint8_t *src, unsigned src_stride, 342 unsigned width, unsigned height); 343 344 /** 345 * Pack pixels from S8_UINT. 346 * Note: strides are in bytes. 347 * 348 * Only defined for stencil formats. 349 */ 350 void 351 (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride, 352 const uint8_t *src, unsigned src_stride, 353 unsigned width, unsigned height); 354 355 /** 356 * Unpack pixel blocks to R32G32B32A32_UINT. 357 * Note: strides are in bytes. 358 * 359 * Only defined for INT formats. 360 */ 361 void 362 (*unpack_rgba_uint)(uint32_t *dst, unsigned dst_stride, 363 const uint8_t *src, unsigned src_stride, 364 unsigned width, unsigned height); 365 366 void 367 (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride, 368 const uint32_t *src, unsigned src_stride, 369 unsigned width, unsigned height); 370 371 /** 372 * Unpack pixel blocks to R32G32B32A32_SINT. 373 * Note: strides are in bytes. 374 * 375 * Only defined for INT formats. 376 */ 377 void 378 (*unpack_rgba_sint)(int32_t *dst, unsigned dst_stride, 379 const uint8_t *src, unsigned src_stride, 380 unsigned width, unsigned height); 381 382 void 383 (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride, 384 const int32_t *src, unsigned src_stride, 385 unsigned width, unsigned height); 386 387 /** 388 * Fetch a single pixel (i, j) from a block. 389 * 390 * Only defined for unsigned (pure) integer formats. 391 */ 392 void 393 (*fetch_rgba_uint)(uint32_t *dst, 394 const uint8_t *src, 395 unsigned i, unsigned j); 396 397 /** 398 * Fetch a single pixel (i, j) from a block. 399 * 400 * Only defined for signed (pure) integer formats. 401 */ 402 void 403 (*fetch_rgba_sint)(int32_t *dst, 404 const uint8_t *src, 405 unsigned i, unsigned j); 406 }; 407 408 409 extern const struct util_format_description 410 util_format_description_table[]; 411 412 413 const struct util_format_description * 414 util_format_description(enum pipe_format format); 415 416 417 /* 418 * Format query functions. 419 */ 420 421 static inline const char * 422 util_format_name(enum pipe_format format) 423 { 424 const struct util_format_description *desc = util_format_description(format); 425 426 assert(desc); 427 if (!desc) { 428 return "PIPE_FORMAT_???"; 429 } 430 431 return desc->name; 432 } 433 434 static inline const char * 435 util_format_short_name(enum pipe_format format) 436 { 437 const struct util_format_description *desc = util_format_description(format); 438 439 assert(desc); 440 if (!desc) { 441 return "???"; 442 } 443 444 return desc->short_name; 445 } 446 447 /** 448 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info. 449 */ 450 static inline boolean 451 util_format_is_plain(enum pipe_format format) 452 { 453 const struct util_format_description *desc = util_format_description(format); 454 455 if (!format) { 456 return FALSE; 457 } 458 459 return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE; 460 } 461 462 static inline boolean 463 util_format_is_compressed(enum pipe_format format) 464 { 465 const struct util_format_description *desc = util_format_description(format); 466 467 assert(desc); 468 if (!desc) { 469 return FALSE; 470 } 471 472 switch (desc->layout) { 473 case UTIL_FORMAT_LAYOUT_S3TC: 474 case UTIL_FORMAT_LAYOUT_RGTC: 475 case UTIL_FORMAT_LAYOUT_ETC: 476 case UTIL_FORMAT_LAYOUT_BPTC: 477 case UTIL_FORMAT_LAYOUT_ASTC: 478 /* XXX add other formats in the future */ 479 return TRUE; 480 default: 481 return FALSE; 482 } 483 } 484 485 static inline boolean 486 util_format_is_s3tc(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_S3TC ? TRUE : FALSE; 496 } 497 498 static inline boolean 499 util_format_is_etc(enum pipe_format format) 500 { 501 const struct util_format_description *desc = util_format_description(format); 502 503 assert(desc); 504 if (!desc) { 505 return FALSE; 506 } 507 508 return desc->layout == UTIL_FORMAT_LAYOUT_ETC ? TRUE : FALSE; 509 } 510 511 static inline boolean 512 util_format_is_srgb(enum pipe_format format) 513 { 514 const struct util_format_description *desc = util_format_description(format); 515 return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB; 516 } 517 518 static inline boolean 519 util_format_has_depth(const struct util_format_description *desc) 520 { 521 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && 522 desc->swizzle[0] != PIPE_SWIZZLE_NONE; 523 } 524 525 static inline boolean 526 util_format_has_stencil(const struct util_format_description *desc) 527 { 528 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && 529 desc->swizzle[1] != PIPE_SWIZZLE_NONE; 530 } 531 532 static inline boolean 533 util_format_is_depth_or_stencil(enum pipe_format format) 534 { 535 const struct util_format_description *desc = util_format_description(format); 536 537 assert(desc); 538 if (!desc) { 539 return FALSE; 540 } 541 542 return util_format_has_depth(desc) || 543 util_format_has_stencil(desc); 544 } 545 546 static inline boolean 547 util_format_is_depth_and_stencil(enum pipe_format format) 548 { 549 const struct util_format_description *desc = util_format_description(format); 550 551 assert(desc); 552 if (!desc) { 553 return FALSE; 554 } 555 556 return util_format_has_depth(desc) && 557 util_format_has_stencil(desc); 558 } 559 560 561 /** 562 * Calculates the depth format type based upon the incoming format description. 563 */ 564 static inline unsigned 565 util_get_depth_format_type(const struct util_format_description *desc) 566 { 567 unsigned depth_channel = desc->swizzle[0]; 568 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && 569 depth_channel != PIPE_SWIZZLE_NONE) { 570 return desc->channel[depth_channel].type; 571 } else { 572 return UTIL_FORMAT_TYPE_VOID; 573 } 574 } 575 576 577 /** 578 * Calculates the MRD for the depth format. MRD is used in depth bias 579 * for UNORM and unbound depth buffers. When the depth buffer is floating 580 * point, the depth bias calculation does not use the MRD. However, the 581 * default MRD will be 1.0 / ((1 << 24) - 1). 582 */ 583 double 584 util_get_depth_format_mrd(const struct util_format_description *desc); 585 586 587 /** 588 * Return whether this is an RGBA, Z, S, or combined ZS format. 589 * Useful for initializing pipe_blit_info::mask. 590 */ 591 static inline unsigned 592 util_format_get_mask(enum pipe_format format) 593 { 594 const struct util_format_description *desc = 595 util_format_description(format); 596 597 if (!desc) 598 return 0; 599 600 if (util_format_has_depth(desc)) { 601 if (util_format_has_stencil(desc)) { 602 return PIPE_MASK_ZS; 603 } else { 604 return PIPE_MASK_Z; 605 } 606 } else { 607 if (util_format_has_stencil(desc)) { 608 return PIPE_MASK_S; 609 } else { 610 return PIPE_MASK_RGBA; 611 } 612 } 613 } 614 615 /** 616 * Give the RGBA colormask of the channels that can be represented in this 617 * format. 618 * 619 * That is, the channels whose values are preserved. 620 */ 621 static inline unsigned 622 util_format_colormask(const struct util_format_description *desc) 623 { 624 unsigned colormask; 625 unsigned chan; 626 627 switch (desc->colorspace) { 628 case UTIL_FORMAT_COLORSPACE_RGB: 629 case UTIL_FORMAT_COLORSPACE_SRGB: 630 case UTIL_FORMAT_COLORSPACE_YUV: 631 colormask = 0; 632 for (chan = 0; chan < 4; ++chan) { 633 if (desc->swizzle[chan] < 4) { 634 colormask |= (1 << chan); 635 } 636 } 637 return colormask; 638 case UTIL_FORMAT_COLORSPACE_ZS: 639 return 0; 640 default: 641 assert(0); 642 return 0; 643 } 644 } 645 646 647 /** 648 * Checks if color mask covers every channel for the specified format 649 * 650 * @param desc a format description to check colormask with 651 * @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA 652 */ 653 static inline boolean 654 util_format_colormask_full(const struct util_format_description *desc, unsigned colormask) 655 { 656 return (~colormask & util_format_colormask(desc)) == 0; 657 } 658 659 660 boolean 661 util_format_is_float(enum pipe_format format); 662 663 664 boolean 665 util_format_has_alpha(enum pipe_format format); 666 667 668 boolean 669 util_format_is_luminance(enum pipe_format format); 670 671 boolean 672 util_format_is_alpha(enum pipe_format format); 673 674 boolean 675 util_format_is_luminance_alpha(enum pipe_format format); 676 677 678 boolean 679 util_format_is_intensity(enum pipe_format format); 680 681 boolean 682 util_format_is_subsampled_422(enum pipe_format format); 683 684 boolean 685 util_format_is_pure_integer(enum pipe_format format); 686 687 boolean 688 util_format_is_pure_sint(enum pipe_format format); 689 690 boolean 691 util_format_is_pure_uint(enum pipe_format format); 692 693 boolean 694 util_format_is_snorm(enum pipe_format format); 695 696 boolean 697 util_format_is_snorm8(enum pipe_format format); 698 699 /** 700 * Check if the src format can be blitted to the destination format with 701 * a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not 702 * the reverse. 703 */ 704 boolean 705 util_is_format_compatible(const struct util_format_description *src_desc, 706 const struct util_format_description *dst_desc); 707 708 /** 709 * Whether the format is supported by Gallium for the given bindings. 710 * This covers S3TC textures and floating-point render targets. 711 */ 712 boolean 713 util_format_is_supported(enum pipe_format format, unsigned bind); 714 715 /** 716 * Whether this format is a rgab8 variant. 717 * 718 * That is, any format that matches the 719 * 720 * PIPE_FORMAT_?8?8?8?8_UNORM 721 */ 722 static inline boolean 723 util_format_is_rgba8_variant(const struct util_format_description *desc) 724 { 725 unsigned chan; 726 727 if(desc->block.width != 1 || 728 desc->block.height != 1 || 729 desc->block.bits != 32) 730 return FALSE; 731 732 for(chan = 0; chan < 4; ++chan) { 733 if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED && 734 desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) 735 return FALSE; 736 if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED && 737 !desc->channel[chan].normalized) 738 return FALSE; 739 if(desc->channel[chan].size != 8) 740 return FALSE; 741 } 742 743 return TRUE; 744 } 745 746 747 /** 748 * Return total bits needed for the pixel format per block. 749 */ 750 static inline uint 751 util_format_get_blocksizebits(enum pipe_format format) 752 { 753 const struct util_format_description *desc = util_format_description(format); 754 755 assert(desc); 756 if (!desc) { 757 return 0; 758 } 759 760 return desc->block.bits; 761 } 762 763 /** 764 * Return bytes per block (not pixel) for the given format. 765 */ 766 static inline uint 767 util_format_get_blocksize(enum pipe_format format) 768 { 769 uint bits = util_format_get_blocksizebits(format); 770 uint bytes = bits / 8; 771 772 assert(bits % 8 == 0); 773 assert(bytes > 0); 774 if (bytes == 0) { 775 bytes = 1; 776 } 777 778 return bytes; 779 } 780 781 static inline uint 782 util_format_get_blockwidth(enum pipe_format format) 783 { 784 const struct util_format_description *desc = util_format_description(format); 785 786 assert(desc); 787 if (!desc) { 788 return 1; 789 } 790 791 return desc->block.width; 792 } 793 794 static inline uint 795 util_format_get_blockheight(enum pipe_format format) 796 { 797 const struct util_format_description *desc = util_format_description(format); 798 799 assert(desc); 800 if (!desc) { 801 return 1; 802 } 803 804 return desc->block.height; 805 } 806 807 static inline unsigned 808 util_format_get_nblocksx(enum pipe_format format, 809 unsigned x) 810 { 811 unsigned blockwidth = util_format_get_blockwidth(format); 812 return (x + blockwidth - 1) / blockwidth; 813 } 814 815 static inline unsigned 816 util_format_get_nblocksy(enum pipe_format format, 817 unsigned y) 818 { 819 unsigned blockheight = util_format_get_blockheight(format); 820 return (y + blockheight - 1) / blockheight; 821 } 822 823 static inline unsigned 824 util_format_get_nblocks(enum pipe_format format, 825 unsigned width, 826 unsigned height) 827 { 828 return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); 829 } 830 831 static inline size_t 832 util_format_get_stride(enum pipe_format format, 833 unsigned width) 834 { 835 return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); 836 } 837 838 static inline size_t 839 util_format_get_2d_size(enum pipe_format format, 840 size_t stride, 841 unsigned height) 842 { 843 return util_format_get_nblocksy(format, height) * stride; 844 } 845 846 static inline uint 847 util_format_get_component_bits(enum pipe_format format, 848 enum util_format_colorspace colorspace, 849 uint component) 850 { 851 const struct util_format_description *desc = util_format_description(format); 852 enum util_format_colorspace desc_colorspace; 853 854 assert(format); 855 if (!format) { 856 return 0; 857 } 858 859 assert(component < 4); 860 861 /* Treat RGB and SRGB as equivalent. */ 862 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 863 colorspace = UTIL_FORMAT_COLORSPACE_RGB; 864 } 865 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 866 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; 867 } else { 868 desc_colorspace = desc->colorspace; 869 } 870 871 if (desc_colorspace != colorspace) { 872 return 0; 873 } 874 875 switch (desc->swizzle[component]) { 876 case PIPE_SWIZZLE_X: 877 return desc->channel[0].size; 878 case PIPE_SWIZZLE_Y: 879 return desc->channel[1].size; 880 case PIPE_SWIZZLE_Z: 881 return desc->channel[2].size; 882 case PIPE_SWIZZLE_W: 883 return desc->channel[3].size; 884 default: 885 return 0; 886 } 887 } 888 889 /** 890 * Given a linear RGB colorspace format, return the corresponding SRGB 891 * format, or PIPE_FORMAT_NONE if none. 892 */ 893 static inline enum pipe_format 894 util_format_srgb(enum pipe_format format) 895 { 896 if (util_format_is_srgb(format)) 897 return format; 898 899 switch (format) { 900 case PIPE_FORMAT_L8_UNORM: 901 return PIPE_FORMAT_L8_SRGB; 902 case PIPE_FORMAT_L8A8_UNORM: 903 return PIPE_FORMAT_L8A8_SRGB; 904 case PIPE_FORMAT_R8G8B8_UNORM: 905 return PIPE_FORMAT_R8G8B8_SRGB; 906 case PIPE_FORMAT_A8B8G8R8_UNORM: 907 return PIPE_FORMAT_A8B8G8R8_SRGB; 908 case PIPE_FORMAT_X8B8G8R8_UNORM: 909 return PIPE_FORMAT_X8B8G8R8_SRGB; 910 case PIPE_FORMAT_B8G8R8A8_UNORM: 911 return PIPE_FORMAT_B8G8R8A8_SRGB; 912 case PIPE_FORMAT_B8G8R8X8_UNORM: 913 return PIPE_FORMAT_B8G8R8X8_SRGB; 914 case PIPE_FORMAT_A8R8G8B8_UNORM: 915 return PIPE_FORMAT_A8R8G8B8_SRGB; 916 case PIPE_FORMAT_X8R8G8B8_UNORM: 917 return PIPE_FORMAT_X8R8G8B8_SRGB; 918 case PIPE_FORMAT_R8G8B8A8_UNORM: 919 return PIPE_FORMAT_R8G8B8A8_SRGB; 920 case PIPE_FORMAT_R8G8B8X8_UNORM: 921 return PIPE_FORMAT_R8G8B8X8_SRGB; 922 case PIPE_FORMAT_DXT1_RGB: 923 return PIPE_FORMAT_DXT1_SRGB; 924 case PIPE_FORMAT_DXT1_RGBA: 925 return PIPE_FORMAT_DXT1_SRGBA; 926 case PIPE_FORMAT_DXT3_RGBA: 927 return PIPE_FORMAT_DXT3_SRGBA; 928 case PIPE_FORMAT_DXT5_RGBA: 929 return PIPE_FORMAT_DXT5_SRGBA; 930 case PIPE_FORMAT_B5G6R5_UNORM: 931 return PIPE_FORMAT_B5G6R5_SRGB; 932 case PIPE_FORMAT_BPTC_RGBA_UNORM: 933 return PIPE_FORMAT_BPTC_SRGBA; 934 case PIPE_FORMAT_ASTC_4x4: 935 return PIPE_FORMAT_ASTC_4x4_SRGB; 936 case PIPE_FORMAT_ASTC_5x4: 937 return PIPE_FORMAT_ASTC_5x4_SRGB; 938 case PIPE_FORMAT_ASTC_5x5: 939 return PIPE_FORMAT_ASTC_5x5_SRGB; 940 case PIPE_FORMAT_ASTC_6x5: 941 return PIPE_FORMAT_ASTC_6x5_SRGB; 942 case PIPE_FORMAT_ASTC_6x6: 943 return PIPE_FORMAT_ASTC_6x6_SRGB; 944 case PIPE_FORMAT_ASTC_8x5: 945 return PIPE_FORMAT_ASTC_8x5_SRGB; 946 case PIPE_FORMAT_ASTC_8x6: 947 return PIPE_FORMAT_ASTC_8x6_SRGB; 948 case PIPE_FORMAT_ASTC_8x8: 949 return PIPE_FORMAT_ASTC_8x8_SRGB; 950 case PIPE_FORMAT_ASTC_10x5: 951 return PIPE_FORMAT_ASTC_10x5_SRGB; 952 case PIPE_FORMAT_ASTC_10x6: 953 return PIPE_FORMAT_ASTC_10x6_SRGB; 954 case PIPE_FORMAT_ASTC_10x8: 955 return PIPE_FORMAT_ASTC_10x8_SRGB; 956 case PIPE_FORMAT_ASTC_10x10: 957 return PIPE_FORMAT_ASTC_10x10_SRGB; 958 case PIPE_FORMAT_ASTC_12x10: 959 return PIPE_FORMAT_ASTC_12x10_SRGB; 960 case PIPE_FORMAT_ASTC_12x12: 961 return PIPE_FORMAT_ASTC_12x12_SRGB; 962 963 default: 964 return PIPE_FORMAT_NONE; 965 } 966 } 967 968 /** 969 * Given an sRGB format, return the corresponding linear colorspace format. 970 * For non sRGB formats, return the format unchanged. 971 */ 972 static inline enum pipe_format 973 util_format_linear(enum pipe_format format) 974 { 975 switch (format) { 976 case PIPE_FORMAT_L8_SRGB: 977 return PIPE_FORMAT_L8_UNORM; 978 case PIPE_FORMAT_L8A8_SRGB: 979 return PIPE_FORMAT_L8A8_UNORM; 980 case PIPE_FORMAT_R8G8B8_SRGB: 981 return PIPE_FORMAT_R8G8B8_UNORM; 982 case PIPE_FORMAT_A8B8G8R8_SRGB: 983 return PIPE_FORMAT_A8B8G8R8_UNORM; 984 case PIPE_FORMAT_X8B8G8R8_SRGB: 985 return PIPE_FORMAT_X8B8G8R8_UNORM; 986 case PIPE_FORMAT_B8G8R8A8_SRGB: 987 return PIPE_FORMAT_B8G8R8A8_UNORM; 988 case PIPE_FORMAT_B8G8R8X8_SRGB: 989 return PIPE_FORMAT_B8G8R8X8_UNORM; 990 case PIPE_FORMAT_A8R8G8B8_SRGB: 991 return PIPE_FORMAT_A8R8G8B8_UNORM; 992 case PIPE_FORMAT_X8R8G8B8_SRGB: 993 return PIPE_FORMAT_X8R8G8B8_UNORM; 994 case PIPE_FORMAT_R8G8B8A8_SRGB: 995 return PIPE_FORMAT_R8G8B8A8_UNORM; 996 case PIPE_FORMAT_R8G8B8X8_SRGB: 997 return PIPE_FORMAT_R8G8B8X8_UNORM; 998 case PIPE_FORMAT_DXT1_SRGB: 999 return PIPE_FORMAT_DXT1_RGB; 1000 case PIPE_FORMAT_DXT1_SRGBA: 1001 return PIPE_FORMAT_DXT1_RGBA; 1002 case PIPE_FORMAT_DXT3_SRGBA: 1003 return PIPE_FORMAT_DXT3_RGBA; 1004 case PIPE_FORMAT_DXT5_SRGBA: 1005 return PIPE_FORMAT_DXT5_RGBA; 1006 case PIPE_FORMAT_B5G6R5_SRGB: 1007 return PIPE_FORMAT_B5G6R5_UNORM; 1008 case PIPE_FORMAT_BPTC_SRGBA: 1009 return PIPE_FORMAT_BPTC_RGBA_UNORM; 1010 case PIPE_FORMAT_ASTC_4x4_SRGB: 1011 return PIPE_FORMAT_ASTC_4x4; 1012 case PIPE_FORMAT_ASTC_5x4_SRGB: 1013 return PIPE_FORMAT_ASTC_5x4; 1014 case PIPE_FORMAT_ASTC_5x5_SRGB: 1015 return PIPE_FORMAT_ASTC_5x5; 1016 case PIPE_FORMAT_ASTC_6x5_SRGB: 1017 return PIPE_FORMAT_ASTC_6x5; 1018 case PIPE_FORMAT_ASTC_6x6_SRGB: 1019 return PIPE_FORMAT_ASTC_6x6; 1020 case PIPE_FORMAT_ASTC_8x5_SRGB: 1021 return PIPE_FORMAT_ASTC_8x5; 1022 case PIPE_FORMAT_ASTC_8x6_SRGB: 1023 return PIPE_FORMAT_ASTC_8x6; 1024 case PIPE_FORMAT_ASTC_8x8_SRGB: 1025 return PIPE_FORMAT_ASTC_8x8; 1026 case PIPE_FORMAT_ASTC_10x5_SRGB: 1027 return PIPE_FORMAT_ASTC_10x5; 1028 case PIPE_FORMAT_ASTC_10x6_SRGB: 1029 return PIPE_FORMAT_ASTC_10x6; 1030 case PIPE_FORMAT_ASTC_10x8_SRGB: 1031 return PIPE_FORMAT_ASTC_10x8; 1032 case PIPE_FORMAT_ASTC_10x10_SRGB: 1033 return PIPE_FORMAT_ASTC_10x10; 1034 case PIPE_FORMAT_ASTC_12x10_SRGB: 1035 return PIPE_FORMAT_ASTC_12x10; 1036 case PIPE_FORMAT_ASTC_12x12_SRGB: 1037 return PIPE_FORMAT_ASTC_12x12; 1038 default: 1039 return format; 1040 } 1041 } 1042 1043 /** 1044 * Given a depth-stencil format, return the corresponding stencil-only format. 1045 * For stencil-only formats, return the format unchanged. 1046 */ 1047 static inline enum pipe_format 1048 util_format_stencil_only(enum pipe_format format) 1049 { 1050 switch (format) { 1051 /* mask out the depth component */ 1052 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 1053 return PIPE_FORMAT_X24S8_UINT; 1054 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 1055 return PIPE_FORMAT_S8X24_UINT; 1056 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 1057 return PIPE_FORMAT_X32_S8X24_UINT; 1058 1059 /* stencil only formats */ 1060 case PIPE_FORMAT_X24S8_UINT: 1061 case PIPE_FORMAT_S8X24_UINT: 1062 case PIPE_FORMAT_X32_S8X24_UINT: 1063 case PIPE_FORMAT_S8_UINT: 1064 return format; 1065 1066 default: 1067 assert(0); 1068 return PIPE_FORMAT_NONE; 1069 } 1070 } 1071 1072 /** 1073 * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*. 1074 * This is identity for non-intensity formats. 1075 */ 1076 static inline enum pipe_format 1077 util_format_intensity_to_red(enum pipe_format format) 1078 { 1079 switch (format) { 1080 case PIPE_FORMAT_I8_UNORM: 1081 return PIPE_FORMAT_R8_UNORM; 1082 case PIPE_FORMAT_I8_SNORM: 1083 return PIPE_FORMAT_R8_SNORM; 1084 case PIPE_FORMAT_I16_UNORM: 1085 return PIPE_FORMAT_R16_UNORM; 1086 case PIPE_FORMAT_I16_SNORM: 1087 return PIPE_FORMAT_R16_SNORM; 1088 case PIPE_FORMAT_I16_FLOAT: 1089 return PIPE_FORMAT_R16_FLOAT; 1090 case PIPE_FORMAT_I32_FLOAT: 1091 return PIPE_FORMAT_R32_FLOAT; 1092 case PIPE_FORMAT_I8_UINT: 1093 return PIPE_FORMAT_R8_UINT; 1094 case PIPE_FORMAT_I8_SINT: 1095 return PIPE_FORMAT_R8_SINT; 1096 case PIPE_FORMAT_I16_UINT: 1097 return PIPE_FORMAT_R16_UINT; 1098 case PIPE_FORMAT_I16_SINT: 1099 return PIPE_FORMAT_R16_SINT; 1100 case PIPE_FORMAT_I32_UINT: 1101 return PIPE_FORMAT_R32_UINT; 1102 case PIPE_FORMAT_I32_SINT: 1103 return PIPE_FORMAT_R32_SINT; 1104 default: 1105 assert(!util_format_is_intensity(format)); 1106 return format; 1107 } 1108 } 1109 1110 /** 1111 * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*. 1112 * This is identity for non-luminance formats. 1113 */ 1114 static inline enum pipe_format 1115 util_format_luminance_to_red(enum pipe_format format) 1116 { 1117 switch (format) { 1118 case PIPE_FORMAT_L8_UNORM: 1119 return PIPE_FORMAT_R8_UNORM; 1120 case PIPE_FORMAT_L8_SNORM: 1121 return PIPE_FORMAT_R8_SNORM; 1122 case PIPE_FORMAT_L16_UNORM: 1123 return PIPE_FORMAT_R16_UNORM; 1124 case PIPE_FORMAT_L16_SNORM: 1125 return PIPE_FORMAT_R16_SNORM; 1126 case PIPE_FORMAT_L16_FLOAT: 1127 return PIPE_FORMAT_R16_FLOAT; 1128 case PIPE_FORMAT_L32_FLOAT: 1129 return PIPE_FORMAT_R32_FLOAT; 1130 case PIPE_FORMAT_L8_UINT: 1131 return PIPE_FORMAT_R8_UINT; 1132 case PIPE_FORMAT_L8_SINT: 1133 return PIPE_FORMAT_R8_SINT; 1134 case PIPE_FORMAT_L16_UINT: 1135 return PIPE_FORMAT_R16_UINT; 1136 case PIPE_FORMAT_L16_SINT: 1137 return PIPE_FORMAT_R16_SINT; 1138 case PIPE_FORMAT_L32_UINT: 1139 return PIPE_FORMAT_R32_UINT; 1140 case PIPE_FORMAT_L32_SINT: 1141 return PIPE_FORMAT_R32_SINT; 1142 1143 case PIPE_FORMAT_LATC1_UNORM: 1144 return PIPE_FORMAT_RGTC1_UNORM; 1145 case PIPE_FORMAT_LATC1_SNORM: 1146 return PIPE_FORMAT_RGTC1_SNORM; 1147 1148 case PIPE_FORMAT_L4A4_UNORM: 1149 return PIPE_FORMAT_R4A4_UNORM; 1150 1151 case PIPE_FORMAT_L8A8_UNORM: 1152 return PIPE_FORMAT_R8A8_UNORM; 1153 case PIPE_FORMAT_L8A8_SNORM: 1154 return PIPE_FORMAT_R8A8_SNORM; 1155 case PIPE_FORMAT_L16A16_UNORM: 1156 return PIPE_FORMAT_R16A16_UNORM; 1157 case PIPE_FORMAT_L16A16_SNORM: 1158 return PIPE_FORMAT_R16A16_SNORM; 1159 case PIPE_FORMAT_L16A16_FLOAT: 1160 return PIPE_FORMAT_R16A16_FLOAT; 1161 case PIPE_FORMAT_L32A32_FLOAT: 1162 return PIPE_FORMAT_R32A32_FLOAT; 1163 case PIPE_FORMAT_L8A8_UINT: 1164 return PIPE_FORMAT_R8A8_UINT; 1165 case PIPE_FORMAT_L8A8_SINT: 1166 return PIPE_FORMAT_R8A8_SINT; 1167 case PIPE_FORMAT_L16A16_UINT: 1168 return PIPE_FORMAT_R16A16_UINT; 1169 case PIPE_FORMAT_L16A16_SINT: 1170 return PIPE_FORMAT_R16A16_SINT; 1171 case PIPE_FORMAT_L32A32_UINT: 1172 return PIPE_FORMAT_R32A32_UINT; 1173 case PIPE_FORMAT_L32A32_SINT: 1174 return PIPE_FORMAT_R32A32_SINT; 1175 1176 /* We don't have compressed red-alpha variants for these. */ 1177 case PIPE_FORMAT_LATC2_UNORM: 1178 case PIPE_FORMAT_LATC2_SNORM: 1179 return PIPE_FORMAT_NONE; 1180 1181 default: 1182 assert(!util_format_is_luminance(format) && 1183 !util_format_is_luminance_alpha(format)); 1184 return format; 1185 } 1186 } 1187 1188 /** 1189 * Return the number of components stored. 1190 * Formats with block size != 1x1 will always have 1 component (the block). 1191 */ 1192 static inline unsigned 1193 util_format_get_nr_components(enum pipe_format format) 1194 { 1195 const struct util_format_description *desc = util_format_description(format); 1196 return desc->nr_channels; 1197 } 1198 1199 /** 1200 * Return the index of the first non-void channel 1201 * -1 if no non-void channels 1202 */ 1203 static inline int 1204 util_format_get_first_non_void_channel(enum pipe_format format) 1205 { 1206 const struct util_format_description *desc = util_format_description(format); 1207 int i; 1208 1209 for (i = 0; i < 4; i++) 1210 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) 1211 break; 1212 1213 if (i == 4) 1214 return -1; 1215 1216 return i; 1217 } 1218 1219 /* 1220 * Format access functions. 1221 */ 1222 1223 void 1224 util_format_read_4f(enum pipe_format format, 1225 float *dst, unsigned dst_stride, 1226 const void *src, unsigned src_stride, 1227 unsigned x, unsigned y, unsigned w, unsigned h); 1228 1229 void 1230 util_format_write_4f(enum pipe_format format, 1231 const float *src, unsigned src_stride, 1232 void *dst, unsigned dst_stride, 1233 unsigned x, unsigned y, unsigned w, unsigned h); 1234 1235 void 1236 util_format_read_4ub(enum pipe_format format, 1237 uint8_t *dst, unsigned dst_stride, 1238 const void *src, unsigned src_stride, 1239 unsigned x, unsigned y, unsigned w, unsigned h); 1240 1241 void 1242 util_format_write_4ub(enum pipe_format format, 1243 const uint8_t *src, unsigned src_stride, 1244 void *dst, unsigned dst_stride, 1245 unsigned x, unsigned y, unsigned w, unsigned h); 1246 1247 void 1248 util_format_read_4ui(enum pipe_format format, 1249 unsigned *dst, unsigned dst_stride, 1250 const void *src, unsigned src_stride, 1251 unsigned x, unsigned y, unsigned w, unsigned h); 1252 1253 void 1254 util_format_write_4ui(enum pipe_format format, 1255 const unsigned int *src, unsigned src_stride, 1256 void *dst, unsigned dst_stride, 1257 unsigned x, unsigned y, unsigned w, unsigned h); 1258 1259 void 1260 util_format_read_4i(enum pipe_format format, 1261 int *dst, unsigned dst_stride, 1262 const void *src, unsigned src_stride, 1263 unsigned x, unsigned y, unsigned w, unsigned h); 1264 1265 void 1266 util_format_write_4i(enum pipe_format format, 1267 const int *src, unsigned src_stride, 1268 void *dst, unsigned dst_stride, 1269 unsigned x, unsigned y, unsigned w, unsigned h); 1270 1271 /* 1272 * Generic format conversion; 1273 */ 1274 1275 boolean 1276 util_format_fits_8unorm(const struct util_format_description *format_desc); 1277 1278 boolean 1279 util_format_translate(enum pipe_format dst_format, 1280 void *dst, unsigned dst_stride, 1281 unsigned dst_x, unsigned dst_y, 1282 enum pipe_format src_format, 1283 const void *src, unsigned src_stride, 1284 unsigned src_x, unsigned src_y, 1285 unsigned width, unsigned height); 1286 1287 boolean 1288 util_format_translate_3d(enum pipe_format dst_format, 1289 void *dst, unsigned dst_stride, 1290 unsigned dst_slice_stride, 1291 unsigned dst_x, unsigned dst_y, 1292 unsigned dst_z, 1293 enum pipe_format src_format, 1294 const void *src, unsigned src_stride, 1295 unsigned src_slice_stride, 1296 unsigned src_x, unsigned src_y, 1297 unsigned src_z, unsigned width, 1298 unsigned height, unsigned depth); 1299 1300 /* 1301 * Swizzle operations. 1302 */ 1303 1304 /* Compose two sets of swizzles. 1305 * If V is a 4D vector and the function parameters represent functions that 1306 * swizzle vector components, this holds: 1307 * swz2(swz1(V)) = dst(V) 1308 */ 1309 void util_format_compose_swizzles(const unsigned char swz1[4], 1310 const unsigned char swz2[4], 1311 unsigned char dst[4]); 1312 1313 /* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x) 1314 * to \param src and store the result in \param dst. 1315 * \param is_integer determines the value written for PIPE_SWIZZLE_1. 1316 */ 1317 void util_format_apply_color_swizzle(union pipe_color_union *dst, 1318 const union pipe_color_union *src, 1319 const unsigned char swz[4], 1320 const boolean is_integer); 1321 1322 void pipe_swizzle_4f(float *dst, const float *src, 1323 const unsigned char swz[4]); 1324 1325 void util_format_unswizzle_4f(float *dst, const float *src, 1326 const unsigned char swz[4]); 1327 1328 #ifdef __cplusplus 1329 } // extern "C" { 1330 #endif 1331 1332 #endif /* ! U_FORMAT_H */ 1333