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