u_tile.c revision a7900748106a9ad339a4552ca944f2fa30486cfc
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28/** 29 * RGBA/float tile get/put functions. 30 * Usable both by drivers and state trackers. 31 */ 32 33 34#include "pipe/p_defines.h" 35#include "pipe/p_inlines.h" 36 37#include "util/u_math.h" 38#include "util/u_memory.h" 39#include "util/u_rect.h" 40#include "util/u_tile.h" 41 42 43/** 44 * Move raw block of pixels from transfer object to user memory. 45 */ 46void 47pipe_get_tile_raw(struct pipe_transfer *pt, 48 uint x, uint y, uint w, uint h, 49 void *dst, int dst_stride) 50{ 51 struct pipe_screen *screen = pt->texture->screen; 52 const void *src; 53 54 if (dst_stride == 0) 55 dst_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size; 56 57 if (pipe_clip_tile(x, y, &w, &h, pt)) 58 return; 59 60 src = screen->transfer_map(screen, pt); 61 assert(src); 62 if(!src) 63 return; 64 65 pipe_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y); 66 67 screen->transfer_unmap(screen, pt); 68} 69 70 71/** 72 * Move raw block of pixels from user memory to transfer object. 73 */ 74void 75pipe_put_tile_raw(struct pipe_transfer *pt, 76 uint x, uint y, uint w, uint h, 77 const void *src, int src_stride) 78{ 79 struct pipe_screen *screen = pt->texture->screen; 80 void *dst; 81 82 if (src_stride == 0) 83 src_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size; 84 85 if (pipe_clip_tile(x, y, &w, &h, pt)) 86 return; 87 88 dst = screen->transfer_map(screen, pt); 89 assert(dst); 90 if(!dst) 91 return; 92 93 pipe_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0); 94 95 screen->transfer_unmap(screen, pt); 96} 97 98 99 100 101/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ 102#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) 103 104#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ 105 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) 106 107 108 109/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ 110 111static void 112a8r8g8b8_get_tile_rgba(const unsigned *src, 113 unsigned w, unsigned h, 114 float *p, 115 unsigned dst_stride) 116{ 117 unsigned i, j; 118 119 for (i = 0; i < h; i++) { 120 float *pRow = p; 121 for (j = 0; j < w; j++, pRow += 4) { 122 const unsigned pixel = *src++; 123 pRow[0] = ubyte_to_float((pixel >> 16) & 0xff); 124 pRow[1] = ubyte_to_float((pixel >> 8) & 0xff); 125 pRow[2] = ubyte_to_float((pixel >> 0) & 0xff); 126 pRow[3] = ubyte_to_float((pixel >> 24) & 0xff); 127 } 128 p += dst_stride; 129 } 130} 131 132 133static void 134a8r8g8b8_put_tile_rgba(unsigned *dst, 135 unsigned w, unsigned h, 136 const float *p, 137 unsigned src_stride) 138{ 139 unsigned i, j; 140 141 for (i = 0; i < h; i++) { 142 const float *pRow = p; 143 for (j = 0; j < w; j++, pRow += 4) { 144 unsigned r, g, b, a; 145 r = float_to_ubyte(pRow[0]); 146 g = float_to_ubyte(pRow[1]); 147 b = float_to_ubyte(pRow[2]); 148 a = float_to_ubyte(pRow[3]); 149 *dst++ = (a << 24) | (r << 16) | (g << 8) | b; 150 } 151 p += src_stride; 152 } 153} 154 155 156/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ 157 158static void 159x8r8g8b8_get_tile_rgba(const unsigned *src, 160 unsigned w, unsigned h, 161 float *p, 162 unsigned dst_stride) 163{ 164 unsigned i, j; 165 166 for (i = 0; i < h; i++) { 167 float *pRow = p; 168 for (j = 0; j < w; j++, pRow += 4) { 169 const unsigned pixel = *src++; 170 pRow[0] = ubyte_to_float((pixel >> 16) & 0xff); 171 pRow[1] = ubyte_to_float((pixel >> 8) & 0xff); 172 pRow[2] = ubyte_to_float((pixel >> 0) & 0xff); 173 pRow[3] = ubyte_to_float(0xff); 174 } 175 p += dst_stride; 176 } 177} 178 179 180static void 181x8r8g8b8_put_tile_rgba(unsigned *dst, 182 unsigned w, unsigned h, 183 const float *p, 184 unsigned src_stride) 185{ 186 unsigned i, j; 187 188 for (i = 0; i < h; i++) { 189 const float *pRow = p; 190 for (j = 0; j < w; j++, pRow += 4) { 191 unsigned r, g, b; 192 r = float_to_ubyte(pRow[0]); 193 g = float_to_ubyte(pRow[1]); 194 b = float_to_ubyte(pRow[2]); 195 *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b; 196 } 197 p += src_stride; 198 } 199} 200 201 202/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ 203 204static void 205b8g8r8a8_get_tile_rgba(const unsigned *src, 206 unsigned w, unsigned h, 207 float *p, 208 unsigned dst_stride) 209{ 210 unsigned i, j; 211 212 for (i = 0; i < h; i++) { 213 float *pRow = p; 214 for (j = 0; j < w; j++, pRow += 4) { 215 const unsigned pixel = *src++; 216 pRow[0] = ubyte_to_float((pixel >> 8) & 0xff); 217 pRow[1] = ubyte_to_float((pixel >> 16) & 0xff); 218 pRow[2] = ubyte_to_float((pixel >> 24) & 0xff); 219 pRow[3] = ubyte_to_float((pixel >> 0) & 0xff); 220 } 221 p += dst_stride; 222 } 223} 224 225 226static void 227b8g8r8a8_put_tile_rgba(unsigned *dst, 228 unsigned w, unsigned h, 229 const float *p, 230 unsigned src_stride) 231{ 232 unsigned i, j; 233 234 for (i = 0; i < h; i++) { 235 const float *pRow = p; 236 for (j = 0; j < w; j++, pRow += 4) { 237 unsigned r, g, b, a; 238 r = float_to_ubyte(pRow[0]); 239 g = float_to_ubyte(pRow[1]); 240 b = float_to_ubyte(pRow[2]); 241 a = float_to_ubyte(pRow[3]); 242 *dst++ = (b << 24) | (g << 16) | (r << 8) | a; 243 } 244 p += src_stride; 245 } 246} 247 248 249/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ 250 251static void 252a1r5g5b5_get_tile_rgba(const ushort *src, 253 unsigned w, unsigned h, 254 float *p, 255 unsigned dst_stride) 256{ 257 unsigned i, j; 258 259 for (i = 0; i < h; i++) { 260 float *pRow = p; 261 for (j = 0; j < w; j++, pRow += 4) { 262 const ushort pixel = *src++; 263 pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f); 264 pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f); 265 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); 266 pRow[3] = ((pixel >> 15) ) * 1.0f; 267 } 268 p += dst_stride; 269 } 270} 271 272 273static void 274a1r5g5b5_put_tile_rgba(ushort *dst, 275 unsigned w, unsigned h, 276 const float *p, 277 unsigned src_stride) 278{ 279 unsigned i, j; 280 281 for (i = 0; i < h; i++) { 282 const float *pRow = p; 283 for (j = 0; j < w; j++, pRow += 4) { 284 unsigned r, g, b, a; 285 r = float_to_ubyte(pRow[0]); 286 g = float_to_ubyte(pRow[1]); 287 b = float_to_ubyte(pRow[2]); 288 a = float_to_ubyte(pRow[3]); 289 r = r >> 3; /* 5 bits */ 290 g = g >> 3; /* 5 bits */ 291 b = b >> 3; /* 5 bits */ 292 a = a >> 7; /* 1 bit */ 293 *dst++ = (a << 15) | (r << 10) | (g << 5) | b; 294 } 295 p += src_stride; 296 } 297} 298 299 300/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ 301 302static void 303a4r4g4b4_get_tile_rgba(const ushort *src, 304 unsigned w, unsigned h, 305 float *p, 306 unsigned dst_stride) 307{ 308 unsigned i, j; 309 310 for (i = 0; i < h; i++) { 311 float *pRow = p; 312 for (j = 0; j < w; j++, pRow += 4) { 313 const ushort pixel = *src++; 314 pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f); 315 pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f); 316 pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f); 317 pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f); 318 } 319 p += dst_stride; 320 } 321} 322 323 324static void 325a4r4g4b4_put_tile_rgba(ushort *dst, 326 unsigned w, unsigned h, 327 const float *p, 328 unsigned src_stride) 329{ 330 unsigned i, j; 331 332 for (i = 0; i < h; i++) { 333 const float *pRow = p; 334 for (j = 0; j < w; j++, pRow += 4) { 335 unsigned r, g, b, a; 336 r = float_to_ubyte(pRow[0]); 337 g = float_to_ubyte(pRow[1]); 338 b = float_to_ubyte(pRow[2]); 339 a = float_to_ubyte(pRow[3]); 340 r >>= 4; 341 g >>= 4; 342 b >>= 4; 343 a >>= 4; 344 *dst++ = (a << 12) | (r << 16) | (g << 4) | b; 345 } 346 p += src_stride; 347 } 348} 349 350 351/*** PIPE_FORMAT_R5G6B5_UNORM ***/ 352 353static void 354r5g6b5_get_tile_rgba(const ushort *src, 355 unsigned w, unsigned h, 356 float *p, 357 unsigned dst_stride) 358{ 359 unsigned i, j; 360 361 for (i = 0; i < h; i++) { 362 float *pRow = p; 363 for (j = 0; j < w; j++, pRow += 4) { 364 const ushort pixel = *src++; 365 pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f); 366 pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f); 367 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); 368 pRow[3] = 1.0f; 369 } 370 p += dst_stride; 371 } 372} 373 374 375static void 376r5g6b5_put_tile_rgba(ushort *dst, 377 unsigned w, unsigned h, 378 const float *p, 379 unsigned src_stride) 380{ 381 unsigned i, j; 382 383 for (i = 0; i < h; i++) { 384 const float *pRow = p; 385 for (j = 0; j < w; j++, pRow += 4) { 386 uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0); 387 uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0); 388 uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0); 389 *dst++ = (r << 11) | (g << 5) | (b); 390 } 391 p += src_stride; 392 } 393} 394 395 396 397/*** PIPE_FORMAT_Z16_UNORM ***/ 398 399/** 400 * Return each Z value as four floats in [0,1]. 401 */ 402static void 403z16_get_tile_rgba(const ushort *src, 404 unsigned w, unsigned h, 405 float *p, 406 unsigned dst_stride) 407{ 408 const float scale = 1.0f / 65535.0f; 409 unsigned i, j; 410 411 for (i = 0; i < h; i++) { 412 float *pRow = p; 413 for (j = 0; j < w; j++, pRow += 4) { 414 pRow[0] = 415 pRow[1] = 416 pRow[2] = 417 pRow[3] = *src++ * scale; 418 } 419 p += dst_stride; 420 } 421} 422 423 424 425 426/*** PIPE_FORMAT_L8_UNORM ***/ 427 428static void 429l8_get_tile_rgba(const ubyte *src, 430 unsigned w, unsigned h, 431 float *p, 432 unsigned dst_stride) 433{ 434 unsigned i, j; 435 436 for (i = 0; i < h; i++) { 437 float *pRow = p; 438 for (j = 0; j < w; j++, src++, pRow += 4) { 439 pRow[0] = 440 pRow[1] = 441 pRow[2] = ubyte_to_float(*src); 442 pRow[3] = 1.0; 443 } 444 p += dst_stride; 445 } 446} 447 448 449static void 450l8_put_tile_rgba(ubyte *dst, 451 unsigned w, unsigned h, 452 const float *p, 453 unsigned src_stride) 454{ 455 unsigned i, j; 456 457 for (i = 0; i < h; i++) { 458 const float *pRow = p; 459 for (j = 0; j < w; j++, pRow += 4) { 460 unsigned r; 461 r = float_to_ubyte(pRow[0]); 462 *dst++ = (ubyte) r; 463 } 464 p += src_stride; 465 } 466} 467 468 469 470/*** PIPE_FORMAT_A8_UNORM ***/ 471 472static void 473a8_get_tile_rgba(const ubyte *src, 474 unsigned w, unsigned h, 475 float *p, 476 unsigned dst_stride) 477{ 478 unsigned i, j; 479 480 for (i = 0; i < h; i++) { 481 float *pRow = p; 482 for (j = 0; j < w; j++, src++, pRow += 4) { 483 pRow[0] = 484 pRow[1] = 485 pRow[2] = 0.0; 486 pRow[3] = ubyte_to_float(*src); 487 } 488 p += dst_stride; 489 } 490} 491 492 493static void 494a8_put_tile_rgba(ubyte *dst, 495 unsigned w, unsigned h, 496 const float *p, 497 unsigned src_stride) 498{ 499 unsigned i, j; 500 501 for (i = 0; i < h; i++) { 502 const float *pRow = p; 503 for (j = 0; j < w; j++, pRow += 4) { 504 unsigned a; 505 a = float_to_ubyte(pRow[3]); 506 *dst++ = (ubyte) a; 507 } 508 p += src_stride; 509 } 510} 511 512 513 514/*** PIPE_FORMAT_R16_SNORM ***/ 515 516static void 517r16_get_tile_rgba(const short *src, 518 unsigned w, unsigned h, 519 float *p, 520 unsigned dst_stride) 521{ 522 unsigned i, j; 523 524 for (i = 0; i < h; i++) { 525 float *pRow = p; 526 for (j = 0; j < w; j++, src++, pRow += 4) { 527 pRow[0] = SHORT_TO_FLOAT(src[0]); 528 pRow[1] = 529 pRow[2] = 0.0; 530 pRow[3] = 1.0; 531 } 532 p += dst_stride; 533 } 534} 535 536 537static void 538r16_put_tile_rgba(short *dst, 539 unsigned w, unsigned h, 540 const float *p, 541 unsigned src_stride) 542{ 543 unsigned i, j; 544 545 for (i = 0; i < h; i++) { 546 const float *pRow = p; 547 for (j = 0; j < w; j++, dst++, pRow += 4) { 548 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); 549 } 550 p += src_stride; 551 } 552} 553 554 555/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ 556 557static void 558r16g16b16a16_get_tile_rgba(const short *src, 559 unsigned w, unsigned h, 560 float *p, 561 unsigned dst_stride) 562{ 563 unsigned i, j; 564 565 for (i = 0; i < h; i++) { 566 float *pRow = p; 567 for (j = 0; j < w; j++, src += 4, pRow += 4) { 568 pRow[0] = SHORT_TO_FLOAT(src[0]); 569 pRow[1] = SHORT_TO_FLOAT(src[1]); 570 pRow[2] = SHORT_TO_FLOAT(src[2]); 571 pRow[3] = SHORT_TO_FLOAT(src[3]); 572 } 573 p += dst_stride; 574 } 575} 576 577 578static void 579r16g16b16a16_put_tile_rgba(short *dst, 580 unsigned w, unsigned h, 581 const float *p, 582 unsigned src_stride) 583{ 584 unsigned i, j; 585 586 for (i = 0; i < h; i++) { 587 const float *pRow = p; 588 for (j = 0; j < w; j++, dst += 4, pRow += 4) { 589 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); 590 UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]); 591 UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]); 592 UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]); 593 } 594 p += src_stride; 595 } 596} 597 598 599 600/*** PIPE_FORMAT_I8_UNORM ***/ 601 602static void 603i8_get_tile_rgba(const ubyte *src, 604 unsigned w, unsigned h, 605 float *p, 606 unsigned dst_stride) 607{ 608 unsigned i, j; 609 610 for (i = 0; i < h; i++) { 611 float *pRow = p; 612 for (j = 0; j < w; j++, src++, pRow += 4) { 613 pRow[0] = 614 pRow[1] = 615 pRow[2] = 616 pRow[3] = ubyte_to_float(*src); 617 } 618 p += dst_stride; 619 } 620} 621 622 623static void 624i8_put_tile_rgba(ubyte *dst, 625 unsigned w, unsigned h, 626 const float *p, 627 unsigned src_stride) 628{ 629 unsigned i, j; 630 631 for (i = 0; i < h; i++) { 632 const float *pRow = p; 633 for (j = 0; j < w; j++, pRow += 4) { 634 unsigned r; 635 r = float_to_ubyte(pRow[0]); 636 *dst++ = (ubyte) r; 637 } 638 p += src_stride; 639 } 640} 641 642 643/*** PIPE_FORMAT_A8L8_UNORM ***/ 644 645static void 646a8l8_get_tile_rgba(const ushort *src, 647 unsigned w, unsigned h, 648 float *p, 649 unsigned dst_stride) 650{ 651 unsigned i, j; 652 653 for (i = 0; i < h; i++) { 654 float *pRow = p; 655 for (j = 0; j < w; j++, pRow += 4) { 656 ushort p = *src++; 657 pRow[0] = 658 pRow[1] = 659 pRow[2] = ubyte_to_float(p & 0xff); 660 pRow[3] = ubyte_to_float(p >> 8); 661 } 662 p += dst_stride; 663 } 664} 665 666 667static void 668a8l8_put_tile_rgba(ushort *dst, 669 unsigned w, unsigned h, 670 const float *p, 671 unsigned src_stride) 672{ 673 unsigned i, j; 674 675 for (i = 0; i < h; i++) { 676 const float *pRow = p; 677 for (j = 0; j < w; j++, pRow += 4) { 678 unsigned r, a; 679 r = float_to_ubyte(pRow[0]); 680 a = float_to_ubyte(pRow[3]); 681 *dst++ = (a << 8) | r; 682 } 683 p += src_stride; 684 } 685} 686 687 688 689 690/*** PIPE_FORMAT_Z32_UNORM ***/ 691 692/** 693 * Return each Z value as four floats in [0,1]. 694 */ 695static void 696z32_get_tile_rgba(const unsigned *src, 697 unsigned w, unsigned h, 698 float *p, 699 unsigned dst_stride) 700{ 701 const double scale = 1.0 / (double) 0xffffffff; 702 unsigned i, j; 703 704 for (i = 0; i < h; i++) { 705 float *pRow = p; 706 for (j = 0; j < w; j++, pRow += 4) { 707 pRow[0] = 708 pRow[1] = 709 pRow[2] = 710 pRow[3] = (float) (*src++ * scale); 711 } 712 p += dst_stride; 713 } 714} 715 716 717/*** PIPE_FORMAT_S8Z24_UNORM ***/ 718 719/** 720 * Return Z component as four float in [0,1]. Stencil part ignored. 721 */ 722static void 723s8z24_get_tile_rgba(const unsigned *src, 724 unsigned w, unsigned h, 725 float *p, 726 unsigned dst_stride) 727{ 728 const double scale = 1.0 / ((1 << 24) - 1); 729 unsigned i, j; 730 731 for (i = 0; i < h; i++) { 732 float *pRow = p; 733 for (j = 0; j < w; j++, pRow += 4) { 734 pRow[0] = 735 pRow[1] = 736 pRow[2] = 737 pRow[3] = (float) (scale * (*src++ & 0xffffff)); 738 } 739 p += dst_stride; 740 } 741} 742 743 744/*** PIPE_FORMAT_Z24S8_UNORM ***/ 745 746/** 747 * Return Z component as four float in [0,1]. Stencil part ignored. 748 */ 749static void 750z24s8_get_tile_rgba(const unsigned *src, 751 unsigned w, unsigned h, 752 float *p, 753 unsigned dst_stride) 754{ 755 const double scale = 1.0 / ((1 << 24) - 1); 756 unsigned i, j; 757 758 for (i = 0; i < h; i++) { 759 float *pRow = p; 760 for (j = 0; j < w; j++, pRow += 4) { 761 pRow[0] = 762 pRow[1] = 763 pRow[2] = 764 pRow[3] = (float) (scale * (*src++ >> 8)); 765 } 766 p += dst_stride; 767 } 768} 769 770 771/*** PIPE_FORMAT_Z32_FLOAT ***/ 772 773/** 774 * Return each Z value as four floats in [0,1]. 775 */ 776static void 777z32f_get_tile_rgba(const float *src, 778 unsigned w, unsigned h, 779 float *p, 780 unsigned dst_stride) 781{ 782 unsigned i, j; 783 784 for (i = 0; i < h; i++) { 785 float *pRow = p; 786 for (j = 0; j < w; j++, pRow += 4) { 787 pRow[0] = 788 pRow[1] = 789 pRow[2] = 790 pRow[3] = *src++; 791 } 792 p += dst_stride; 793 } 794} 795 796 797/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/ 798 799/** 800 * Convert YCbCr (or YCrCb) to RGBA. 801 */ 802static void 803ycbcr_get_tile_rgba(const ushort *src, 804 unsigned w, unsigned h, 805 float *p, 806 unsigned dst_stride, 807 boolean rev) 808{ 809 const float scale = 1.0f / 255.0f; 810 unsigned i, j; 811 812 for (i = 0; i < h; i++) { 813 float *pRow = p; 814 /* do two texels at a time */ 815 for (j = 0; j < (w & ~1); j += 2, src += 2) { 816 const ushort t0 = src[0]; 817 const ushort t1 = src[1]; 818 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ 819 const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */ 820 ubyte cb, cr; 821 float r, g, b; 822 823 if (rev) { 824 cb = t1 & 0xff; /* chroma U */ 825 cr = t0 & 0xff; /* chroma V */ 826 } 827 else { 828 cb = t0 & 0xff; /* chroma U */ 829 cr = t1 & 0xff; /* chroma V */ 830 } 831 832 /* even pixel: y0,cr,cb */ 833 r = 1.164f * (y0-16) + 1.596f * (cr-128); 834 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); 835 b = 1.164f * (y0-16) + 2.018f * (cb-128); 836 pRow[0] = r * scale; 837 pRow[1] = g * scale; 838 pRow[2] = b * scale; 839 pRow[3] = 1.0f; 840 pRow += 4; 841 842 /* odd pixel: use y1,cr,cb */ 843 r = 1.164f * (y1-16) + 1.596f * (cr-128); 844 g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128); 845 b = 1.164f * (y1-16) + 2.018f * (cb-128); 846 pRow[0] = r * scale; 847 pRow[1] = g * scale; 848 pRow[2] = b * scale; 849 pRow[3] = 1.0f; 850 pRow += 4; 851 852 } 853 /* do the last texel */ 854 if (w & 1) { 855 const ushort t0 = src[0]; 856 const ushort t1 = src[1]; 857 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ 858 ubyte cb, cr; 859 float r, g, b; 860 861 if (rev) { 862 cb = t1 & 0xff; /* chroma U */ 863 cr = t0 & 0xff; /* chroma V */ 864 } 865 else { 866 cb = t0 & 0xff; /* chroma U */ 867 cr = t1 & 0xff; /* chroma V */ 868 } 869 870 /* even pixel: y0,cr,cb */ 871 r = 1.164f * (y0-16) + 1.596f * (cr-128); 872 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); 873 b = 1.164f * (y0-16) + 2.018f * (cb-128); 874 pRow[0] = r * scale; 875 pRow[1] = g * scale; 876 pRow[2] = b * scale; 877 pRow[3] = 1.0f; 878 pRow += 4; 879 } 880 p += dst_stride; 881 } 882} 883 884 885static void 886fake_get_tile_rgba(const ushort *src, 887 unsigned w, unsigned h, 888 float *p, 889 unsigned dst_stride) 890{ 891 unsigned i, j; 892 893 for (i = 0; i < h; i++) { 894 float *pRow = p; 895 for (j = 0; j < w; j++, pRow += 4) { 896 pRow[0] = 897 pRow[1] = 898 pRow[2] = 899 pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f; 900 } 901 p += dst_stride; 902 } 903} 904 905 906void 907pipe_tile_raw_to_rgba(enum pipe_format format, 908 void *src, 909 uint w, uint h, 910 float *dst, unsigned dst_stride) 911{ 912 switch (format) { 913 case PIPE_FORMAT_A8R8G8B8_UNORM: 914 a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 915 break; 916 case PIPE_FORMAT_X8R8G8B8_UNORM: 917 x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 918 break; 919 case PIPE_FORMAT_B8G8R8A8_UNORM: 920 b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 921 break; 922 case PIPE_FORMAT_A1R5G5B5_UNORM: 923 a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 924 break; 925 case PIPE_FORMAT_A4R4G4B4_UNORM: 926 a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 927 break; 928 case PIPE_FORMAT_R5G6B5_UNORM: 929 r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 930 break; 931 case PIPE_FORMAT_L8_UNORM: 932 l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); 933 break; 934 case PIPE_FORMAT_A8_UNORM: 935 a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); 936 break; 937 case PIPE_FORMAT_I8_UNORM: 938 i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); 939 break; 940 case PIPE_FORMAT_A8L8_UNORM: 941 a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 942 break; 943 case PIPE_FORMAT_R16_SNORM: 944 r16_get_tile_rgba((short *) src, w, h, dst, dst_stride); 945 break; 946 case PIPE_FORMAT_R16G16B16A16_SNORM: 947 r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride); 948 break; 949 case PIPE_FORMAT_Z16_UNORM: 950 z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 951 break; 952 case PIPE_FORMAT_Z32_UNORM: 953 z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 954 break; 955 case PIPE_FORMAT_S8Z24_UNORM: 956 case PIPE_FORMAT_X8Z24_UNORM: 957 s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 958 break; 959 case PIPE_FORMAT_Z24S8_UNORM: 960 case PIPE_FORMAT_Z24X8_UNORM: 961 z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 962 break; 963 case PIPE_FORMAT_Z32_FLOAT: 964 z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride); 965 break; 966 case PIPE_FORMAT_YCBCR: 967 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE); 968 break; 969 case PIPE_FORMAT_YCBCR_REV: 970 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE); 971 break; 972 default: 973 debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format)); 974 fake_get_tile_rgba(src, w, h, dst, dst_stride); 975 } 976} 977 978 979void 980pipe_get_tile_rgba(struct pipe_transfer *pt, 981 uint x, uint y, uint w, uint h, 982 float *p) 983{ 984 unsigned dst_stride = w * 4; 985 void *packed; 986 987 if (pipe_clip_tile(x, y, &w, &h, pt)) 988 return; 989 990 packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size); 991 992 if (!packed) 993 return; 994 995 if(pt->format == PIPE_FORMAT_YCBCR || pt->format == PIPE_FORMAT_YCBCR_REV) 996 assert((x & 1) == 0); 997 998 pipe_get_tile_raw(pt, x, y, w, h, packed, 0); 999 1000 pipe_tile_raw_to_rgba(pt->format, packed, w, h, p, dst_stride); 1001 1002 FREE(packed); 1003} 1004 1005 1006void 1007pipe_put_tile_rgba(struct pipe_transfer *pt, 1008 uint x, uint y, uint w, uint h, 1009 const float *p) 1010{ 1011 unsigned src_stride = w * 4; 1012 void *packed; 1013 1014 if (pipe_clip_tile(x, y, &w, &h, pt)) 1015 return; 1016 1017 packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size); 1018 1019 if (!packed) 1020 return; 1021 1022 switch (pt->format) { 1023 case PIPE_FORMAT_A8R8G8B8_UNORM: 1024 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); 1025 break; 1026 case PIPE_FORMAT_X8R8G8B8_UNORM: 1027 x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); 1028 break; 1029 case PIPE_FORMAT_B8G8R8A8_UNORM: 1030 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); 1031 break; 1032 case PIPE_FORMAT_A1R5G5B5_UNORM: 1033 a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1034 break; 1035 case PIPE_FORMAT_R5G6B5_UNORM: 1036 r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1037 break; 1038 case PIPE_FORMAT_R8G8B8A8_UNORM: 1039 assert(0); 1040 break; 1041 case PIPE_FORMAT_A4R4G4B4_UNORM: 1042 a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1043 break; 1044 case PIPE_FORMAT_L8_UNORM: 1045 l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); 1046 break; 1047 case PIPE_FORMAT_A8_UNORM: 1048 a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); 1049 break; 1050 case PIPE_FORMAT_I8_UNORM: 1051 i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); 1052 break; 1053 case PIPE_FORMAT_A8L8_UNORM: 1054 a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1055 break; 1056 case PIPE_FORMAT_R16_SNORM: 1057 r16_put_tile_rgba((short *) packed, w, h, p, src_stride); 1058 break; 1059 case PIPE_FORMAT_R16G16B16A16_SNORM: 1060 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); 1061 break; 1062 case PIPE_FORMAT_Z16_UNORM: 1063 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ 1064 break; 1065 case PIPE_FORMAT_Z32_UNORM: 1066 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 1067 break; 1068 case PIPE_FORMAT_S8Z24_UNORM: 1069 case PIPE_FORMAT_X8Z24_UNORM: 1070 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 1071 break; 1072 case PIPE_FORMAT_Z24S8_UNORM: 1073 case PIPE_FORMAT_Z24X8_UNORM: 1074 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 1075 break; 1076 default: 1077 debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(pt->format)); 1078 } 1079 1080 pipe_put_tile_raw(pt, x, y, w, h, packed, 0); 1081 1082 FREE(packed); 1083} 1084 1085 1086/** 1087 * Get a block of Z values, converted to 32-bit range. 1088 */ 1089void 1090pipe_get_tile_z(struct pipe_transfer *pt, 1091 uint x, uint y, uint w, uint h, 1092 uint *z) 1093{ 1094 struct pipe_screen *screen = pt->texture->screen; 1095 const uint dstStride = w; 1096 ubyte *map; 1097 uint *pDest = z; 1098 uint i, j; 1099 1100 if (pipe_clip_tile(x, y, &w, &h, pt)) 1101 return; 1102 1103 map = (ubyte *)screen->transfer_map(screen, pt); 1104 if (!map) { 1105 assert(0); 1106 return; 1107 } 1108 1109 switch (pt->format) { 1110 case PIPE_FORMAT_Z32_UNORM: 1111 { 1112 const uint *ptrc 1113 = (const uint *)(map + y * pt->stride + x*4); 1114 for (i = 0; i < h; i++) { 1115 memcpy(pDest, ptrc, 4 * w); 1116 pDest += dstStride; 1117 ptrc += pt->stride/4; 1118 } 1119 } 1120 break; 1121 case PIPE_FORMAT_S8Z24_UNORM: 1122 case PIPE_FORMAT_X8Z24_UNORM: 1123 { 1124 const uint *ptrc 1125 = (const uint *)(map + y * pt->stride + x*4); 1126 for (i = 0; i < h; i++) { 1127 for (j = 0; j < w; j++) { 1128 /* convert 24-bit Z to 32-bit Z */ 1129 pDest[j] = (ptrc[j] << 8) | (ptrc[j] & 0xff); 1130 } 1131 pDest += dstStride; 1132 ptrc += pt->stride/4; 1133 } 1134 } 1135 break; 1136 case PIPE_FORMAT_Z16_UNORM: 1137 { 1138 const ushort *ptrc 1139 = (const ushort *)(map + y * pt->stride + x*2); 1140 for (i = 0; i < h; i++) { 1141 for (j = 0; j < w; j++) { 1142 /* convert 16-bit Z to 32-bit Z */ 1143 pDest[j] = (ptrc[j] << 16) | ptrc[j]; 1144 } 1145 pDest += dstStride; 1146 ptrc += pt->stride/2; 1147 } 1148 } 1149 break; 1150 default: 1151 assert(0); 1152 } 1153 1154 screen->transfer_unmap(screen, pt); 1155} 1156 1157 1158void 1159pipe_put_tile_z(struct pipe_transfer *pt, 1160 uint x, uint y, uint w, uint h, 1161 const uint *zSrc) 1162{ 1163 struct pipe_screen *screen = pt->texture->screen; 1164 const uint srcStride = w; 1165 const uint *ptrc = zSrc; 1166 ubyte *map; 1167 uint i, j; 1168 1169 if (pipe_clip_tile(x, y, &w, &h, pt)) 1170 return; 1171 1172 map = (ubyte *)screen->transfer_map(screen, pt); 1173 if (!map) { 1174 assert(0); 1175 return; 1176 } 1177 1178 switch (pt->format) { 1179 case PIPE_FORMAT_Z32_UNORM: 1180 { 1181 uint *pDest = (uint *) (map + y * pt->stride + x*4); 1182 for (i = 0; i < h; i++) { 1183 memcpy(pDest, ptrc, 4 * w); 1184 pDest += pt->stride/4; 1185 ptrc += srcStride; 1186 } 1187 } 1188 break; 1189 case PIPE_FORMAT_S8Z24_UNORM: 1190 case PIPE_FORMAT_X8Z24_UNORM: 1191 { 1192 uint *pDest = (uint *) (map + y * pt->stride + x*4); 1193 for (i = 0; i < h; i++) { 1194 for (j = 0; j < w; j++) { 1195 /* convert 32-bit Z to 24-bit Z (0 stencil) */ 1196 pDest[j] = ptrc[j] >> 8; 1197 } 1198 pDest += pt->stride/4; 1199 ptrc += srcStride; 1200 } 1201 } 1202 break; 1203 case PIPE_FORMAT_Z24S8_UNORM: 1204 case PIPE_FORMAT_Z24X8_UNORM: 1205 { 1206 uint *pDest = (uint *) (map + y * pt->stride + x*4); 1207 for (i = 0; i < h; i++) { 1208 for (j = 0; j < w; j++) { 1209 /* convert 32-bit Z to 24-bit Z (0 stencil) */ 1210 pDest[j] = ptrc[j] << 8; 1211 } 1212 pDest += pt->stride/4; 1213 ptrc += srcStride; 1214 } 1215 } 1216 break; 1217 case PIPE_FORMAT_Z16_UNORM: 1218 { 1219 ushort *pDest = (ushort *) (map + y * pt->stride + x*2); 1220 for (i = 0; i < h; i++) { 1221 for (j = 0; j < w; j++) { 1222 /* convert 32-bit Z to 16-bit Z */ 1223 pDest[j] = ptrc[j] >> 16; 1224 } 1225 pDest += pt->stride/2; 1226 ptrc += srcStride; 1227 } 1228 } 1229 break; 1230 default: 1231 assert(0); 1232 } 1233 1234 screen->transfer_unmap(screen, pt); 1235} 1236 1237 1238