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