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