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