1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2014 Intel Corporation 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 "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25#include "errors.h" 26#include "format_utils.h" 27#include "glformats.h" 28#include "format_pack.h" 29#include "format_unpack.h" 30 31const mesa_array_format RGBA32_FLOAT = 32 MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3); 33 34const mesa_array_format RGBA8_UBYTE = 35 MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3); 36 37const mesa_array_format RGBA32_UINT = 38 MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3); 39 40const mesa_array_format RGBA32_INT = 41 MESA_ARRAY_FORMAT(4, 1, 0, 0, 4, 0, 1, 2, 3); 42 43static void 44invert_swizzle(uint8_t dst[4], const uint8_t src[4]) 45{ 46 int i, j; 47 48 dst[0] = MESA_FORMAT_SWIZZLE_NONE; 49 dst[1] = MESA_FORMAT_SWIZZLE_NONE; 50 dst[2] = MESA_FORMAT_SWIZZLE_NONE; 51 dst[3] = MESA_FORMAT_SWIZZLE_NONE; 52 53 for (i = 0; i < 4; ++i) 54 for (j = 0; j < 4; ++j) 55 if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE) 56 dst[i] = j; 57} 58 59/* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This 60 * is used when we need to rebase a format to match a different 61 * base internal format. 62 * 63 * The rebase swizzle can be NULL, which means that no rebase is necessary, 64 * in which case the src to RGBA swizzle is copied to the output without 65 * changes. 66 * 67 * The resulting rebased swizzle and well as the input swizzles are 68 * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase 69 * is necessary. 70 */ 71static void 72compute_rebased_rgba_component_mapping(uint8_t *src2rgba, 73 uint8_t *rebase_swizzle, 74 uint8_t *rebased_src2rgba) 75{ 76 int i; 77 78 if (rebase_swizzle) { 79 for (i = 0; i < 4; i++) { 80 if (rebase_swizzle[i] > MESA_FORMAT_SWIZZLE_W) 81 rebased_src2rgba[i] = rebase_swizzle[i]; 82 else 83 rebased_src2rgba[i] = src2rgba[rebase_swizzle[i]]; 84 } 85 } else { 86 /* No rebase needed, so src2rgba is all that we need */ 87 memcpy(rebased_src2rgba, src2rgba, 4 * sizeof(uint8_t)); 88 } 89} 90 91/* Computes the final swizzle transform to apply from src to dst in a 92 * conversion that might involve a rebase swizzle. 93 * 94 * This is used to compute the swizzle transform to apply in conversions 95 * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle 96 * and possibly, a rebase swizzle. 97 * 98 * The final swizzle transform to apply (src2dst) when a rebase swizzle is 99 * involved is: src -> rgba -> base -> rgba -> dst 100 */ 101static void 102compute_src2dst_component_mapping(uint8_t *src2rgba, uint8_t *rgba2dst, 103 uint8_t *rebase_swizzle, uint8_t *src2dst) 104{ 105 int i; 106 107 if (!rebase_swizzle) { 108 for (i = 0; i < 4; i++) { 109 if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) { 110 src2dst[i] = rgba2dst[i]; 111 } else { 112 src2dst[i] = src2rgba[rgba2dst[i]]; 113 } 114 } 115 } else { 116 for (i = 0; i < 4; i++) { 117 if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) { 118 src2dst[i] = rgba2dst[i]; 119 } else if (rebase_swizzle[rgba2dst[i]] > MESA_FORMAT_SWIZZLE_W) { 120 src2dst[i] = rebase_swizzle[rgba2dst[i]]; 121 } else { 122 src2dst[i] = src2rgba[rebase_swizzle[rgba2dst[i]]]; 123 } 124 } 125 } 126} 127 128/** 129 * This function is used by clients of _mesa_format_convert to obtain 130 * the rebase swizzle to use in a format conversion based on the base 131 * format involved. 132 * 133 * \param baseFormat the base internal format involved in the conversion. 134 * \param map the rebase swizzle to consider 135 * 136 * This function computes 'map' as rgba -> baseformat -> rgba and returns true 137 * if the resulting swizzle transform is not the identity transform (thus, a 138 * rebase is needed). If the function returns false then a rebase swizzle 139 * is not necessary and the value of 'map' is undefined. In this situation 140 * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle' 141 * parameter. 142 */ 143bool 144_mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map) 145{ 146 uint8_t rgba2base[6], base2rgba[6]; 147 int i; 148 149 switch (baseFormat) { 150 case GL_ALPHA: 151 case GL_RED: 152 case GL_GREEN: 153 case GL_BLUE: 154 case GL_RG: 155 case GL_RGB: 156 case GL_BGR: 157 case GL_RGBA: 158 case GL_BGRA: 159 case GL_ABGR_EXT: 160 case GL_LUMINANCE: 161 case GL_INTENSITY: 162 case GL_LUMINANCE_ALPHA: 163 { 164 bool needRebase = false; 165 _mesa_compute_component_mapping(GL_RGBA, baseFormat, rgba2base); 166 _mesa_compute_component_mapping(baseFormat, GL_RGBA, base2rgba); 167 for (i = 0; i < 4; i++) { 168 if (base2rgba[i] > MESA_FORMAT_SWIZZLE_W) { 169 map[i] = base2rgba[i]; 170 } else { 171 map[i] = rgba2base[base2rgba[i]]; 172 } 173 if (map[i] != i) 174 needRebase = true; 175 } 176 return needRebase; 177 } 178 default: 179 unreachable("Unexpected base format"); 180 } 181} 182 183 184/** 185 * Special case conversion function to swap r/b channels from the source 186 * image to the dest image. 187 */ 188static void 189convert_ubyte_rgba_to_bgra(size_t width, size_t height, 190 const uint8_t *src, size_t src_stride, 191 uint8_t *dst, size_t dst_stride) 192{ 193 int row; 194 195 if (sizeof(void *) == 8 && 196 src_stride % 8 == 0 && 197 dst_stride % 8 == 0 && 198 (GLsizeiptr) src % 8 == 0 && 199 (GLsizeiptr) dst % 8 == 0) { 200 /* use 64-bit word to swizzle two 32-bit pixels. We need 8-byte 201 * alignment for src/dst addresses and strides. 202 */ 203 for (row = 0; row < height; row++) { 204 const GLuint64 *s = (const GLuint64 *) src; 205 GLuint64 *d = (GLuint64 *) dst; 206 int i; 207 for (i = 0; i < width/2; i++) { 208 d[i] = ( (s[i] & 0xff00ff00ff00ff00) | 209 ((s[i] & 0xff000000ff) << 16) | 210 ((s[i] & 0xff000000ff0000) >> 16)); 211 } 212 if (width & 1) { 213 /* handle the case of odd widths */ 214 const GLuint s = ((const GLuint *) src)[width - 1]; 215 GLuint *d = (GLuint *) dst + width - 1; 216 *d = ( (s & 0xff00ff00) | 217 ((s & 0xff) << 16) | 218 ((s & 0xff0000) >> 16)); 219 } 220 src += src_stride; 221 dst += dst_stride; 222 } 223 } else { 224 for (row = 0; row < height; row++) { 225 const GLuint *s = (const GLuint *) src; 226 GLuint *d = (GLuint *) dst; 227 int i; 228 for (i = 0; i < width; i++) { 229 d[i] = ( (s[i] & 0xff00ff00) | 230 ((s[i] & 0xff) << 16) | 231 ((s[i] & 0xff0000) >> 16)); 232 } 233 src += src_stride; 234 dst += dst_stride; 235 } 236 } 237} 238 239 240/** 241 * This can be used to convert between most color formats. 242 * 243 * Limitations: 244 * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats. 245 * - This function doesn't handle byte-swapping or transferOps, these should 246 * be handled by the caller. 247 * 248 * \param void_dst The address where converted color data will be stored. 249 * The caller must ensure that the buffer is large enough 250 * to hold the converted pixel data. 251 * \param dst_format The destination color format. It can be a mesa_format 252 * or a mesa_array_format represented as an uint32_t. 253 * \param dst_stride The stride of the destination format in bytes. 254 * \param void_src The address of the source color data to convert. 255 * \param src_format The source color format. It can be a mesa_format 256 * or a mesa_array_format represented as an uint32_t. 257 * \param src_stride The stride of the source format in bytes. 258 * \param width The width, in pixels, of the source image to convert. 259 * \param height The height, in pixels, of the source image to convert. 260 * \param rebase_swizzle A swizzle transform to apply during the conversion, 261 * typically used to match a different internal base 262 * format involved. NULL if no rebase transform is needed 263 * (i.e. the internal base format and the base format of 264 * the dst or the src -depending on whether we are doing 265 * an upload or a download respectively- are the same). 266 */ 267void 268_mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride, 269 void *void_src, uint32_t src_format, size_t src_stride, 270 size_t width, size_t height, uint8_t *rebase_swizzle) 271{ 272 uint8_t *dst = (uint8_t *)void_dst; 273 uint8_t *src = (uint8_t *)void_src; 274 mesa_array_format src_array_format, dst_array_format; 275 bool src_format_is_mesa_array_format, dst_format_is_mesa_array_format; 276 uint8_t src2dst[4], src2rgba[4], rgba2dst[4], dst2rgba[4]; 277 uint8_t rebased_src2rgba[4]; 278 enum mesa_array_format_datatype src_type = 0, dst_type = 0, common_type; 279 bool normalized, dst_integer, src_integer, is_signed; 280 int src_num_channels = 0, dst_num_channels = 0; 281 uint8_t (*tmp_ubyte)[4]; 282 float (*tmp_float)[4]; 283 uint32_t (*tmp_uint)[4]; 284 int bits; 285 size_t row; 286 287 if (_mesa_format_is_mesa_array_format(src_format)) { 288 src_format_is_mesa_array_format = true; 289 src_array_format = src_format; 290 } else { 291 assert(_mesa_is_format_color_format(src_format)); 292 src_format_is_mesa_array_format = false; 293 src_array_format = _mesa_format_to_array_format(src_format); 294 } 295 296 if (_mesa_format_is_mesa_array_format(dst_format)) { 297 dst_format_is_mesa_array_format = true; 298 dst_array_format = dst_format; 299 } else { 300 assert(_mesa_is_format_color_format(dst_format)); 301 dst_format_is_mesa_array_format = false; 302 dst_array_format = _mesa_format_to_array_format(dst_format); 303 } 304 305 /* First we see if we can implement the conversion with a direct pack 306 * or unpack. 307 * 308 * In this case we want to be careful when we need to apply a swizzle to 309 * match an internal base format, since in these cases a simple pack/unpack 310 * to the dst format from the src format may not match the requirements 311 * of the internal base format. For now we decide to be safe and 312 * avoid this path in these scenarios but in the future we may want to 313 * enable it for specific combinations that are known to work. 314 */ 315 if (!rebase_swizzle) { 316 /* Do a direct memcpy where possible */ 317 if ((dst_format_is_mesa_array_format && 318 src_format_is_mesa_array_format && 319 src_array_format == dst_array_format) || 320 src_format == dst_format) { 321 int format_size = _mesa_get_format_bytes(src_format); 322 for (row = 0; row < height; row++) { 323 memcpy(dst, src, width * format_size); 324 src += src_stride; 325 dst += dst_stride; 326 } 327 return; 328 } 329 330 /* Handle the cases where we can directly unpack */ 331 if (!src_format_is_mesa_array_format) { 332 if (dst_array_format == RGBA32_FLOAT) { 333 for (row = 0; row < height; ++row) { 334 _mesa_unpack_rgba_row(src_format, width, 335 src, (float (*)[4])dst); 336 src += src_stride; 337 dst += dst_stride; 338 } 339 return; 340 } else if (dst_array_format == RGBA8_UBYTE) { 341 assert(!_mesa_is_format_integer_color(src_format)); 342 for (row = 0; row < height; ++row) { 343 _mesa_unpack_ubyte_rgba_row(src_format, width, 344 src, (uint8_t (*)[4])dst); 345 src += src_stride; 346 dst += dst_stride; 347 } 348 return; 349 } else if (dst_array_format == RGBA32_UINT && 350 _mesa_is_format_unsigned(src_format)) { 351 assert(_mesa_is_format_integer_color(src_format)); 352 for (row = 0; row < height; ++row) { 353 _mesa_unpack_uint_rgba_row(src_format, width, 354 src, (uint32_t (*)[4])dst); 355 src += src_stride; 356 dst += dst_stride; 357 } 358 return; 359 } 360 } 361 362 /* Handle the cases where we can directly pack */ 363 if (!dst_format_is_mesa_array_format) { 364 if (src_array_format == RGBA32_FLOAT) { 365 for (row = 0; row < height; ++row) { 366 _mesa_pack_float_rgba_row(dst_format, width, 367 (const float (*)[4])src, dst); 368 src += src_stride; 369 dst += dst_stride; 370 } 371 return; 372 } else if (src_array_format == RGBA8_UBYTE) { 373 assert(!_mesa_is_format_integer_color(dst_format)); 374 375 if (dst_format == MESA_FORMAT_B8G8R8A8_UNORM) { 376 convert_ubyte_rgba_to_bgra(width, height, src, src_stride, 377 dst, dst_stride); 378 } 379 else { 380 for (row = 0; row < height; ++row) { 381 _mesa_pack_ubyte_rgba_row(dst_format, width, 382 (const uint8_t (*)[4])src, dst); 383 src += src_stride; 384 dst += dst_stride; 385 } 386 } 387 return; 388 } else if (src_array_format == RGBA32_UINT && 389 _mesa_is_format_unsigned(dst_format)) { 390 assert(_mesa_is_format_integer_color(dst_format)); 391 for (row = 0; row < height; ++row) { 392 _mesa_pack_uint_rgba_row(dst_format, width, 393 (const uint32_t (*)[4])src, dst); 394 src += src_stride; 395 dst += dst_stride; 396 } 397 return; 398 } 399 } 400 } 401 402 /* Handle conversions between array formats */ 403 normalized = false; 404 if (src_array_format) { 405 src_type = _mesa_array_format_get_datatype(src_array_format); 406 407 src_num_channels = _mesa_array_format_get_num_channels(src_array_format); 408 409 _mesa_array_format_get_swizzle(src_array_format, src2rgba); 410 411 normalized = _mesa_array_format_is_normalized(src_array_format); 412 } 413 414 if (dst_array_format) { 415 dst_type = _mesa_array_format_get_datatype(dst_array_format); 416 417 dst_num_channels = _mesa_array_format_get_num_channels(dst_array_format); 418 419 _mesa_array_format_get_swizzle(dst_array_format, dst2rgba); 420 invert_swizzle(rgba2dst, dst2rgba); 421 422 normalized |= _mesa_array_format_is_normalized(dst_array_format); 423 } 424 425 if (src_array_format && dst_array_format) { 426 assert(_mesa_array_format_is_normalized(src_array_format) == 427 _mesa_array_format_is_normalized(dst_array_format)); 428 429 compute_src2dst_component_mapping(src2rgba, rgba2dst, rebase_swizzle, 430 src2dst); 431 432 for (row = 0; row < height; ++row) { 433 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, 434 src, src_type, src_num_channels, 435 src2dst, normalized, width); 436 src += src_stride; 437 dst += dst_stride; 438 } 439 return; 440 } 441 442 /* At this point, we're fresh out of fast-paths and we need to convert 443 * to float, uint32, or, if we're lucky, uint8. 444 */ 445 dst_integer = false; 446 src_integer = false; 447 448 if (src_array_format) { 449 if (!_mesa_array_format_is_float(src_array_format) && 450 !_mesa_array_format_is_normalized(src_array_format)) 451 src_integer = true; 452 } else { 453 switch (_mesa_get_format_datatype(src_format)) { 454 case GL_UNSIGNED_INT: 455 case GL_INT: 456 src_integer = true; 457 break; 458 } 459 } 460 461 /* If the destination format is signed but the source is unsigned, then we 462 * don't loose any data by converting to a signed intermediate format above 463 * and beyond the precision that we loose in the conversion itself. If the 464 * destination is unsigned then, by using an unsigned intermediate format, 465 * we make the conversion function that converts from the source to the 466 * intermediate format take care of truncating at zero. The exception here 467 * is if the intermediate format is float, in which case the first 468 * conversion will leave it signed and the second conversion will truncate 469 * at zero. 470 */ 471 is_signed = false; 472 if (dst_array_format) { 473 if (!_mesa_array_format_is_float(dst_array_format) && 474 !_mesa_array_format_is_normalized(dst_array_format)) 475 dst_integer = true; 476 is_signed = _mesa_array_format_is_signed(dst_array_format); 477 bits = 8 * _mesa_array_format_get_type_size(dst_array_format); 478 } else { 479 switch (_mesa_get_format_datatype(dst_format)) { 480 case GL_UNSIGNED_NORMALIZED: 481 is_signed = false; 482 break; 483 case GL_SIGNED_NORMALIZED: 484 is_signed = true; 485 break; 486 case GL_FLOAT: 487 is_signed = true; 488 break; 489 case GL_UNSIGNED_INT: 490 is_signed = false; 491 dst_integer = true; 492 break; 493 case GL_INT: 494 is_signed = true; 495 dst_integer = true; 496 break; 497 } 498 bits = _mesa_get_format_max_bits(dst_format); 499 } 500 501 assert(src_integer == dst_integer); 502 503 if (src_integer && dst_integer) { 504 tmp_uint = malloc(width * height * sizeof(*tmp_uint)); 505 506 /* The [un]packing functions for unsigned datatypes treat the 32-bit 507 * integer array as signed for signed formats and as unsigned for 508 * unsigned formats. This is a bit of a problem if we ever convert from 509 * a signed to an unsigned format because the unsigned packing function 510 * doesn't know that the input is signed and will treat it as unsigned 511 * and not do the trunctation. The thing that saves us here is that all 512 * of the packed formats are unsigned, so we can just always use 513 * _mesa_swizzle_and_convert for signed formats, which is aware of the 514 * truncation problem. 515 */ 516 common_type = is_signed ? MESA_ARRAY_FORMAT_TYPE_INT : 517 MESA_ARRAY_FORMAT_TYPE_UINT; 518 if (src_array_format) { 519 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, 520 rebased_src2rgba); 521 for (row = 0; row < height; ++row) { 522 _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4, 523 src, src_type, src_num_channels, 524 rebased_src2rgba, normalized, width); 525 src += src_stride; 526 } 527 } else { 528 for (row = 0; row < height; ++row) { 529 _mesa_unpack_uint_rgba_row(src_format, width, 530 src, tmp_uint + row * width); 531 if (rebase_swizzle) 532 _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4, 533 tmp_uint + row * width, common_type, 4, 534 rebase_swizzle, false, width); 535 src += src_stride; 536 } 537 } 538 539 /* At this point, we have already done the truncation if the source is 540 * signed but the destination is unsigned, so no need to force the 541 * _mesa_swizzle_and_convert path. 542 */ 543 if (dst_format_is_mesa_array_format) { 544 for (row = 0; row < height; ++row) { 545 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, 546 tmp_uint + row * width, common_type, 4, 547 rgba2dst, normalized, width); 548 dst += dst_stride; 549 } 550 } else { 551 for (row = 0; row < height; ++row) { 552 _mesa_pack_uint_rgba_row(dst_format, width, 553 (const uint32_t (*)[4])tmp_uint + row * width, dst); 554 dst += dst_stride; 555 } 556 } 557 558 free(tmp_uint); 559 } else if (is_signed || bits > 8) { 560 tmp_float = malloc(width * height * sizeof(*tmp_float)); 561 562 if (src_format_is_mesa_array_format) { 563 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, 564 rebased_src2rgba); 565 for (row = 0; row < height; ++row) { 566 _mesa_swizzle_and_convert(tmp_float + row * width, 567 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, 568 src, src_type, src_num_channels, 569 rebased_src2rgba, normalized, width); 570 src += src_stride; 571 } 572 } else { 573 for (row = 0; row < height; ++row) { 574 _mesa_unpack_rgba_row(src_format, width, 575 src, tmp_float + row * width); 576 if (rebase_swizzle) 577 _mesa_swizzle_and_convert(tmp_float + row * width, 578 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, 579 tmp_float + row * width, 580 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, 581 rebase_swizzle, normalized, width); 582 src += src_stride; 583 } 584 } 585 586 if (dst_format_is_mesa_array_format) { 587 for (row = 0; row < height; ++row) { 588 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, 589 tmp_float + row * width, 590 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, 591 rgba2dst, normalized, width); 592 dst += dst_stride; 593 } 594 } else { 595 for (row = 0; row < height; ++row) { 596 _mesa_pack_float_rgba_row(dst_format, width, 597 (const float (*)[4])tmp_float + row * width, dst); 598 dst += dst_stride; 599 } 600 } 601 602 free(tmp_float); 603 } else { 604 tmp_ubyte = malloc(width * height * sizeof(*tmp_ubyte)); 605 606 if (src_format_is_mesa_array_format) { 607 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, 608 rebased_src2rgba); 609 for (row = 0; row < height; ++row) { 610 _mesa_swizzle_and_convert(tmp_ubyte + row * width, 611 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, 612 src, src_type, src_num_channels, 613 rebased_src2rgba, normalized, width); 614 src += src_stride; 615 } 616 } else { 617 for (row = 0; row < height; ++row) { 618 _mesa_unpack_ubyte_rgba_row(src_format, width, 619 src, tmp_ubyte + row * width); 620 if (rebase_swizzle) 621 _mesa_swizzle_and_convert(tmp_ubyte + row * width, 622 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, 623 tmp_ubyte + row * width, 624 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, 625 rebase_swizzle, normalized, width); 626 src += src_stride; 627 } 628 } 629 630 if (dst_format_is_mesa_array_format) { 631 for (row = 0; row < height; ++row) { 632 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, 633 tmp_ubyte + row * width, 634 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, 635 rgba2dst, normalized, width); 636 dst += dst_stride; 637 } 638 } else { 639 for (row = 0; row < height; ++row) { 640 _mesa_pack_ubyte_rgba_row(dst_format, width, 641 (const uint8_t (*)[4])tmp_ubyte + row * width, dst); 642 dst += dst_stride; 643 } 644 } 645 646 free(tmp_ubyte); 647 } 648} 649 650static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 }; 651static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 }; 652static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 }; 653 654/** 655 * Describes a format as an array format, if possible 656 * 657 * A helper function for figuring out if a (possibly packed) format is 658 * actually an array format and, if so, what the array parameters are. 659 * 660 * \param[in] format the mesa format 661 * \param[out] type the GL type of the array (GL_BYTE, etc.) 662 * \param[out] num_components the number of components in the array 663 * \param[out] swizzle a swizzle describing how to get from the 664 * given format to RGBA 665 * \param[out] normalized for integer formats, this represents whether 666 * the format is a normalized integer or a 667 * regular integer 668 * \return true if this format is an array format, false otherwise 669 */ 670bool 671_mesa_format_to_array(mesa_format format, GLenum *type, int *num_components, 672 uint8_t swizzle[4], bool *normalized) 673{ 674 int i; 675 GLuint format_components; 676 uint8_t packed_swizzle[4]; 677 const uint8_t *endian; 678 679 if (_mesa_is_format_compressed(format)) 680 return false; 681 682 *normalized = !_mesa_is_format_integer(format); 683 684 _mesa_uncompressed_format_to_type_and_comps(format, type, &format_components); 685 686 switch (_mesa_get_format_layout(format)) { 687 case MESA_FORMAT_LAYOUT_ARRAY: 688 *num_components = format_components; 689 _mesa_get_format_swizzle(format, swizzle); 690 return true; 691 case MESA_FORMAT_LAYOUT_PACKED: 692 switch (*type) { 693 case GL_UNSIGNED_BYTE: 694 case GL_BYTE: 695 if (_mesa_get_format_max_bits(format) != 8) 696 return false; 697 *num_components = _mesa_get_format_bytes(format); 698 switch (*num_components) { 699 case 1: 700 endian = map_identity; 701 break; 702 case 2: 703 endian = _mesa_little_endian() ? map_identity : map_1032; 704 break; 705 case 4: 706 endian = _mesa_little_endian() ? map_identity : map_3210; 707 break; 708 default: 709 endian = map_identity; 710 assert(!"Invalid number of components"); 711 } 712 break; 713 case GL_UNSIGNED_SHORT: 714 case GL_SHORT: 715 case GL_HALF_FLOAT: 716 if (_mesa_get_format_max_bits(format) != 16) 717 return false; 718 *num_components = _mesa_get_format_bytes(format) / 2; 719 switch (*num_components) { 720 case 1: 721 endian = map_identity; 722 break; 723 case 2: 724 endian = _mesa_little_endian() ? map_identity : map_1032; 725 break; 726 default: 727 endian = map_identity; 728 assert(!"Invalid number of components"); 729 } 730 break; 731 case GL_UNSIGNED_INT: 732 case GL_INT: 733 case GL_FLOAT: 734 /* This isn't packed. At least not really. */ 735 assert(format_components == 1); 736 if (_mesa_get_format_max_bits(format) != 32) 737 return false; 738 *num_components = format_components; 739 endian = map_identity; 740 break; 741 default: 742 return false; 743 } 744 745 _mesa_get_format_swizzle(format, packed_swizzle); 746 747 for (i = 0; i < 4; ++i) 748 swizzle[i] = endian[packed_swizzle[i]]; 749 750 return true; 751 case MESA_FORMAT_LAYOUT_OTHER: 752 default: 753 return false; 754 } 755} 756 757/** 758 * Attempts to perform the given swizzle-and-convert operation with memcpy 759 * 760 * This function determines if the given swizzle-and-convert operation can 761 * be done with a simple memcpy and, if so, does the memcpy. If not, it 762 * returns false and we fall back to the standard version below. 763 * 764 * The arguments are exactly the same as for _mesa_swizzle_and_convert 765 * 766 * \return true if it successfully performed the swizzle-and-convert 767 * operation with memcpy, false otherwise 768 */ 769static bool 770swizzle_convert_try_memcpy(void *dst, 771 enum mesa_array_format_datatype dst_type, 772 int num_dst_channels, 773 const void *src, 774 enum mesa_array_format_datatype src_type, 775 int num_src_channels, 776 const uint8_t swizzle[4], bool normalized, int count) 777{ 778 int i; 779 780 if (src_type != dst_type) 781 return false; 782 if (num_src_channels != num_dst_channels) 783 return false; 784 785 for (i = 0; i < num_dst_channels; ++i) 786 if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE) 787 return false; 788 789 memcpy(dst, src, count * num_src_channels * 790 _mesa_array_format_datatype_get_size(src_type)); 791 792 return true; 793} 794 795/** 796 * Represents a single instance of the standard swizzle-and-convert loop 797 * 798 * Any swizzle-and-convert operation simply loops through the pixels and 799 * performs the transformation operation one pixel at a time. This macro 800 * embodies one instance of the conversion loop. This way we can do all 801 * control flow outside of the loop and allow the compiler to unroll 802 * everything inside the loop. 803 * 804 * Note: This loop is carefully crafted for performance. Be careful when 805 * changing it and run some benchmarks to ensure no performance regressions 806 * if you do. 807 * 808 * \param DST_TYPE the C datatype of the destination 809 * \param DST_CHANS the number of destination channels 810 * \param SRC_TYPE the C datatype of the source 811 * \param SRC_CHANS the number of source channels 812 * \param CONV an expression for converting from the source data, 813 * storred in the variable "src", to the destination 814 * format 815 */ 816#define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \ 817 do { \ 818 int s, j; \ 819 for (s = 0; s < count; ++s) { \ 820 for (j = 0; j < SRC_CHANS; ++j) { \ 821 SRC_TYPE src = typed_src[j]; \ 822 tmp[j] = CONV; \ 823 } \ 824 \ 825 typed_dst[0] = tmp[swizzle_x]; \ 826 if (DST_CHANS > 1) { \ 827 typed_dst[1] = tmp[swizzle_y]; \ 828 if (DST_CHANS > 2) { \ 829 typed_dst[2] = tmp[swizzle_z]; \ 830 if (DST_CHANS > 3) { \ 831 typed_dst[3] = tmp[swizzle_w]; \ 832 } \ 833 } \ 834 } \ 835 typed_src += SRC_CHANS; \ 836 typed_dst += DST_CHANS; \ 837 } \ 838 } while (0) 839 840/** 841 * Represents a single swizzle-and-convert operation 842 * 843 * This macro represents everything done in a single swizzle-and-convert 844 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro. 845 * This macro acts as a wrapper that uses a nested switch to ensure that 846 * all looping parameters get unrolled. 847 * 848 * This macro makes assumptions about variables etc. in the calling 849 * function. Changes to _mesa_swizzle_and_convert may require changes to 850 * this macro. 851 * 852 * \param DST_TYPE the C datatype of the destination 853 * \param SRC_TYPE the C datatype of the source 854 * \param CONV an expression for converting from the source data, 855 * storred in the variable "src", to the destination 856 * format 857 */ 858#define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \ 859 do { \ 860 const uint8_t swizzle_x = swizzle[0]; \ 861 const uint8_t swizzle_y = swizzle[1]; \ 862 const uint8_t swizzle_z = swizzle[2]; \ 863 const uint8_t swizzle_w = swizzle[3]; \ 864 const SRC_TYPE *typed_src = void_src; \ 865 DST_TYPE *typed_dst = void_dst; \ 866 DST_TYPE tmp[7]; \ 867 tmp[4] = 0; \ 868 tmp[5] = one; \ 869 switch (num_dst_channels) { \ 870 case 1: \ 871 switch (num_src_channels) { \ 872 case 1: \ 873 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \ 874 break; \ 875 case 2: \ 876 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \ 877 break; \ 878 case 3: \ 879 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \ 880 break; \ 881 case 4: \ 882 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \ 883 break; \ 884 } \ 885 break; \ 886 case 2: \ 887 switch (num_src_channels) { \ 888 case 1: \ 889 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \ 890 break; \ 891 case 2: \ 892 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \ 893 break; \ 894 case 3: \ 895 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \ 896 break; \ 897 case 4: \ 898 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \ 899 break; \ 900 } \ 901 break; \ 902 case 3: \ 903 switch (num_src_channels) { \ 904 case 1: \ 905 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \ 906 break; \ 907 case 2: \ 908 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \ 909 break; \ 910 case 3: \ 911 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \ 912 break; \ 913 case 4: \ 914 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \ 915 break; \ 916 } \ 917 break; \ 918 case 4: \ 919 switch (num_src_channels) { \ 920 case 1: \ 921 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \ 922 break; \ 923 case 2: \ 924 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \ 925 break; \ 926 case 3: \ 927 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \ 928 break; \ 929 case 4: \ 930 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \ 931 break; \ 932 } \ 933 break; \ 934 } \ 935 } while (0) 936 937 938static void 939convert_float(void *void_dst, int num_dst_channels, 940 const void *void_src, GLenum src_type, int num_src_channels, 941 const uint8_t swizzle[4], bool normalized, int count) 942{ 943 const float one = 1.0f; 944 945 switch (src_type) { 946 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 947 SWIZZLE_CONVERT(float, float, src); 948 break; 949 case MESA_ARRAY_FORMAT_TYPE_HALF: 950 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src)); 951 break; 952 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 953 if (normalized) { 954 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src, 8)); 955 } else { 956 SWIZZLE_CONVERT(float, uint8_t, src); 957 } 958 break; 959 case MESA_ARRAY_FORMAT_TYPE_BYTE: 960 if (normalized) { 961 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src, 8)); 962 } else { 963 SWIZZLE_CONVERT(float, int8_t, src); 964 } 965 break; 966 case MESA_ARRAY_FORMAT_TYPE_USHORT: 967 if (normalized) { 968 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src, 16)); 969 } else { 970 SWIZZLE_CONVERT(float, uint16_t, src); 971 } 972 break; 973 case MESA_ARRAY_FORMAT_TYPE_SHORT: 974 if (normalized) { 975 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src, 16)); 976 } else { 977 SWIZZLE_CONVERT(float, int16_t, src); 978 } 979 break; 980 case MESA_ARRAY_FORMAT_TYPE_UINT: 981 if (normalized) { 982 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src, 32)); 983 } else { 984 SWIZZLE_CONVERT(float, uint32_t, src); 985 } 986 break; 987 case MESA_ARRAY_FORMAT_TYPE_INT: 988 if (normalized) { 989 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src, 32)); 990 } else { 991 SWIZZLE_CONVERT(float, int32_t, src); 992 } 993 break; 994 default: 995 assert(!"Invalid channel type combination"); 996 } 997} 998 999 1000static void 1001convert_half_float(void *void_dst, int num_dst_channels, 1002 const void *void_src, GLenum src_type, int num_src_channels, 1003 const uint8_t swizzle[4], bool normalized, int count) 1004{ 1005 const uint16_t one = _mesa_float_to_half(1.0f); 1006 1007 switch (src_type) { 1008 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1009 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src)); 1010 break; 1011 case MESA_ARRAY_FORMAT_TYPE_HALF: 1012 SWIZZLE_CONVERT(uint16_t, uint16_t, src); 1013 break; 1014 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1015 if (normalized) { 1016 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src, 8)); 1017 } else { 1018 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src)); 1019 } 1020 break; 1021 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1022 if (normalized) { 1023 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src, 8)); 1024 } else { 1025 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src)); 1026 } 1027 break; 1028 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1029 if (normalized) { 1030 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src, 16)); 1031 } else { 1032 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src)); 1033 } 1034 break; 1035 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1036 if (normalized) { 1037 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src, 16)); 1038 } else { 1039 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src)); 1040 } 1041 break; 1042 case MESA_ARRAY_FORMAT_TYPE_UINT: 1043 if (normalized) { 1044 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src, 32)); 1045 } else { 1046 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src)); 1047 } 1048 break; 1049 case MESA_ARRAY_FORMAT_TYPE_INT: 1050 if (normalized) { 1051 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src, 32)); 1052 } else { 1053 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src)); 1054 } 1055 break; 1056 default: 1057 assert(!"Invalid channel type combination"); 1058 } 1059} 1060 1061static void 1062convert_ubyte(void *void_dst, int num_dst_channels, 1063 const void *void_src, GLenum src_type, int num_src_channels, 1064 const uint8_t swizzle[4], bool normalized, int count) 1065{ 1066 const uint8_t one = normalized ? UINT8_MAX : 1; 1067 1068 switch (src_type) { 1069 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1070 if (normalized) { 1071 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src, 8)); 1072 } else { 1073 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src, 8)); 1074 } 1075 break; 1076 case MESA_ARRAY_FORMAT_TYPE_HALF: 1077 if (normalized) { 1078 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src, 8)); 1079 } else { 1080 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src, 8)); 1081 } 1082 break; 1083 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1084 SWIZZLE_CONVERT(uint8_t, uint8_t, src); 1085 break; 1086 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1087 if (normalized) { 1088 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src, 8, 8)); 1089 } else { 1090 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src, 8)); 1091 } 1092 break; 1093 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1094 if (normalized) { 1095 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 8)); 1096 } else { 1097 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src, 8)); 1098 } 1099 break; 1100 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1101 if (normalized) { 1102 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src, 16, 8)); 1103 } else { 1104 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src, 8)); 1105 } 1106 break; 1107 case MESA_ARRAY_FORMAT_TYPE_UINT: 1108 if (normalized) { 1109 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 8)); 1110 } else { 1111 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src, 8)); 1112 } 1113 break; 1114 case MESA_ARRAY_FORMAT_TYPE_INT: 1115 if (normalized) { 1116 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src, 32, 8)); 1117 } else { 1118 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src, 8)); 1119 } 1120 break; 1121 default: 1122 assert(!"Invalid channel type combination"); 1123 } 1124} 1125 1126 1127static void 1128convert_byte(void *void_dst, int num_dst_channels, 1129 const void *void_src, GLenum src_type, int num_src_channels, 1130 const uint8_t swizzle[4], bool normalized, int count) 1131{ 1132 const int8_t one = normalized ? INT8_MAX : 1; 1133 1134 switch (src_type) { 1135 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1136 if (normalized) { 1137 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src, 8)); 1138 } else { 1139 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src, 8)); 1140 } 1141 break; 1142 case MESA_ARRAY_FORMAT_TYPE_HALF: 1143 if (normalized) { 1144 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src, 8)); 1145 } else { 1146 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src, 8)); 1147 } 1148 break; 1149 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1150 if (normalized) { 1151 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 8)); 1152 } else { 1153 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src, 8)); 1154 } 1155 break; 1156 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1157 SWIZZLE_CONVERT(int8_t, int8_t, src); 1158 break; 1159 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1160 if (normalized) { 1161 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 8)); 1162 } else { 1163 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src, 8)); 1164 } 1165 break; 1166 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1167 if (normalized) { 1168 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src, 16, 8)); 1169 } else { 1170 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src, 8)); 1171 } 1172 break; 1173 case MESA_ARRAY_FORMAT_TYPE_UINT: 1174 if (normalized) { 1175 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 8)); 1176 } else { 1177 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src, 8)); 1178 } 1179 break; 1180 case MESA_ARRAY_FORMAT_TYPE_INT: 1181 if (normalized) { 1182 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src, 32, 8)); 1183 } else { 1184 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src, 8)); 1185 } 1186 break; 1187 default: 1188 assert(!"Invalid channel type combination"); 1189 } 1190} 1191 1192 1193static void 1194convert_ushort(void *void_dst, int num_dst_channels, 1195 const void *void_src, GLenum src_type, int num_src_channels, 1196 const uint8_t swizzle[4], bool normalized, int count) 1197{ 1198 const uint16_t one = normalized ? UINT16_MAX : 1; 1199 1200 switch (src_type) { 1201 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1202 if (normalized) { 1203 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src, 16)); 1204 } else { 1205 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src, 16)); 1206 } 1207 break; 1208 case MESA_ARRAY_FORMAT_TYPE_HALF: 1209 if (normalized) { 1210 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src, 16)); 1211 } else { 1212 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src, 16)); 1213 } 1214 break; 1215 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1216 if (normalized) { 1217 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 16)); 1218 } else { 1219 SWIZZLE_CONVERT(uint16_t, uint8_t, src); 1220 } 1221 break; 1222 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1223 if (normalized) { 1224 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src, 8, 16)); 1225 } else { 1226 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src, 16)); 1227 } 1228 break; 1229 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1230 SWIZZLE_CONVERT(uint16_t, uint16_t, src); 1231 break; 1232 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1233 if (normalized) { 1234 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src, 16, 16)); 1235 } else { 1236 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src, 16)); 1237 } 1238 break; 1239 case MESA_ARRAY_FORMAT_TYPE_UINT: 1240 if (normalized) { 1241 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 16)); 1242 } else { 1243 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src, 16)); 1244 } 1245 break; 1246 case MESA_ARRAY_FORMAT_TYPE_INT: 1247 if (normalized) { 1248 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src, 32, 16)); 1249 } else { 1250 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src, 16)); 1251 } 1252 break; 1253 default: 1254 assert(!"Invalid channel type combination"); 1255 } 1256} 1257 1258 1259static void 1260convert_short(void *void_dst, int num_dst_channels, 1261 const void *void_src, GLenum src_type, int num_src_channels, 1262 const uint8_t swizzle[4], bool normalized, int count) 1263{ 1264 const int16_t one = normalized ? INT16_MAX : 1; 1265 1266 switch (src_type) { 1267 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1268 if (normalized) { 1269 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src, 16)); 1270 } else { 1271 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src, 16)); 1272 } 1273 break; 1274 case MESA_ARRAY_FORMAT_TYPE_HALF: 1275 if (normalized) { 1276 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src, 16)); 1277 } else { 1278 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src, 16)); 1279 } 1280 break; 1281 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1282 if (normalized) { 1283 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 16)); 1284 } else { 1285 SWIZZLE_CONVERT(int16_t, uint8_t, src); 1286 } 1287 break; 1288 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1289 if (normalized) { 1290 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src, 8, 16)); 1291 } else { 1292 SWIZZLE_CONVERT(int16_t, int8_t, src); 1293 } 1294 break; 1295 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1296 if (normalized) { 1297 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 16)); 1298 } else { 1299 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src, 16)); 1300 } 1301 break; 1302 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1303 SWIZZLE_CONVERT(int16_t, int16_t, src); 1304 break; 1305 case MESA_ARRAY_FORMAT_TYPE_UINT: 1306 if (normalized) { 1307 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 16)); 1308 } else { 1309 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src, 16)); 1310 } 1311 break; 1312 case MESA_ARRAY_FORMAT_TYPE_INT: 1313 if (normalized) { 1314 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src, 32, 16)); 1315 } else { 1316 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src, 16)); 1317 } 1318 break; 1319 default: 1320 assert(!"Invalid channel type combination"); 1321 } 1322} 1323 1324static void 1325convert_uint(void *void_dst, int num_dst_channels, 1326 const void *void_src, GLenum src_type, int num_src_channels, 1327 const uint8_t swizzle[4], bool normalized, int count) 1328{ 1329 const uint32_t one = normalized ? UINT32_MAX : 1; 1330 1331 switch (src_type) { 1332 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1333 if (normalized) { 1334 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src, 32)); 1335 } else { 1336 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src, 32)); 1337 } 1338 break; 1339 case MESA_ARRAY_FORMAT_TYPE_HALF: 1340 if (normalized) { 1341 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src, 32)); 1342 } else { 1343 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src, 32)); 1344 } 1345 break; 1346 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1347 if (normalized) { 1348 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 32)); 1349 } else { 1350 SWIZZLE_CONVERT(uint32_t, uint8_t, src); 1351 } 1352 break; 1353 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1354 if (normalized) { 1355 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src, 8, 32)); 1356 } else { 1357 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src, 32)); 1358 } 1359 break; 1360 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1361 if (normalized) { 1362 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 32)); 1363 } else { 1364 SWIZZLE_CONVERT(uint32_t, uint16_t, src); 1365 } 1366 break; 1367 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1368 if (normalized) { 1369 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src, 16, 32)); 1370 } else { 1371 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src, 32)); 1372 } 1373 break; 1374 case MESA_ARRAY_FORMAT_TYPE_UINT: 1375 SWIZZLE_CONVERT(uint32_t, uint32_t, src); 1376 break; 1377 case MESA_ARRAY_FORMAT_TYPE_INT: 1378 if (normalized) { 1379 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src, 32, 32)); 1380 } else { 1381 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src, 32)); 1382 } 1383 break; 1384 default: 1385 assert(!"Invalid channel type combination"); 1386 } 1387} 1388 1389 1390static void 1391convert_int(void *void_dst, int num_dst_channels, 1392 const void *void_src, GLenum src_type, int num_src_channels, 1393 const uint8_t swizzle[4], bool normalized, int count) 1394{ 1395 const int32_t one = normalized ? INT32_MAX : 1; 1396 1397 switch (src_type) { 1398 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1399 if (normalized) { 1400 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src, 32)); 1401 } else { 1402 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src, 32)); 1403 } 1404 break; 1405 case MESA_ARRAY_FORMAT_TYPE_HALF: 1406 if (normalized) { 1407 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src, 32)); 1408 } else { 1409 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src, 32)); 1410 } 1411 break; 1412 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1413 if (normalized) { 1414 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 32)); 1415 } else { 1416 SWIZZLE_CONVERT(int32_t, uint8_t, src); 1417 } 1418 break; 1419 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1420 if (normalized) { 1421 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src, 8, 32)); 1422 } else { 1423 SWIZZLE_CONVERT(int32_t, int8_t, src); 1424 } 1425 break; 1426 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1427 if (normalized) { 1428 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 32)); 1429 } else { 1430 SWIZZLE_CONVERT(int32_t, uint16_t, src); 1431 } 1432 break; 1433 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1434 if (normalized) { 1435 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src, 16, 32)); 1436 } else { 1437 SWIZZLE_CONVERT(int32_t, int16_t, src); 1438 } 1439 break; 1440 case MESA_ARRAY_FORMAT_TYPE_UINT: 1441 if (normalized) { 1442 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 32)); 1443 } else { 1444 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src, 32)); 1445 } 1446 break; 1447 case MESA_ARRAY_FORMAT_TYPE_INT: 1448 SWIZZLE_CONVERT(int32_t, int32_t, src); 1449 break; 1450 default: 1451 assert(!"Invalid channel type combination"); 1452 } 1453} 1454 1455 1456/** 1457 * Convert between array-based color formats. 1458 * 1459 * Most format conversion operations required by GL can be performed by 1460 * converting one channel at a time, shuffling the channels around, and 1461 * optionally filling missing channels with zeros and ones. This function 1462 * does just that in a general, yet efficient, way. 1463 * 1464 * The swizzle parameter is an array of 4 numbers (see 1465 * _mesa_get_format_swizzle) that describes where each channel in the 1466 * destination should come from in the source. If swizzle[i] < 4 then it 1467 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is 1468 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding 1469 * dst[i] will be filled with the appropreate representation of zero or one 1470 * respectively. 1471 * 1472 * Under most circumstances, the source and destination images must be 1473 * different as no care is taken not to clobber one with the other. 1474 * However, if they have the same number of bits per pixel, it is safe to 1475 * do an in-place conversion. 1476 * 1477 * \param[out] dst pointer to where the converted data should 1478 * be stored 1479 * 1480 * \param[in] dst_type the destination GL type of the converted 1481 * data (GL_BYTE, etc.) 1482 * 1483 * \param[in] num_dst_channels the number of channels in the converted 1484 * data 1485 * 1486 * \param[in] src pointer to the source data 1487 * 1488 * \param[in] src_type the GL type of the source data (GL_BYTE, 1489 * etc.) 1490 * 1491 * \param[in] num_src_channels the number of channels in the source data 1492 * (the number of channels total, not just 1493 * the number used) 1494 * 1495 * \param[in] swizzle describes how to get the destination data 1496 * from the source data. 1497 * 1498 * \param[in] normalized for integer types, this indicates whether 1499 * the data should be considered as integers 1500 * or as normalized integers; 1501 * 1502 * \param[in] count the number of pixels to convert 1503 */ 1504void 1505_mesa_swizzle_and_convert(void *void_dst, enum mesa_array_format_datatype dst_type, int num_dst_channels, 1506 const void *void_src, enum mesa_array_format_datatype src_type, int num_src_channels, 1507 const uint8_t swizzle[4], bool normalized, int count) 1508{ 1509 if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels, 1510 void_src, src_type, num_src_channels, 1511 swizzle, normalized, count)) 1512 return; 1513 1514 switch (dst_type) { 1515 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1516 convert_float(void_dst, num_dst_channels, void_src, src_type, 1517 num_src_channels, swizzle, normalized, count); 1518 break; 1519 case MESA_ARRAY_FORMAT_TYPE_HALF: 1520 convert_half_float(void_dst, num_dst_channels, void_src, src_type, 1521 num_src_channels, swizzle, normalized, count); 1522 break; 1523 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1524 convert_ubyte(void_dst, num_dst_channels, void_src, src_type, 1525 num_src_channels, swizzle, normalized, count); 1526 break; 1527 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1528 convert_byte(void_dst, num_dst_channels, void_src, src_type, 1529 num_src_channels, swizzle, normalized, count); 1530 break; 1531 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1532 convert_ushort(void_dst, num_dst_channels, void_src, src_type, 1533 num_src_channels, swizzle, normalized, count); 1534 break; 1535 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1536 convert_short(void_dst, num_dst_channels, void_src, src_type, 1537 num_src_channels, swizzle, normalized, count); 1538 break; 1539 case MESA_ARRAY_FORMAT_TYPE_UINT: 1540 convert_uint(void_dst, num_dst_channels, void_src, src_type, 1541 num_src_channels, swizzle, normalized, count); 1542 break; 1543 case MESA_ARRAY_FORMAT_TYPE_INT: 1544 convert_int(void_dst, num_dst_channels, void_src, src_type, 1545 num_src_channels, swizzle, normalized, count); 1546 break; 1547 default: 1548 assert(!"Invalid channel type"); 1549 } 1550} 1551