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 /* Handle the cases where we can directly unpack */ 316 if (!src_format_is_mesa_array_format) { 317 if (dst_array_format == RGBA32_FLOAT) { 318 for (row = 0; row < height; ++row) { 319 _mesa_unpack_rgba_row(src_format, width, 320 src, (float (*)[4])dst); 321 src += src_stride; 322 dst += dst_stride; 323 } 324 return; 325 } else if (dst_array_format == RGBA8_UBYTE) { 326 assert(!_mesa_is_format_integer_color(src_format)); 327 for (row = 0; row < height; ++row) { 328 _mesa_unpack_ubyte_rgba_row(src_format, width, 329 src, (uint8_t (*)[4])dst); 330 src += src_stride; 331 dst += dst_stride; 332 } 333 return; 334 } else if (dst_array_format == RGBA32_UINT && 335 _mesa_is_format_unsigned(src_format)) { 336 assert(_mesa_is_format_integer_color(src_format)); 337 for (row = 0; row < height; ++row) { 338 _mesa_unpack_uint_rgba_row(src_format, width, 339 src, (uint32_t (*)[4])dst); 340 src += src_stride; 341 dst += dst_stride; 342 } 343 return; 344 } 345 } 346 347 /* Handle the cases where we can directly pack */ 348 if (!dst_format_is_mesa_array_format) { 349 if (src_array_format == RGBA32_FLOAT) { 350 for (row = 0; row < height; ++row) { 351 _mesa_pack_float_rgba_row(dst_format, width, 352 (const float (*)[4])src, dst); 353 src += src_stride; 354 dst += dst_stride; 355 } 356 return; 357 } else if (src_array_format == RGBA8_UBYTE) { 358 assert(!_mesa_is_format_integer_color(dst_format)); 359 360 if (dst_format == MESA_FORMAT_B8G8R8A8_UNORM) { 361 convert_ubyte_rgba_to_bgra(width, height, src, src_stride, 362 dst, dst_stride); 363 } 364 else { 365 for (row = 0; row < height; ++row) { 366 _mesa_pack_ubyte_rgba_row(dst_format, width, 367 (const uint8_t (*)[4])src, dst); 368 src += src_stride; 369 dst += dst_stride; 370 } 371 } 372 return; 373 } else if (src_array_format == RGBA32_UINT && 374 _mesa_is_format_unsigned(dst_format)) { 375 assert(_mesa_is_format_integer_color(dst_format)); 376 for (row = 0; row < height; ++row) { 377 _mesa_pack_uint_rgba_row(dst_format, width, 378 (const uint32_t (*)[4])src, dst); 379 src += src_stride; 380 dst += dst_stride; 381 } 382 return; 383 } 384 } 385 } 386 387 /* Handle conversions between array formats */ 388 normalized = false; 389 if (src_array_format) { 390 src_type = _mesa_array_format_get_datatype(src_array_format); 391 392 src_num_channels = _mesa_array_format_get_num_channels(src_array_format); 393 394 _mesa_array_format_get_swizzle(src_array_format, src2rgba); 395 396 normalized = _mesa_array_format_is_normalized(src_array_format); 397 } 398 399 if (dst_array_format) { 400 dst_type = _mesa_array_format_get_datatype(dst_array_format); 401 402 dst_num_channels = _mesa_array_format_get_num_channels(dst_array_format); 403 404 _mesa_array_format_get_swizzle(dst_array_format, dst2rgba); 405 invert_swizzle(rgba2dst, dst2rgba); 406 407 normalized |= _mesa_array_format_is_normalized(dst_array_format); 408 } 409 410 if (src_array_format && dst_array_format) { 411 assert(_mesa_array_format_is_normalized(src_array_format) == 412 _mesa_array_format_is_normalized(dst_array_format)); 413 414 compute_src2dst_component_mapping(src2rgba, rgba2dst, rebase_swizzle, 415 src2dst); 416 417 for (row = 0; row < height; ++row) { 418 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, 419 src, src_type, src_num_channels, 420 src2dst, normalized, width); 421 src += src_stride; 422 dst += dst_stride; 423 } 424 return; 425 } 426 427 /* At this point, we're fresh out of fast-paths and we need to convert 428 * to float, uint32, or, if we're lucky, uint8. 429 */ 430 dst_integer = false; 431 src_integer = false; 432 433 if (src_array_format) { 434 if (!_mesa_array_format_is_float(src_array_format) && 435 !_mesa_array_format_is_normalized(src_array_format)) 436 src_integer = true; 437 } else { 438 switch (_mesa_get_format_datatype(src_format)) { 439 case GL_UNSIGNED_INT: 440 case GL_INT: 441 src_integer = true; 442 break; 443 } 444 } 445 446 /* If the destination format is signed but the source is unsigned, then we 447 * don't loose any data by converting to a signed intermediate format above 448 * and beyond the precision that we loose in the conversion itself. If the 449 * destination is unsigned then, by using an unsigned intermediate format, 450 * we make the conversion function that converts from the source to the 451 * intermediate format take care of truncating at zero. The exception here 452 * is if the intermediate format is float, in which case the first 453 * conversion will leave it signed and the second conversion will truncate 454 * at zero. 455 */ 456 is_signed = false; 457 if (dst_array_format) { 458 if (!_mesa_array_format_is_float(dst_array_format) && 459 !_mesa_array_format_is_normalized(dst_array_format)) 460 dst_integer = true; 461 is_signed = _mesa_array_format_is_signed(dst_array_format); 462 bits = 8 * _mesa_array_format_get_type_size(dst_array_format); 463 } else { 464 switch (_mesa_get_format_datatype(dst_format)) { 465 case GL_UNSIGNED_NORMALIZED: 466 is_signed = false; 467 break; 468 case GL_SIGNED_NORMALIZED: 469 is_signed = true; 470 break; 471 case GL_FLOAT: 472 is_signed = true; 473 break; 474 case GL_UNSIGNED_INT: 475 is_signed = false; 476 dst_integer = true; 477 break; 478 case GL_INT: 479 is_signed = true; 480 dst_integer = true; 481 break; 482 } 483 bits = _mesa_get_format_max_bits(dst_format); 484 } 485 486 assert(src_integer == dst_integer); 487 488 if (src_integer && dst_integer) { 489 tmp_uint = malloc(width * height * sizeof(*tmp_uint)); 490 491 /* The [un]packing functions for unsigned datatypes treat the 32-bit 492 * integer array as signed for signed formats and as unsigned for 493 * unsigned formats. This is a bit of a problem if we ever convert from 494 * a signed to an unsigned format because the unsigned packing function 495 * doesn't know that the input is signed and will treat it as unsigned 496 * and not do the trunctation. The thing that saves us here is that all 497 * of the packed formats are unsigned, so we can just always use 498 * _mesa_swizzle_and_convert for signed formats, which is aware of the 499 * truncation problem. 500 */ 501 common_type = is_signed ? MESA_ARRAY_FORMAT_TYPE_INT : 502 MESA_ARRAY_FORMAT_TYPE_UINT; 503 if (src_array_format) { 504 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, 505 rebased_src2rgba); 506 for (row = 0; row < height; ++row) { 507 _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4, 508 src, src_type, src_num_channels, 509 rebased_src2rgba, normalized, width); 510 src += src_stride; 511 } 512 } else { 513 for (row = 0; row < height; ++row) { 514 _mesa_unpack_uint_rgba_row(src_format, width, 515 src, tmp_uint + row * width); 516 if (rebase_swizzle) 517 _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4, 518 tmp_uint + row * width, common_type, 4, 519 rebase_swizzle, false, width); 520 src += src_stride; 521 } 522 } 523 524 /* At this point, we have already done the truncation if the source is 525 * signed but the destination is unsigned, so no need to force the 526 * _mesa_swizzle_and_convert path. 527 */ 528 if (dst_format_is_mesa_array_format) { 529 for (row = 0; row < height; ++row) { 530 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, 531 tmp_uint + row * width, common_type, 4, 532 rgba2dst, normalized, width); 533 dst += dst_stride; 534 } 535 } else { 536 for (row = 0; row < height; ++row) { 537 _mesa_pack_uint_rgba_row(dst_format, width, 538 (const uint32_t (*)[4])tmp_uint + row * width, dst); 539 dst += dst_stride; 540 } 541 } 542 543 free(tmp_uint); 544 } else if (is_signed || bits > 8) { 545 tmp_float = malloc(width * height * sizeof(*tmp_float)); 546 547 if (src_format_is_mesa_array_format) { 548 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, 549 rebased_src2rgba); 550 for (row = 0; row < height; ++row) { 551 _mesa_swizzle_and_convert(tmp_float + row * width, 552 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, 553 src, src_type, src_num_channels, 554 rebased_src2rgba, normalized, width); 555 src += src_stride; 556 } 557 } else { 558 for (row = 0; row < height; ++row) { 559 _mesa_unpack_rgba_row(src_format, width, 560 src, tmp_float + row * width); 561 if (rebase_swizzle) 562 _mesa_swizzle_and_convert(tmp_float + row * width, 563 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, 564 tmp_float + row * width, 565 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, 566 rebase_swizzle, normalized, width); 567 src += src_stride; 568 } 569 } 570 571 if (dst_format_is_mesa_array_format) { 572 for (row = 0; row < height; ++row) { 573 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, 574 tmp_float + row * width, 575 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, 576 rgba2dst, normalized, width); 577 dst += dst_stride; 578 } 579 } else { 580 for (row = 0; row < height; ++row) { 581 _mesa_pack_float_rgba_row(dst_format, width, 582 (const float (*)[4])tmp_float + row * width, dst); 583 dst += dst_stride; 584 } 585 } 586 587 free(tmp_float); 588 } else { 589 tmp_ubyte = malloc(width * height * sizeof(*tmp_ubyte)); 590 591 if (src_format_is_mesa_array_format) { 592 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, 593 rebased_src2rgba); 594 for (row = 0; row < height; ++row) { 595 _mesa_swizzle_and_convert(tmp_ubyte + row * width, 596 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, 597 src, src_type, src_num_channels, 598 rebased_src2rgba, normalized, width); 599 src += src_stride; 600 } 601 } else { 602 for (row = 0; row < height; ++row) { 603 _mesa_unpack_ubyte_rgba_row(src_format, width, 604 src, tmp_ubyte + row * width); 605 if (rebase_swizzle) 606 _mesa_swizzle_and_convert(tmp_ubyte + row * width, 607 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, 608 tmp_ubyte + row * width, 609 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, 610 rebase_swizzle, normalized, width); 611 src += src_stride; 612 } 613 } 614 615 if (dst_format_is_mesa_array_format) { 616 for (row = 0; row < height; ++row) { 617 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, 618 tmp_ubyte + row * width, 619 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, 620 rgba2dst, normalized, width); 621 dst += dst_stride; 622 } 623 } else { 624 for (row = 0; row < height; ++row) { 625 _mesa_pack_ubyte_rgba_row(dst_format, width, 626 (const uint8_t (*)[4])tmp_ubyte + row * width, dst); 627 dst += dst_stride; 628 } 629 } 630 631 free(tmp_ubyte); 632 } 633 } 634 635 static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 }; 636 static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 }; 637 static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 }; 638 639 /** 640 * Describes a format as an array format, if possible 641 * 642 * A helper function for figuring out if a (possibly packed) format is 643 * actually an array format and, if so, what the array parameters are. 644 * 645 * \param[in] format the mesa format 646 * \param[out] type the GL type of the array (GL_BYTE, etc.) 647 * \param[out] num_components the number of components in the array 648 * \param[out] swizzle a swizzle describing how to get from the 649 * given format to RGBA 650 * \param[out] normalized for integer formats, this represents whether 651 * the format is a normalized integer or a 652 * regular integer 653 * \return true if this format is an array format, false otherwise 654 */ 655 bool 656 _mesa_format_to_array(mesa_format format, GLenum *type, int *num_components, 657 uint8_t swizzle[4], bool *normalized) 658 { 659 int i; 660 GLuint format_components; 661 uint8_t packed_swizzle[4]; 662 const uint8_t *endian; 663 664 if (_mesa_is_format_compressed(format)) 665 return false; 666 667 *normalized = !_mesa_is_format_integer(format); 668 669 _mesa_uncompressed_format_to_type_and_comps(format, type, &format_components); 670 671 switch (_mesa_get_format_layout(format)) { 672 case MESA_FORMAT_LAYOUT_ARRAY: 673 *num_components = format_components; 674 _mesa_get_format_swizzle(format, swizzle); 675 return true; 676 case MESA_FORMAT_LAYOUT_PACKED: 677 switch (*type) { 678 case GL_UNSIGNED_BYTE: 679 case GL_BYTE: 680 if (_mesa_get_format_max_bits(format) != 8) 681 return false; 682 *num_components = _mesa_get_format_bytes(format); 683 switch (*num_components) { 684 case 1: 685 endian = map_identity; 686 break; 687 case 2: 688 endian = _mesa_little_endian() ? map_identity : map_1032; 689 break; 690 case 4: 691 endian = _mesa_little_endian() ? map_identity : map_3210; 692 break; 693 default: 694 endian = map_identity; 695 assert(!"Invalid number of components"); 696 } 697 break; 698 case GL_UNSIGNED_SHORT: 699 case GL_SHORT: 700 case GL_HALF_FLOAT: 701 if (_mesa_get_format_max_bits(format) != 16) 702 return false; 703 *num_components = _mesa_get_format_bytes(format) / 2; 704 switch (*num_components) { 705 case 1: 706 endian = map_identity; 707 break; 708 case 2: 709 endian = _mesa_little_endian() ? map_identity : map_1032; 710 break; 711 default: 712 endian = map_identity; 713 assert(!"Invalid number of components"); 714 } 715 break; 716 case GL_UNSIGNED_INT: 717 case GL_INT: 718 case GL_FLOAT: 719 /* This isn't packed. At least not really. */ 720 assert(format_components == 1); 721 if (_mesa_get_format_max_bits(format) != 32) 722 return false; 723 *num_components = format_components; 724 endian = map_identity; 725 break; 726 default: 727 return false; 728 } 729 730 _mesa_get_format_swizzle(format, packed_swizzle); 731 732 for (i = 0; i < 4; ++i) 733 swizzle[i] = endian[packed_swizzle[i]]; 734 735 return true; 736 case MESA_FORMAT_LAYOUT_OTHER: 737 default: 738 return false; 739 } 740 } 741 742 /** 743 * Attempts to perform the given swizzle-and-convert operation with memcpy 744 * 745 * This function determines if the given swizzle-and-convert operation can 746 * be done with a simple memcpy and, if so, does the memcpy. If not, it 747 * returns false and we fall back to the standard version below. 748 * 749 * The arguments are exactly the same as for _mesa_swizzle_and_convert 750 * 751 * \return true if it successfully performed the swizzle-and-convert 752 * operation with memcpy, false otherwise 753 */ 754 static bool 755 swizzle_convert_try_memcpy(void *dst, 756 enum mesa_array_format_datatype dst_type, 757 int num_dst_channels, 758 const void *src, 759 enum mesa_array_format_datatype src_type, 760 int num_src_channels, 761 const uint8_t swizzle[4], bool normalized, int count) 762 { 763 int i; 764 765 if (src_type != dst_type) 766 return false; 767 if (num_src_channels != num_dst_channels) 768 return false; 769 770 for (i = 0; i < num_dst_channels; ++i) 771 if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE) 772 return false; 773 774 memcpy(dst, src, count * num_src_channels * 775 _mesa_array_format_datatype_get_size(src_type)); 776 777 return true; 778 } 779 780 /** 781 * Represents a single instance of the standard swizzle-and-convert loop 782 * 783 * Any swizzle-and-convert operation simply loops through the pixels and 784 * performs the transformation operation one pixel at a time. This macro 785 * embodies one instance of the conversion loop. This way we can do all 786 * control flow outside of the loop and allow the compiler to unroll 787 * everything inside the loop. 788 * 789 * Note: This loop is carefully crafted for performance. Be careful when 790 * changing it and run some benchmarks to ensure no performance regressions 791 * if you do. 792 * 793 * \param DST_TYPE the C datatype of the destination 794 * \param DST_CHANS the number of destination channels 795 * \param SRC_TYPE the C datatype of the source 796 * \param SRC_CHANS the number of source channels 797 * \param CONV an expression for converting from the source data, 798 * storred in the variable "src", to the destination 799 * format 800 */ 801 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \ 802 do { \ 803 int s, j; \ 804 for (s = 0; s < count; ++s) { \ 805 for (j = 0; j < SRC_CHANS; ++j) { \ 806 SRC_TYPE src = typed_src[j]; \ 807 tmp[j] = CONV; \ 808 } \ 809 \ 810 typed_dst[0] = tmp[swizzle_x]; \ 811 if (DST_CHANS > 1) { \ 812 typed_dst[1] = tmp[swizzle_y]; \ 813 if (DST_CHANS > 2) { \ 814 typed_dst[2] = tmp[swizzle_z]; \ 815 if (DST_CHANS > 3) { \ 816 typed_dst[3] = tmp[swizzle_w]; \ 817 } \ 818 } \ 819 } \ 820 typed_src += SRC_CHANS; \ 821 typed_dst += DST_CHANS; \ 822 } \ 823 } while (0) 824 825 /** 826 * Represents a single swizzle-and-convert operation 827 * 828 * This macro represents everything done in a single swizzle-and-convert 829 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro. 830 * This macro acts as a wrapper that uses a nested switch to ensure that 831 * all looping parameters get unrolled. 832 * 833 * This macro makes assumptions about variables etc. in the calling 834 * function. Changes to _mesa_swizzle_and_convert may require changes to 835 * this macro. 836 * 837 * \param DST_TYPE the C datatype of the destination 838 * \param SRC_TYPE the C datatype of the source 839 * \param CONV an expression for converting from the source data, 840 * storred in the variable "src", to the destination 841 * format 842 */ 843 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \ 844 do { \ 845 const uint8_t swizzle_x = swizzle[0]; \ 846 const uint8_t swizzle_y = swizzle[1]; \ 847 const uint8_t swizzle_z = swizzle[2]; \ 848 const uint8_t swizzle_w = swizzle[3]; \ 849 const SRC_TYPE *typed_src = void_src; \ 850 DST_TYPE *typed_dst = void_dst; \ 851 DST_TYPE tmp[7]; \ 852 tmp[4] = 0; \ 853 tmp[5] = one; \ 854 switch (num_dst_channels) { \ 855 case 1: \ 856 switch (num_src_channels) { \ 857 case 1: \ 858 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \ 859 break; \ 860 case 2: \ 861 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \ 862 break; \ 863 case 3: \ 864 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \ 865 break; \ 866 case 4: \ 867 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \ 868 break; \ 869 } \ 870 break; \ 871 case 2: \ 872 switch (num_src_channels) { \ 873 case 1: \ 874 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \ 875 break; \ 876 case 2: \ 877 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \ 878 break; \ 879 case 3: \ 880 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \ 881 break; \ 882 case 4: \ 883 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \ 884 break; \ 885 } \ 886 break; \ 887 case 3: \ 888 switch (num_src_channels) { \ 889 case 1: \ 890 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \ 891 break; \ 892 case 2: \ 893 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \ 894 break; \ 895 case 3: \ 896 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \ 897 break; \ 898 case 4: \ 899 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \ 900 break; \ 901 } \ 902 break; \ 903 case 4: \ 904 switch (num_src_channels) { \ 905 case 1: \ 906 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \ 907 break; \ 908 case 2: \ 909 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \ 910 break; \ 911 case 3: \ 912 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \ 913 break; \ 914 case 4: \ 915 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \ 916 break; \ 917 } \ 918 break; \ 919 } \ 920 } while (0) 921 922 923 static void 924 convert_float(void *void_dst, int num_dst_channels, 925 const void *void_src, GLenum src_type, int num_src_channels, 926 const uint8_t swizzle[4], bool normalized, int count) 927 { 928 const float one = 1.0f; 929 930 switch (src_type) { 931 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 932 SWIZZLE_CONVERT(float, float, src); 933 break; 934 case MESA_ARRAY_FORMAT_TYPE_HALF: 935 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src)); 936 break; 937 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 938 if (normalized) { 939 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src, 8)); 940 } else { 941 SWIZZLE_CONVERT(float, uint8_t, src); 942 } 943 break; 944 case MESA_ARRAY_FORMAT_TYPE_BYTE: 945 if (normalized) { 946 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src, 8)); 947 } else { 948 SWIZZLE_CONVERT(float, int8_t, src); 949 } 950 break; 951 case MESA_ARRAY_FORMAT_TYPE_USHORT: 952 if (normalized) { 953 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src, 16)); 954 } else { 955 SWIZZLE_CONVERT(float, uint16_t, src); 956 } 957 break; 958 case MESA_ARRAY_FORMAT_TYPE_SHORT: 959 if (normalized) { 960 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src, 16)); 961 } else { 962 SWIZZLE_CONVERT(float, int16_t, src); 963 } 964 break; 965 case MESA_ARRAY_FORMAT_TYPE_UINT: 966 if (normalized) { 967 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src, 32)); 968 } else { 969 SWIZZLE_CONVERT(float, uint32_t, src); 970 } 971 break; 972 case MESA_ARRAY_FORMAT_TYPE_INT: 973 if (normalized) { 974 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src, 32)); 975 } else { 976 SWIZZLE_CONVERT(float, int32_t, src); 977 } 978 break; 979 default: 980 assert(!"Invalid channel type combination"); 981 } 982 } 983 984 985 static void 986 convert_half_float(void *void_dst, int num_dst_channels, 987 const void *void_src, GLenum src_type, int num_src_channels, 988 const uint8_t swizzle[4], bool normalized, int count) 989 { 990 const uint16_t one = _mesa_float_to_half(1.0f); 991 992 switch (src_type) { 993 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 994 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src)); 995 break; 996 case MESA_ARRAY_FORMAT_TYPE_HALF: 997 SWIZZLE_CONVERT(uint16_t, uint16_t, src); 998 break; 999 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1000 if (normalized) { 1001 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src, 8)); 1002 } else { 1003 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src)); 1004 } 1005 break; 1006 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1007 if (normalized) { 1008 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src, 8)); 1009 } else { 1010 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src)); 1011 } 1012 break; 1013 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1014 if (normalized) { 1015 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src, 16)); 1016 } else { 1017 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src)); 1018 } 1019 break; 1020 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1021 if (normalized) { 1022 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src, 16)); 1023 } else { 1024 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src)); 1025 } 1026 break; 1027 case MESA_ARRAY_FORMAT_TYPE_UINT: 1028 if (normalized) { 1029 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src, 32)); 1030 } else { 1031 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src)); 1032 } 1033 break; 1034 case MESA_ARRAY_FORMAT_TYPE_INT: 1035 if (normalized) { 1036 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src, 32)); 1037 } else { 1038 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src)); 1039 } 1040 break; 1041 default: 1042 assert(!"Invalid channel type combination"); 1043 } 1044 } 1045 1046 static void 1047 convert_ubyte(void *void_dst, int num_dst_channels, 1048 const void *void_src, GLenum src_type, int num_src_channels, 1049 const uint8_t swizzle[4], bool normalized, int count) 1050 { 1051 const uint8_t one = normalized ? UINT8_MAX : 1; 1052 1053 switch (src_type) { 1054 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1055 if (normalized) { 1056 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src, 8)); 1057 } else { 1058 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src, 8)); 1059 } 1060 break; 1061 case MESA_ARRAY_FORMAT_TYPE_HALF: 1062 if (normalized) { 1063 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src, 8)); 1064 } else { 1065 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src, 8)); 1066 } 1067 break; 1068 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1069 SWIZZLE_CONVERT(uint8_t, uint8_t, src); 1070 break; 1071 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1072 if (normalized) { 1073 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src, 8, 8)); 1074 } else { 1075 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src, 8)); 1076 } 1077 break; 1078 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1079 if (normalized) { 1080 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 8)); 1081 } else { 1082 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src, 8)); 1083 } 1084 break; 1085 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1086 if (normalized) { 1087 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src, 16, 8)); 1088 } else { 1089 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src, 8)); 1090 } 1091 break; 1092 case MESA_ARRAY_FORMAT_TYPE_UINT: 1093 if (normalized) { 1094 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 8)); 1095 } else { 1096 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src, 8)); 1097 } 1098 break; 1099 case MESA_ARRAY_FORMAT_TYPE_INT: 1100 if (normalized) { 1101 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src, 32, 8)); 1102 } else { 1103 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src, 8)); 1104 } 1105 break; 1106 default: 1107 assert(!"Invalid channel type combination"); 1108 } 1109 } 1110 1111 1112 static void 1113 convert_byte(void *void_dst, int num_dst_channels, 1114 const void *void_src, GLenum src_type, int num_src_channels, 1115 const uint8_t swizzle[4], bool normalized, int count) 1116 { 1117 const int8_t one = normalized ? INT8_MAX : 1; 1118 1119 switch (src_type) { 1120 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1121 if (normalized) { 1122 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src, 8)); 1123 } else { 1124 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src, 8)); 1125 } 1126 break; 1127 case MESA_ARRAY_FORMAT_TYPE_HALF: 1128 if (normalized) { 1129 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src, 8)); 1130 } else { 1131 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src, 8)); 1132 } 1133 break; 1134 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1135 if (normalized) { 1136 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 8)); 1137 } else { 1138 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src, 8)); 1139 } 1140 break; 1141 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1142 SWIZZLE_CONVERT(int8_t, int8_t, src); 1143 break; 1144 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1145 if (normalized) { 1146 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 8)); 1147 } else { 1148 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src, 8)); 1149 } 1150 break; 1151 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1152 if (normalized) { 1153 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src, 16, 8)); 1154 } else { 1155 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src, 8)); 1156 } 1157 break; 1158 case MESA_ARRAY_FORMAT_TYPE_UINT: 1159 if (normalized) { 1160 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 8)); 1161 } else { 1162 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src, 8)); 1163 } 1164 break; 1165 case MESA_ARRAY_FORMAT_TYPE_INT: 1166 if (normalized) { 1167 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src, 32, 8)); 1168 } else { 1169 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src, 8)); 1170 } 1171 break; 1172 default: 1173 assert(!"Invalid channel type combination"); 1174 } 1175 } 1176 1177 1178 static void 1179 convert_ushort(void *void_dst, int num_dst_channels, 1180 const void *void_src, GLenum src_type, int num_src_channels, 1181 const uint8_t swizzle[4], bool normalized, int count) 1182 { 1183 const uint16_t one = normalized ? UINT16_MAX : 1; 1184 1185 switch (src_type) { 1186 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1187 if (normalized) { 1188 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src, 16)); 1189 } else { 1190 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src, 16)); 1191 } 1192 break; 1193 case MESA_ARRAY_FORMAT_TYPE_HALF: 1194 if (normalized) { 1195 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src, 16)); 1196 } else { 1197 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src, 16)); 1198 } 1199 break; 1200 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1201 if (normalized) { 1202 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 16)); 1203 } else { 1204 SWIZZLE_CONVERT(uint16_t, uint8_t, src); 1205 } 1206 break; 1207 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1208 if (normalized) { 1209 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src, 8, 16)); 1210 } else { 1211 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src, 16)); 1212 } 1213 break; 1214 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1215 SWIZZLE_CONVERT(uint16_t, uint16_t, src); 1216 break; 1217 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1218 if (normalized) { 1219 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src, 16, 16)); 1220 } else { 1221 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src, 16)); 1222 } 1223 break; 1224 case MESA_ARRAY_FORMAT_TYPE_UINT: 1225 if (normalized) { 1226 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 16)); 1227 } else { 1228 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src, 16)); 1229 } 1230 break; 1231 case MESA_ARRAY_FORMAT_TYPE_INT: 1232 if (normalized) { 1233 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src, 32, 16)); 1234 } else { 1235 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src, 16)); 1236 } 1237 break; 1238 default: 1239 assert(!"Invalid channel type combination"); 1240 } 1241 } 1242 1243 1244 static void 1245 convert_short(void *void_dst, int num_dst_channels, 1246 const void *void_src, GLenum src_type, int num_src_channels, 1247 const uint8_t swizzle[4], bool normalized, int count) 1248 { 1249 const int16_t one = normalized ? INT16_MAX : 1; 1250 1251 switch (src_type) { 1252 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1253 if (normalized) { 1254 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src, 16)); 1255 } else { 1256 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src, 16)); 1257 } 1258 break; 1259 case MESA_ARRAY_FORMAT_TYPE_HALF: 1260 if (normalized) { 1261 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src, 16)); 1262 } else { 1263 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src, 16)); 1264 } 1265 break; 1266 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1267 if (normalized) { 1268 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 16)); 1269 } else { 1270 SWIZZLE_CONVERT(int16_t, uint8_t, src); 1271 } 1272 break; 1273 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1274 if (normalized) { 1275 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src, 8, 16)); 1276 } else { 1277 SWIZZLE_CONVERT(int16_t, int8_t, src); 1278 } 1279 break; 1280 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1281 if (normalized) { 1282 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 16)); 1283 } else { 1284 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src, 16)); 1285 } 1286 break; 1287 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1288 SWIZZLE_CONVERT(int16_t, int16_t, src); 1289 break; 1290 case MESA_ARRAY_FORMAT_TYPE_UINT: 1291 if (normalized) { 1292 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 16)); 1293 } else { 1294 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src, 16)); 1295 } 1296 break; 1297 case MESA_ARRAY_FORMAT_TYPE_INT: 1298 if (normalized) { 1299 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src, 32, 16)); 1300 } else { 1301 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src, 16)); 1302 } 1303 break; 1304 default: 1305 assert(!"Invalid channel type combination"); 1306 } 1307 } 1308 1309 static void 1310 convert_uint(void *void_dst, int num_dst_channels, 1311 const void *void_src, GLenum src_type, int num_src_channels, 1312 const uint8_t swizzle[4], bool normalized, int count) 1313 { 1314 const uint32_t one = normalized ? UINT32_MAX : 1; 1315 1316 switch (src_type) { 1317 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1318 if (normalized) { 1319 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src, 32)); 1320 } else { 1321 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src, 32)); 1322 } 1323 break; 1324 case MESA_ARRAY_FORMAT_TYPE_HALF: 1325 if (normalized) { 1326 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src, 32)); 1327 } else { 1328 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src, 32)); 1329 } 1330 break; 1331 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1332 if (normalized) { 1333 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 32)); 1334 } else { 1335 SWIZZLE_CONVERT(uint32_t, uint8_t, src); 1336 } 1337 break; 1338 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1339 if (normalized) { 1340 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src, 8, 32)); 1341 } else { 1342 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src, 32)); 1343 } 1344 break; 1345 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1346 if (normalized) { 1347 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 32)); 1348 } else { 1349 SWIZZLE_CONVERT(uint32_t, uint16_t, src); 1350 } 1351 break; 1352 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1353 if (normalized) { 1354 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src, 16, 32)); 1355 } else { 1356 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src, 32)); 1357 } 1358 break; 1359 case MESA_ARRAY_FORMAT_TYPE_UINT: 1360 SWIZZLE_CONVERT(uint32_t, uint32_t, src); 1361 break; 1362 case MESA_ARRAY_FORMAT_TYPE_INT: 1363 if (normalized) { 1364 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src, 32, 32)); 1365 } else { 1366 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src, 32)); 1367 } 1368 break; 1369 default: 1370 assert(!"Invalid channel type combination"); 1371 } 1372 } 1373 1374 1375 static void 1376 convert_int(void *void_dst, int num_dst_channels, 1377 const void *void_src, GLenum src_type, int num_src_channels, 1378 const uint8_t swizzle[4], bool normalized, int count) 1379 { 1380 const int32_t one = normalized ? INT32_MAX : 1; 1381 1382 switch (src_type) { 1383 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1384 if (normalized) { 1385 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src, 32)); 1386 } else { 1387 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src, 32)); 1388 } 1389 break; 1390 case MESA_ARRAY_FORMAT_TYPE_HALF: 1391 if (normalized) { 1392 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src, 32)); 1393 } else { 1394 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src, 32)); 1395 } 1396 break; 1397 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1398 if (normalized) { 1399 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 32)); 1400 } else { 1401 SWIZZLE_CONVERT(int32_t, uint8_t, src); 1402 } 1403 break; 1404 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1405 if (normalized) { 1406 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src, 8, 32)); 1407 } else { 1408 SWIZZLE_CONVERT(int32_t, int8_t, src); 1409 } 1410 break; 1411 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1412 if (normalized) { 1413 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 32)); 1414 } else { 1415 SWIZZLE_CONVERT(int32_t, uint16_t, src); 1416 } 1417 break; 1418 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1419 if (normalized) { 1420 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src, 16, 32)); 1421 } else { 1422 SWIZZLE_CONVERT(int32_t, int16_t, src); 1423 } 1424 break; 1425 case MESA_ARRAY_FORMAT_TYPE_UINT: 1426 if (normalized) { 1427 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 32)); 1428 } else { 1429 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src, 32)); 1430 } 1431 break; 1432 case MESA_ARRAY_FORMAT_TYPE_INT: 1433 SWIZZLE_CONVERT(int32_t, int32_t, src); 1434 break; 1435 default: 1436 assert(!"Invalid channel type combination"); 1437 } 1438 } 1439 1440 1441 /** 1442 * Convert between array-based color formats. 1443 * 1444 * Most format conversion operations required by GL can be performed by 1445 * converting one channel at a time, shuffling the channels around, and 1446 * optionally filling missing channels with zeros and ones. This function 1447 * does just that in a general, yet efficient, way. 1448 * 1449 * The swizzle parameter is an array of 4 numbers (see 1450 * _mesa_get_format_swizzle) that describes where each channel in the 1451 * destination should come from in the source. If swizzle[i] < 4 then it 1452 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is 1453 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding 1454 * dst[i] will be filled with the appropreate representation of zero or one 1455 * respectively. 1456 * 1457 * Under most circumstances, the source and destination images must be 1458 * different as no care is taken not to clobber one with the other. 1459 * However, if they have the same number of bits per pixel, it is safe to 1460 * do an in-place conversion. 1461 * 1462 * \param[out] dst pointer to where the converted data should 1463 * be stored 1464 * 1465 * \param[in] dst_type the destination GL type of the converted 1466 * data (GL_BYTE, etc.) 1467 * 1468 * \param[in] num_dst_channels the number of channels in the converted 1469 * data 1470 * 1471 * \param[in] src pointer to the source data 1472 * 1473 * \param[in] src_type the GL type of the source data (GL_BYTE, 1474 * etc.) 1475 * 1476 * \param[in] num_src_channels the number of channels in the source data 1477 * (the number of channels total, not just 1478 * the number used) 1479 * 1480 * \param[in] swizzle describes how to get the destination data 1481 * from the source data. 1482 * 1483 * \param[in] normalized for integer types, this indicates whether 1484 * the data should be considered as integers 1485 * or as normalized integers; 1486 * 1487 * \param[in] count the number of pixels to convert 1488 */ 1489 void 1490 _mesa_swizzle_and_convert(void *void_dst, enum mesa_array_format_datatype dst_type, int num_dst_channels, 1491 const void *void_src, enum mesa_array_format_datatype src_type, int num_src_channels, 1492 const uint8_t swizzle[4], bool normalized, int count) 1493 { 1494 if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels, 1495 void_src, src_type, num_src_channels, 1496 swizzle, normalized, count)) 1497 return; 1498 1499 switch (dst_type) { 1500 case MESA_ARRAY_FORMAT_TYPE_FLOAT: 1501 convert_float(void_dst, num_dst_channels, void_src, src_type, 1502 num_src_channels, swizzle, normalized, count); 1503 break; 1504 case MESA_ARRAY_FORMAT_TYPE_HALF: 1505 convert_half_float(void_dst, num_dst_channels, void_src, src_type, 1506 num_src_channels, swizzle, normalized, count); 1507 break; 1508 case MESA_ARRAY_FORMAT_TYPE_UBYTE: 1509 convert_ubyte(void_dst, num_dst_channels, void_src, src_type, 1510 num_src_channels, swizzle, normalized, count); 1511 break; 1512 case MESA_ARRAY_FORMAT_TYPE_BYTE: 1513 convert_byte(void_dst, num_dst_channels, void_src, src_type, 1514 num_src_channels, swizzle, normalized, count); 1515 break; 1516 case MESA_ARRAY_FORMAT_TYPE_USHORT: 1517 convert_ushort(void_dst, num_dst_channels, void_src, src_type, 1518 num_src_channels, swizzle, normalized, count); 1519 break; 1520 case MESA_ARRAY_FORMAT_TYPE_SHORT: 1521 convert_short(void_dst, num_dst_channels, void_src, src_type, 1522 num_src_channels, swizzle, normalized, count); 1523 break; 1524 case MESA_ARRAY_FORMAT_TYPE_UINT: 1525 convert_uint(void_dst, num_dst_channels, void_src, src_type, 1526 num_src_channels, swizzle, normalized, count); 1527 break; 1528 case MESA_ARRAY_FORMAT_TYPE_INT: 1529 convert_int(void_dst, num_dst_channels, void_src, src_type, 1530 num_src_channels, swizzle, normalized, count); 1531 break; 1532 default: 1533 assert(!"Invalid channel type"); 1534 } 1535 } 1536