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_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 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 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 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 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 /** 549 * Calculates the depth format type based upon the incoming format description. 550 */ 551 static inline unsigned 552 util_get_depth_format_type(const struct util_format_description *desc) 553 { 554 unsigned depth_channel = desc->swizzle[0]; 555 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && 556 depth_channel != PIPE_SWIZZLE_NONE) { 557 return desc->channel[depth_channel].type; 558 } else { 559 return UTIL_FORMAT_TYPE_VOID; 560 } 561 } 562 563 564 /** 565 * Calculates the MRD for the depth format. MRD is used in depth bias 566 * for UNORM and unbound depth buffers. When the depth buffer is floating 567 * point, the depth bias calculation does not use the MRD. However, the 568 * default MRD will be 1.0 / ((1 << 24) - 1). 569 */ 570 double 571 util_get_depth_format_mrd(const struct util_format_description *desc); 572 573 574 /** 575 * Return whether this is an RGBA, Z, S, or combined ZS format. 576 * Useful for initializing pipe_blit_info::mask. 577 */ 578 static inline unsigned 579 util_format_get_mask(enum pipe_format format) 580 { 581 const struct util_format_description *desc = 582 util_format_description(format); 583 584 if (!desc) 585 return 0; 586 587 if (util_format_has_depth(desc)) { 588 if (util_format_has_stencil(desc)) { 589 return PIPE_MASK_ZS; 590 } else { 591 return PIPE_MASK_Z; 592 } 593 } else { 594 if (util_format_has_stencil(desc)) { 595 return PIPE_MASK_S; 596 } else { 597 return PIPE_MASK_RGBA; 598 } 599 } 600 } 601 602 /** 603 * Give the RGBA colormask of the channels that can be represented in this 604 * format. 605 * 606 * That is, the channels whose values are preserved. 607 */ 608 static inline unsigned 609 util_format_colormask(const struct util_format_description *desc) 610 { 611 unsigned colormask; 612 unsigned chan; 613 614 switch (desc->colorspace) { 615 case UTIL_FORMAT_COLORSPACE_RGB: 616 case UTIL_FORMAT_COLORSPACE_SRGB: 617 case UTIL_FORMAT_COLORSPACE_YUV: 618 colormask = 0; 619 for (chan = 0; chan < 4; ++chan) { 620 if (desc->swizzle[chan] < 4) { 621 colormask |= (1 << chan); 622 } 623 } 624 return colormask; 625 case UTIL_FORMAT_COLORSPACE_ZS: 626 return 0; 627 default: 628 assert(0); 629 return 0; 630 } 631 } 632 633 634 /** 635 * Checks if color mask covers every channel for the specified format 636 * 637 * @param desc a format description to check colormask with 638 * @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA 639 */ 640 static inline boolean 641 util_format_colormask_full(const struct util_format_description *desc, unsigned colormask) 642 { 643 return (~colormask & util_format_colormask(desc)) == 0; 644 } 645 646 647 boolean 648 util_format_is_float(enum pipe_format format); 649 650 651 boolean 652 util_format_has_alpha(enum pipe_format format); 653 654 655 boolean 656 util_format_is_luminance(enum pipe_format format); 657 658 boolean 659 util_format_is_alpha(enum pipe_format format); 660 661 boolean 662 util_format_is_luminance_alpha(enum pipe_format format); 663 664 665 boolean 666 util_format_is_intensity(enum pipe_format format); 667 668 boolean 669 util_format_is_subsampled_422(enum pipe_format format); 670 671 boolean 672 util_format_is_pure_integer(enum pipe_format format); 673 674 boolean 675 util_format_is_pure_sint(enum pipe_format format); 676 677 boolean 678 util_format_is_pure_uint(enum pipe_format format); 679 680 boolean 681 util_format_is_snorm(enum pipe_format format); 682 683 boolean 684 util_format_is_snorm8(enum pipe_format format); 685 686 /** 687 * Check if the src format can be blitted to the destination format with 688 * a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not 689 * the reverse. 690 */ 691 boolean 692 util_is_format_compatible(const struct util_format_description *src_desc, 693 const struct util_format_description *dst_desc); 694 695 /** 696 * Whether the format is supported by Gallium for the given bindings. 697 * This covers S3TC textures and floating-point render targets. 698 */ 699 boolean 700 util_format_is_supported(enum pipe_format format, unsigned bind); 701 702 /** 703 * Whether this format is a rgab8 variant. 704 * 705 * That is, any format that matches the 706 * 707 * PIPE_FORMAT_?8?8?8?8_UNORM 708 */ 709 static inline boolean 710 util_format_is_rgba8_variant(const struct util_format_description *desc) 711 { 712 unsigned chan; 713 714 if(desc->block.width != 1 || 715 desc->block.height != 1 || 716 desc->block.bits != 32) 717 return FALSE; 718 719 for(chan = 0; chan < 4; ++chan) { 720 if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED && 721 desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) 722 return FALSE; 723 if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED && 724 !desc->channel[chan].normalized) 725 return FALSE; 726 if(desc->channel[chan].size != 8) 727 return FALSE; 728 } 729 730 return TRUE; 731 } 732 733 734 /** 735 * Return total bits needed for the pixel format per block. 736 */ 737 static inline uint 738 util_format_get_blocksizebits(enum pipe_format format) 739 { 740 const struct util_format_description *desc = util_format_description(format); 741 742 assert(desc); 743 if (!desc) { 744 return 0; 745 } 746 747 return desc->block.bits; 748 } 749 750 /** 751 * Return bytes per block (not pixel) for the given format. 752 */ 753 static inline uint 754 util_format_get_blocksize(enum pipe_format format) 755 { 756 uint bits = util_format_get_blocksizebits(format); 757 uint bytes = bits / 8; 758 759 assert(bits % 8 == 0); 760 assert(bytes > 0); 761 if (bytes == 0) { 762 bytes = 1; 763 } 764 765 return bytes; 766 } 767 768 static inline uint 769 util_format_get_blockwidth(enum pipe_format format) 770 { 771 const struct util_format_description *desc = util_format_description(format); 772 773 assert(desc); 774 if (!desc) { 775 return 1; 776 } 777 778 return desc->block.width; 779 } 780 781 static inline uint 782 util_format_get_blockheight(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.height; 792 } 793 794 static inline unsigned 795 util_format_get_nblocksx(enum pipe_format format, 796 unsigned x) 797 { 798 unsigned blockwidth = util_format_get_blockwidth(format); 799 return (x + blockwidth - 1) / blockwidth; 800 } 801 802 static inline unsigned 803 util_format_get_nblocksy(enum pipe_format format, 804 unsigned y) 805 { 806 unsigned blockheight = util_format_get_blockheight(format); 807 return (y + blockheight - 1) / blockheight; 808 } 809 810 static inline unsigned 811 util_format_get_nblocks(enum pipe_format format, 812 unsigned width, 813 unsigned height) 814 { 815 return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); 816 } 817 818 static inline size_t 819 util_format_get_stride(enum pipe_format format, 820 unsigned width) 821 { 822 return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); 823 } 824 825 static inline size_t 826 util_format_get_2d_size(enum pipe_format format, 827 size_t stride, 828 unsigned height) 829 { 830 return util_format_get_nblocksy(format, height) * stride; 831 } 832 833 static inline uint 834 util_format_get_component_bits(enum pipe_format format, 835 enum util_format_colorspace colorspace, 836 uint component) 837 { 838 const struct util_format_description *desc = util_format_description(format); 839 enum util_format_colorspace desc_colorspace; 840 841 assert(format); 842 if (!format) { 843 return 0; 844 } 845 846 assert(component < 4); 847 848 /* Treat RGB and SRGB as equivalent. */ 849 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 850 colorspace = UTIL_FORMAT_COLORSPACE_RGB; 851 } 852 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 853 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; 854 } else { 855 desc_colorspace = desc->colorspace; 856 } 857 858 if (desc_colorspace != colorspace) { 859 return 0; 860 } 861 862 switch (desc->swizzle[component]) { 863 case PIPE_SWIZZLE_X: 864 return desc->channel[0].size; 865 case PIPE_SWIZZLE_Y: 866 return desc->channel[1].size; 867 case PIPE_SWIZZLE_Z: 868 return desc->channel[2].size; 869 case PIPE_SWIZZLE_W: 870 return desc->channel[3].size; 871 default: 872 return 0; 873 } 874 } 875 876 /** 877 * Given a linear RGB colorspace format, return the corresponding SRGB 878 * format, or PIPE_FORMAT_NONE if none. 879 */ 880 static inline enum pipe_format 881 util_format_srgb(enum pipe_format format) 882 { 883 if (util_format_is_srgb(format)) 884 return format; 885 886 switch (format) { 887 case PIPE_FORMAT_L8_UNORM: 888 return PIPE_FORMAT_L8_SRGB; 889 case PIPE_FORMAT_L8A8_UNORM: 890 return PIPE_FORMAT_L8A8_SRGB; 891 case PIPE_FORMAT_R8G8B8_UNORM: 892 return PIPE_FORMAT_R8G8B8_SRGB; 893 case PIPE_FORMAT_A8B8G8R8_UNORM: 894 return PIPE_FORMAT_A8B8G8R8_SRGB; 895 case PIPE_FORMAT_X8B8G8R8_UNORM: 896 return PIPE_FORMAT_X8B8G8R8_SRGB; 897 case PIPE_FORMAT_B8G8R8A8_UNORM: 898 return PIPE_FORMAT_B8G8R8A8_SRGB; 899 case PIPE_FORMAT_B8G8R8X8_UNORM: 900 return PIPE_FORMAT_B8G8R8X8_SRGB; 901 case PIPE_FORMAT_A8R8G8B8_UNORM: 902 return PIPE_FORMAT_A8R8G8B8_SRGB; 903 case PIPE_FORMAT_X8R8G8B8_UNORM: 904 return PIPE_FORMAT_X8R8G8B8_SRGB; 905 case PIPE_FORMAT_R8G8B8A8_UNORM: 906 return PIPE_FORMAT_R8G8B8A8_SRGB; 907 case PIPE_FORMAT_R8G8B8X8_UNORM: 908 return PIPE_FORMAT_R8G8B8X8_SRGB; 909 case PIPE_FORMAT_DXT1_RGB: 910 return PIPE_FORMAT_DXT1_SRGB; 911 case PIPE_FORMAT_DXT1_RGBA: 912 return PIPE_FORMAT_DXT1_SRGBA; 913 case PIPE_FORMAT_DXT3_RGBA: 914 return PIPE_FORMAT_DXT3_SRGBA; 915 case PIPE_FORMAT_DXT5_RGBA: 916 return PIPE_FORMAT_DXT5_SRGBA; 917 case PIPE_FORMAT_B5G6R5_UNORM: 918 return PIPE_FORMAT_B5G6R5_SRGB; 919 case PIPE_FORMAT_BPTC_RGBA_UNORM: 920 return PIPE_FORMAT_BPTC_SRGBA; 921 case PIPE_FORMAT_ASTC_4x4: 922 return PIPE_FORMAT_ASTC_4x4_SRGB; 923 case PIPE_FORMAT_ASTC_5x4: 924 return PIPE_FORMAT_ASTC_5x4_SRGB; 925 case PIPE_FORMAT_ASTC_5x5: 926 return PIPE_FORMAT_ASTC_5x5_SRGB; 927 case PIPE_FORMAT_ASTC_6x5: 928 return PIPE_FORMAT_ASTC_6x5_SRGB; 929 case PIPE_FORMAT_ASTC_6x6: 930 return PIPE_FORMAT_ASTC_6x6_SRGB; 931 case PIPE_FORMAT_ASTC_8x5: 932 return PIPE_FORMAT_ASTC_8x5_SRGB; 933 case PIPE_FORMAT_ASTC_8x6: 934 return PIPE_FORMAT_ASTC_8x6_SRGB; 935 case PIPE_FORMAT_ASTC_8x8: 936 return PIPE_FORMAT_ASTC_8x8_SRGB; 937 case PIPE_FORMAT_ASTC_10x5: 938 return PIPE_FORMAT_ASTC_10x5_SRGB; 939 case PIPE_FORMAT_ASTC_10x6: 940 return PIPE_FORMAT_ASTC_10x6_SRGB; 941 case PIPE_FORMAT_ASTC_10x8: 942 return PIPE_FORMAT_ASTC_10x8_SRGB; 943 case PIPE_FORMAT_ASTC_10x10: 944 return PIPE_FORMAT_ASTC_10x10_SRGB; 945 case PIPE_FORMAT_ASTC_12x10: 946 return PIPE_FORMAT_ASTC_12x10_SRGB; 947 case PIPE_FORMAT_ASTC_12x12: 948 return PIPE_FORMAT_ASTC_12x12_SRGB; 949 950 default: 951 return PIPE_FORMAT_NONE; 952 } 953 } 954 955 /** 956 * Given an sRGB format, return the corresponding linear colorspace format. 957 * For non sRGB formats, return the format unchanged. 958 */ 959 static inline enum pipe_format 960 util_format_linear(enum pipe_format format) 961 { 962 switch (format) { 963 case PIPE_FORMAT_L8_SRGB: 964 return PIPE_FORMAT_L8_UNORM; 965 case PIPE_FORMAT_L8A8_SRGB: 966 return PIPE_FORMAT_L8A8_UNORM; 967 case PIPE_FORMAT_R8G8B8_SRGB: 968 return PIPE_FORMAT_R8G8B8_UNORM; 969 case PIPE_FORMAT_A8B8G8R8_SRGB: 970 return PIPE_FORMAT_A8B8G8R8_UNORM; 971 case PIPE_FORMAT_X8B8G8R8_SRGB: 972 return PIPE_FORMAT_X8B8G8R8_UNORM; 973 case PIPE_FORMAT_B8G8R8A8_SRGB: 974 return PIPE_FORMAT_B8G8R8A8_UNORM; 975 case PIPE_FORMAT_B8G8R8X8_SRGB: 976 return PIPE_FORMAT_B8G8R8X8_UNORM; 977 case PIPE_FORMAT_A8R8G8B8_SRGB: 978 return PIPE_FORMAT_A8R8G8B8_UNORM; 979 case PIPE_FORMAT_X8R8G8B8_SRGB: 980 return PIPE_FORMAT_X8R8G8B8_UNORM; 981 case PIPE_FORMAT_R8G8B8A8_SRGB: 982 return PIPE_FORMAT_R8G8B8A8_UNORM; 983 case PIPE_FORMAT_R8G8B8X8_SRGB: 984 return PIPE_FORMAT_R8G8B8X8_UNORM; 985 case PIPE_FORMAT_DXT1_SRGB: 986 return PIPE_FORMAT_DXT1_RGB; 987 case PIPE_FORMAT_DXT1_SRGBA: 988 return PIPE_FORMAT_DXT1_RGBA; 989 case PIPE_FORMAT_DXT3_SRGBA: 990 return PIPE_FORMAT_DXT3_RGBA; 991 case PIPE_FORMAT_DXT5_SRGBA: 992 return PIPE_FORMAT_DXT5_RGBA; 993 case PIPE_FORMAT_B5G6R5_SRGB: 994 return PIPE_FORMAT_B5G6R5_UNORM; 995 case PIPE_FORMAT_BPTC_SRGBA: 996 return PIPE_FORMAT_BPTC_RGBA_UNORM; 997 case PIPE_FORMAT_ASTC_4x4_SRGB: 998 return PIPE_FORMAT_ASTC_4x4; 999 case PIPE_FORMAT_ASTC_5x4_SRGB: 1000 return PIPE_FORMAT_ASTC_5x4; 1001 case PIPE_FORMAT_ASTC_5x5_SRGB: 1002 return PIPE_FORMAT_ASTC_5x5; 1003 case PIPE_FORMAT_ASTC_6x5_SRGB: 1004 return PIPE_FORMAT_ASTC_6x5; 1005 case PIPE_FORMAT_ASTC_6x6_SRGB: 1006 return PIPE_FORMAT_ASTC_6x6; 1007 case PIPE_FORMAT_ASTC_8x5_SRGB: 1008 return PIPE_FORMAT_ASTC_8x5; 1009 case PIPE_FORMAT_ASTC_8x6_SRGB: 1010 return PIPE_FORMAT_ASTC_8x6; 1011 case PIPE_FORMAT_ASTC_8x8_SRGB: 1012 return PIPE_FORMAT_ASTC_8x8; 1013 case PIPE_FORMAT_ASTC_10x5_SRGB: 1014 return PIPE_FORMAT_ASTC_10x5; 1015 case PIPE_FORMAT_ASTC_10x6_SRGB: 1016 return PIPE_FORMAT_ASTC_10x6; 1017 case PIPE_FORMAT_ASTC_10x8_SRGB: 1018 return PIPE_FORMAT_ASTC_10x8; 1019 case PIPE_FORMAT_ASTC_10x10_SRGB: 1020 return PIPE_FORMAT_ASTC_10x10; 1021 case PIPE_FORMAT_ASTC_12x10_SRGB: 1022 return PIPE_FORMAT_ASTC_12x10; 1023 case PIPE_FORMAT_ASTC_12x12_SRGB: 1024 return PIPE_FORMAT_ASTC_12x12; 1025 default: 1026 return format; 1027 } 1028 } 1029 1030 /** 1031 * Given a depth-stencil format, return the corresponding stencil-only format. 1032 * For stencil-only formats, return the format unchanged. 1033 */ 1034 static inline enum pipe_format 1035 util_format_stencil_only(enum pipe_format format) 1036 { 1037 switch (format) { 1038 /* mask out the depth component */ 1039 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 1040 return PIPE_FORMAT_X24S8_UINT; 1041 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 1042 return PIPE_FORMAT_S8X24_UINT; 1043 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 1044 return PIPE_FORMAT_X32_S8X24_UINT; 1045 1046 /* stencil only formats */ 1047 case PIPE_FORMAT_X24S8_UINT: 1048 case PIPE_FORMAT_S8X24_UINT: 1049 case PIPE_FORMAT_X32_S8X24_UINT: 1050 case PIPE_FORMAT_S8_UINT: 1051 return format; 1052 1053 default: 1054 assert(0); 1055 return PIPE_FORMAT_NONE; 1056 } 1057 } 1058 1059 /** 1060 * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*. 1061 * This is identity for non-intensity formats. 1062 */ 1063 static inline enum pipe_format 1064 util_format_intensity_to_red(enum pipe_format format) 1065 { 1066 switch (format) { 1067 case PIPE_FORMAT_I8_UNORM: 1068 return PIPE_FORMAT_R8_UNORM; 1069 case PIPE_FORMAT_I8_SNORM: 1070 return PIPE_FORMAT_R8_SNORM; 1071 case PIPE_FORMAT_I16_UNORM: 1072 return PIPE_FORMAT_R16_UNORM; 1073 case PIPE_FORMAT_I16_SNORM: 1074 return PIPE_FORMAT_R16_SNORM; 1075 case PIPE_FORMAT_I16_FLOAT: 1076 return PIPE_FORMAT_R16_FLOAT; 1077 case PIPE_FORMAT_I32_FLOAT: 1078 return PIPE_FORMAT_R32_FLOAT; 1079 case PIPE_FORMAT_I8_UINT: 1080 return PIPE_FORMAT_R8_UINT; 1081 case PIPE_FORMAT_I8_SINT: 1082 return PIPE_FORMAT_R8_SINT; 1083 case PIPE_FORMAT_I16_UINT: 1084 return PIPE_FORMAT_R16_UINT; 1085 case PIPE_FORMAT_I16_SINT: 1086 return PIPE_FORMAT_R16_SINT; 1087 case PIPE_FORMAT_I32_UINT: 1088 return PIPE_FORMAT_R32_UINT; 1089 case PIPE_FORMAT_I32_SINT: 1090 return PIPE_FORMAT_R32_SINT; 1091 default: 1092 assert(!util_format_is_intensity(format)); 1093 return format; 1094 } 1095 } 1096 1097 /** 1098 * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*. 1099 * This is identity for non-luminance formats. 1100 */ 1101 static inline enum pipe_format 1102 util_format_luminance_to_red(enum pipe_format format) 1103 { 1104 switch (format) { 1105 case PIPE_FORMAT_L8_UNORM: 1106 return PIPE_FORMAT_R8_UNORM; 1107 case PIPE_FORMAT_L8_SNORM: 1108 return PIPE_FORMAT_R8_SNORM; 1109 case PIPE_FORMAT_L16_UNORM: 1110 return PIPE_FORMAT_R16_UNORM; 1111 case PIPE_FORMAT_L16_SNORM: 1112 return PIPE_FORMAT_R16_SNORM; 1113 case PIPE_FORMAT_L16_FLOAT: 1114 return PIPE_FORMAT_R16_FLOAT; 1115 case PIPE_FORMAT_L32_FLOAT: 1116 return PIPE_FORMAT_R32_FLOAT; 1117 case PIPE_FORMAT_L8_UINT: 1118 return PIPE_FORMAT_R8_UINT; 1119 case PIPE_FORMAT_L8_SINT: 1120 return PIPE_FORMAT_R8_SINT; 1121 case PIPE_FORMAT_L16_UINT: 1122 return PIPE_FORMAT_R16_UINT; 1123 case PIPE_FORMAT_L16_SINT: 1124 return PIPE_FORMAT_R16_SINT; 1125 case PIPE_FORMAT_L32_UINT: 1126 return PIPE_FORMAT_R32_UINT; 1127 case PIPE_FORMAT_L32_SINT: 1128 return PIPE_FORMAT_R32_SINT; 1129 1130 case PIPE_FORMAT_LATC1_UNORM: 1131 return PIPE_FORMAT_RGTC1_UNORM; 1132 case PIPE_FORMAT_LATC1_SNORM: 1133 return PIPE_FORMAT_RGTC1_SNORM; 1134 1135 case PIPE_FORMAT_L4A4_UNORM: 1136 return PIPE_FORMAT_R4A4_UNORM; 1137 1138 case PIPE_FORMAT_L8A8_UNORM: 1139 return PIPE_FORMAT_R8A8_UNORM; 1140 case PIPE_FORMAT_L8A8_SNORM: 1141 return PIPE_FORMAT_R8A8_SNORM; 1142 case PIPE_FORMAT_L16A16_UNORM: 1143 return PIPE_FORMAT_R16A16_UNORM; 1144 case PIPE_FORMAT_L16A16_SNORM: 1145 return PIPE_FORMAT_R16A16_SNORM; 1146 case PIPE_FORMAT_L16A16_FLOAT: 1147 return PIPE_FORMAT_R16A16_FLOAT; 1148 case PIPE_FORMAT_L32A32_FLOAT: 1149 return PIPE_FORMAT_R32A32_FLOAT; 1150 case PIPE_FORMAT_L8A8_UINT: 1151 return PIPE_FORMAT_R8A8_UINT; 1152 case PIPE_FORMAT_L8A8_SINT: 1153 return PIPE_FORMAT_R8A8_SINT; 1154 case PIPE_FORMAT_L16A16_UINT: 1155 return PIPE_FORMAT_R16A16_UINT; 1156 case PIPE_FORMAT_L16A16_SINT: 1157 return PIPE_FORMAT_R16A16_SINT; 1158 case PIPE_FORMAT_L32A32_UINT: 1159 return PIPE_FORMAT_R32A32_UINT; 1160 case PIPE_FORMAT_L32A32_SINT: 1161 return PIPE_FORMAT_R32A32_SINT; 1162 1163 /* We don't have compressed red-alpha variants for these. */ 1164 case PIPE_FORMAT_LATC2_UNORM: 1165 case PIPE_FORMAT_LATC2_SNORM: 1166 return PIPE_FORMAT_NONE; 1167 1168 default: 1169 assert(!util_format_is_luminance(format) && 1170 !util_format_is_luminance_alpha(format)); 1171 return format; 1172 } 1173 } 1174 1175 /** 1176 * Return the number of components stored. 1177 * Formats with block size != 1x1 will always have 1 component (the block). 1178 */ 1179 static inline unsigned 1180 util_format_get_nr_components(enum pipe_format format) 1181 { 1182 const struct util_format_description *desc = util_format_description(format); 1183 return desc->nr_channels; 1184 } 1185 1186 /** 1187 * Return the index of the first non-void channel 1188 * -1 if no non-void channels 1189 */ 1190 static inline int 1191 util_format_get_first_non_void_channel(enum pipe_format format) 1192 { 1193 const struct util_format_description *desc = util_format_description(format); 1194 int i; 1195 1196 for (i = 0; i < 4; i++) 1197 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) 1198 break; 1199 1200 if (i == 4) 1201 return -1; 1202 1203 return i; 1204 } 1205 1206 /* 1207 * Format access functions. 1208 */ 1209 1210 void 1211 util_format_read_4f(enum pipe_format format, 1212 float *dst, unsigned dst_stride, 1213 const void *src, unsigned src_stride, 1214 unsigned x, unsigned y, unsigned w, unsigned h); 1215 1216 void 1217 util_format_write_4f(enum pipe_format format, 1218 const float *src, unsigned src_stride, 1219 void *dst, unsigned dst_stride, 1220 unsigned x, unsigned y, unsigned w, unsigned h); 1221 1222 void 1223 util_format_read_4ub(enum pipe_format format, 1224 uint8_t *dst, unsigned dst_stride, 1225 const void *src, unsigned src_stride, 1226 unsigned x, unsigned y, unsigned w, unsigned h); 1227 1228 void 1229 util_format_write_4ub(enum pipe_format format, 1230 const uint8_t *src, unsigned src_stride, 1231 void *dst, unsigned dst_stride, 1232 unsigned x, unsigned y, unsigned w, unsigned h); 1233 1234 void 1235 util_format_read_4ui(enum pipe_format format, 1236 unsigned *dst, unsigned dst_stride, 1237 const void *src, unsigned src_stride, 1238 unsigned x, unsigned y, unsigned w, unsigned h); 1239 1240 void 1241 util_format_write_4ui(enum pipe_format format, 1242 const unsigned int *src, unsigned src_stride, 1243 void *dst, unsigned dst_stride, 1244 unsigned x, unsigned y, unsigned w, unsigned h); 1245 1246 void 1247 util_format_read_4i(enum pipe_format format, 1248 int *dst, unsigned dst_stride, 1249 const void *src, unsigned src_stride, 1250 unsigned x, unsigned y, unsigned w, unsigned h); 1251 1252 void 1253 util_format_write_4i(enum pipe_format format, 1254 const int *src, unsigned src_stride, 1255 void *dst, unsigned dst_stride, 1256 unsigned x, unsigned y, unsigned w, unsigned h); 1257 1258 /* 1259 * Generic format conversion; 1260 */ 1261 1262 boolean 1263 util_format_fits_8unorm(const struct util_format_description *format_desc); 1264 1265 boolean 1266 util_format_translate(enum pipe_format dst_format, 1267 void *dst, unsigned dst_stride, 1268 unsigned dst_x, unsigned dst_y, 1269 enum pipe_format src_format, 1270 const void *src, unsigned src_stride, 1271 unsigned src_x, unsigned src_y, 1272 unsigned width, unsigned height); 1273 1274 boolean 1275 util_format_translate_3d(enum pipe_format dst_format, 1276 void *dst, unsigned dst_stride, 1277 unsigned dst_slice_stride, 1278 unsigned dst_x, unsigned dst_y, 1279 unsigned dst_z, 1280 enum pipe_format src_format, 1281 const void *src, unsigned src_stride, 1282 unsigned src_slice_stride, 1283 unsigned src_x, unsigned src_y, 1284 unsigned src_z, unsigned width, 1285 unsigned height, unsigned depth); 1286 1287 /* 1288 * Swizzle operations. 1289 */ 1290 1291 /* Compose two sets of swizzles. 1292 * If V is a 4D vector and the function parameters represent functions that 1293 * swizzle vector components, this holds: 1294 * swz2(swz1(V)) = dst(V) 1295 */ 1296 void util_format_compose_swizzles(const unsigned char swz1[4], 1297 const unsigned char swz2[4], 1298 unsigned char dst[4]); 1299 1300 /* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x) 1301 * to \param src and store the result in \param dst. 1302 * \param is_integer determines the value written for PIPE_SWIZZLE_1. 1303 */ 1304 void util_format_apply_color_swizzle(union pipe_color_union *dst, 1305 const union pipe_color_union *src, 1306 const unsigned char swz[4], 1307 const boolean is_integer); 1308 1309 void pipe_swizzle_4f(float *dst, const float *src, 1310 const unsigned char swz[4]); 1311 1312 void util_format_unswizzle_4f(float *dst, const float *src, 1313 const unsigned char swz[4]); 1314 1315 #ifdef __cplusplus 1316 } // extern "C" { 1317 #endif 1318 1319 #endif /* ! U_FORMAT_H */ 1320