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