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