u_tile.c revision ac400ffce62be47fc77e8d10cabcd39b92b6c627
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_stride(pt->texture->format, w); 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 util_copy_rect(dst, pt->texture->format, 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 enum pipe_format format = pt->texture->format; 82 83 if (src_stride == 0) 84 src_stride = pf_get_stride(format, w); 85 86 if (pipe_clip_tile(x, y, &w, &h, pt)) 87 return; 88 89 dst = screen->transfer_map(screen, pt); 90 assert(dst); 91 if(!dst) 92 return; 93 94 util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0); 95 96 screen->transfer_unmap(screen, pt); 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_X8R8G8B8_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] = 1.0F; 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_R8G8B8_UNORM ***/ 399 400static void 401r8g8b8_get_tile_rgba(const ubyte *src, 402 unsigned w, unsigned h, 403 float *p, 404 unsigned dst_stride) 405{ 406 unsigned i, j; 407 408 for (i = 0; i < h; i++) { 409 float *pRow = p; 410 for (j = 0; j < w; j++, pRow += 4) { 411 pRow[0] = ubyte_to_float(src[0]); 412 pRow[1] = ubyte_to_float(src[1]); 413 pRow[2] = ubyte_to_float(src[2]); 414 pRow[3] = 1.0f; 415 src += 3; 416 } 417 p += dst_stride; 418 } 419} 420 421 422static void 423r8g8b8_put_tile_rgba(ubyte *dst, 424 unsigned w, unsigned h, 425 const float *p, 426 unsigned src_stride) 427{ 428 unsigned i, j; 429 430 for (i = 0; i < h; i++) { 431 const float *pRow = p; 432 for (j = 0; j < w; j++, pRow += 4) { 433 dst[0] = float_to_ubyte(pRow[0]); 434 dst[1] = float_to_ubyte(pRow[1]); 435 dst[2] = float_to_ubyte(pRow[2]); 436 dst += 3; 437 } 438 p += src_stride; 439 } 440} 441 442 443 444/*** PIPE_FORMAT_Z16_UNORM ***/ 445 446/** 447 * Return each Z value as four floats in [0,1]. 448 */ 449static void 450z16_get_tile_rgba(const ushort *src, 451 unsigned w, unsigned h, 452 float *p, 453 unsigned dst_stride) 454{ 455 const float scale = 1.0f / 65535.0f; 456 unsigned i, j; 457 458 for (i = 0; i < h; i++) { 459 float *pRow = p; 460 for (j = 0; j < w; j++, pRow += 4) { 461 pRow[0] = 462 pRow[1] = 463 pRow[2] = 464 pRow[3] = *src++ * scale; 465 } 466 p += dst_stride; 467 } 468} 469 470 471 472 473/*** PIPE_FORMAT_L8_UNORM ***/ 474 475static void 476l8_get_tile_rgba(const ubyte *src, 477 unsigned w, unsigned h, 478 float *p, 479 unsigned dst_stride) 480{ 481 unsigned i, j; 482 483 for (i = 0; i < h; i++) { 484 float *pRow = p; 485 for (j = 0; j < w; j++, src++, pRow += 4) { 486 pRow[0] = 487 pRow[1] = 488 pRow[2] = ubyte_to_float(*src); 489 pRow[3] = 1.0; 490 } 491 p += dst_stride; 492 } 493} 494 495 496static void 497l8_put_tile_rgba(ubyte *dst, 498 unsigned w, unsigned h, 499 const float *p, 500 unsigned src_stride) 501{ 502 unsigned i, j; 503 504 for (i = 0; i < h; i++) { 505 const float *pRow = p; 506 for (j = 0; j < w; j++, pRow += 4) { 507 unsigned r; 508 r = float_to_ubyte(pRow[0]); 509 *dst++ = (ubyte) r; 510 } 511 p += src_stride; 512 } 513} 514 515 516 517/*** PIPE_FORMAT_A8_UNORM ***/ 518 519static void 520a8_get_tile_rgba(const ubyte *src, 521 unsigned w, unsigned h, 522 float *p, 523 unsigned dst_stride) 524{ 525 unsigned i, j; 526 527 for (i = 0; i < h; i++) { 528 float *pRow = p; 529 for (j = 0; j < w; j++, src++, pRow += 4) { 530 pRow[0] = 531 pRow[1] = 532 pRow[2] = 0.0; 533 pRow[3] = ubyte_to_float(*src); 534 } 535 p += dst_stride; 536 } 537} 538 539 540static void 541a8_put_tile_rgba(ubyte *dst, 542 unsigned w, unsigned h, 543 const float *p, 544 unsigned src_stride) 545{ 546 unsigned i, j; 547 548 for (i = 0; i < h; i++) { 549 const float *pRow = p; 550 for (j = 0; j < w; j++, pRow += 4) { 551 unsigned a; 552 a = float_to_ubyte(pRow[3]); 553 *dst++ = (ubyte) a; 554 } 555 p += src_stride; 556 } 557} 558 559 560 561/*** PIPE_FORMAT_R16_SNORM ***/ 562 563static void 564r16_get_tile_rgba(const short *src, 565 unsigned w, unsigned h, 566 float *p, 567 unsigned dst_stride) 568{ 569 unsigned i, j; 570 571 for (i = 0; i < h; i++) { 572 float *pRow = p; 573 for (j = 0; j < w; j++, src++, pRow += 4) { 574 pRow[0] = SHORT_TO_FLOAT(src[0]); 575 pRow[1] = 576 pRow[2] = 0.0; 577 pRow[3] = 1.0; 578 } 579 p += dst_stride; 580 } 581} 582 583 584static void 585r16_put_tile_rgba(short *dst, 586 unsigned w, unsigned h, 587 const float *p, 588 unsigned src_stride) 589{ 590 unsigned i, j; 591 592 for (i = 0; i < h; i++) { 593 const float *pRow = p; 594 for (j = 0; j < w; j++, dst++, pRow += 4) { 595 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); 596 } 597 p += src_stride; 598 } 599} 600 601 602/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ 603 604static void 605r16g16b16a16_get_tile_rgba(const short *src, 606 unsigned w, unsigned h, 607 float *p, 608 unsigned dst_stride) 609{ 610 unsigned i, j; 611 612 for (i = 0; i < h; i++) { 613 float *pRow = p; 614 for (j = 0; j < w; j++, src += 4, pRow += 4) { 615 pRow[0] = SHORT_TO_FLOAT(src[0]); 616 pRow[1] = SHORT_TO_FLOAT(src[1]); 617 pRow[2] = SHORT_TO_FLOAT(src[2]); 618 pRow[3] = SHORT_TO_FLOAT(src[3]); 619 } 620 p += dst_stride; 621 } 622} 623 624 625static void 626r16g16b16a16_put_tile_rgba(short *dst, 627 unsigned w, unsigned h, 628 const float *p, 629 unsigned src_stride) 630{ 631 unsigned i, j; 632 633 for (i = 0; i < h; i++) { 634 const float *pRow = p; 635 for (j = 0; j < w; j++, dst += 4, pRow += 4) { 636 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); 637 UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]); 638 UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]); 639 UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]); 640 } 641 p += src_stride; 642 } 643} 644 645 646/*** PIPE_FORMAT_R8G8B8A8_SRGB ***/ 647 648/** 649 * Convert an 8-bit sRGB value from non-linear space to a 650 * linear RGB value in [0, 1]. 651 * Implemented with a 256-entry lookup table. 652 */ 653static INLINE float 654srgb_to_linear(ubyte cs8) 655{ 656 static float table[256]; 657 static boolean tableReady = FALSE; 658 if (!tableReady) { 659 /* compute lookup table now */ 660 uint i; 661 for (i = 0; i < 256; i++) { 662 const float cs = ubyte_to_float(i); 663 if (cs <= 0.04045) { 664 table[i] = cs / 12.92f; 665 } 666 else { 667 table[i] = (float) powf((cs + 0.055) / 1.055, 2.4); 668 } 669 } 670 tableReady = TRUE; 671 } 672 return table[cs8]; 673} 674 675 676/** 677 * Convert linear float in [0,1] to an srgb ubyte value in [0,255]. 678 * XXX this hasn't been tested (render to srgb surface). 679 * XXX this needs optimization. 680 */ 681static INLINE ubyte 682linear_to_srgb(float cl) 683{ 684 if (cl >= 1.0F) 685 return 255; 686 else if (cl >= 0.0031308F) 687 return float_to_ubyte(1.055F * powf(cl, 0.41666F) - 0.055F); 688 else if (cl > 0.0F) 689 return float_to_ubyte(12.92F * cl); 690 else 691 return 0.0; 692} 693 694 695static void 696a8r8g8b8_srgb_get_tile_rgba(const unsigned *src, 697 unsigned w, unsigned h, 698 float *p, 699 unsigned dst_stride) 700{ 701 unsigned i, j; 702 703 for (i = 0; i < h; i++) { 704 float *pRow = p; 705 for (j = 0; j < w; j++, pRow += 4) { 706 const unsigned pixel = *src++; 707 pRow[0] = srgb_to_linear((pixel >> 16) & 0xff); 708 pRow[1] = srgb_to_linear((pixel >> 8) & 0xff); 709 pRow[2] = srgb_to_linear((pixel >> 0) & 0xff); 710 pRow[3] = ubyte_to_float((pixel >> 24) & 0xff); 711 } 712 p += dst_stride; 713 } 714} 715 716static void 717a8r8g8b8_srgb_put_tile_rgba(unsigned *dst, 718 unsigned w, unsigned h, 719 const float *p, 720 unsigned src_stride) 721{ 722 unsigned i, j; 723 724 for (i = 0; i < h; i++) { 725 const float *pRow = p; 726 for (j = 0; j < w; j++, pRow += 4) { 727 unsigned r, g, b, a; 728 r = linear_to_srgb(pRow[0]); 729 g = linear_to_srgb(pRow[1]); 730 b = linear_to_srgb(pRow[2]); 731 a = float_to_ubyte(pRow[3]); 732 *dst++ = (a << 24) | (r << 16) | (g << 8) | b; 733 } 734 p += src_stride; 735 } 736} 737 738 739/*** PIPE_FORMAT_A8L8_SRGB ***/ 740 741static void 742a8l8_srgb_get_tile_rgba(const ushort *src, 743 unsigned w, unsigned h, 744 float *p, 745 unsigned dst_stride) 746{ 747 unsigned i, j; 748 749 for (i = 0; i < h; i++) { 750 float *pRow = p; 751 for (j = 0; j < w; j++, pRow += 4) { 752 ushort p = *src++; 753 pRow[0] = 754 pRow[1] = 755 pRow[2] = srgb_to_linear(p & 0xff); 756 pRow[3] = ubyte_to_float(p >> 8); 757 } 758 p += dst_stride; 759 } 760} 761 762static void 763a8l8_srgb_put_tile_rgba(ushort *dst, 764 unsigned w, unsigned h, 765 const float *p, 766 unsigned src_stride) 767{ 768 unsigned i, j; 769 770 for (i = 0; i < h; i++) { 771 const float *pRow = p; 772 for (j = 0; j < w; j++, pRow += 4) { 773 unsigned r, a; 774 r = linear_to_srgb(pRow[0]); 775 a = float_to_ubyte(pRow[3]); 776 *dst++ = (a << 8) | r; 777 } 778 p += src_stride; 779 } 780} 781 782 783/*** PIPE_FORMAT_L8_SRGB ***/ 784 785static void 786l8_srgb_get_tile_rgba(const ubyte *src, 787 unsigned w, unsigned h, 788 float *p, 789 unsigned dst_stride) 790{ 791 unsigned i, j; 792 793 for (i = 0; i < h; i++) { 794 float *pRow = p; 795 for (j = 0; j < w; j++, src++, pRow += 4) { 796 pRow[0] = 797 pRow[1] = 798 pRow[2] = srgb_to_linear(*src); 799 pRow[3] = 1.0; 800 } 801 p += dst_stride; 802 } 803} 804 805static void 806l8_srgb_put_tile_rgba(ubyte *dst, 807 unsigned w, unsigned h, 808 const float *p, 809 unsigned src_stride) 810{ 811 unsigned i, j; 812 813 for (i = 0; i < h; i++) { 814 const float *pRow = p; 815 for (j = 0; j < w; j++, pRow += 4) { 816 unsigned r; 817 r = linear_to_srgb(pRow[0]); 818 *dst++ = (ubyte) r; 819 } 820 p += src_stride; 821 } 822} 823 824 825/*** PIPE_FORMAT_I8_UNORM ***/ 826 827static void 828i8_get_tile_rgba(const ubyte *src, 829 unsigned w, unsigned h, 830 float *p, 831 unsigned dst_stride) 832{ 833 unsigned i, j; 834 835 for (i = 0; i < h; i++) { 836 float *pRow = p; 837 for (j = 0; j < w; j++, src++, pRow += 4) { 838 pRow[0] = 839 pRow[1] = 840 pRow[2] = 841 pRow[3] = ubyte_to_float(*src); 842 } 843 p += dst_stride; 844 } 845} 846 847 848static void 849i8_put_tile_rgba(ubyte *dst, 850 unsigned w, unsigned h, 851 const float *p, 852 unsigned src_stride) 853{ 854 unsigned i, j; 855 856 for (i = 0; i < h; i++) { 857 const float *pRow = p; 858 for (j = 0; j < w; j++, pRow += 4) { 859 unsigned r; 860 r = float_to_ubyte(pRow[0]); 861 *dst++ = (ubyte) r; 862 } 863 p += src_stride; 864 } 865} 866 867 868/*** PIPE_FORMAT_A8L8_UNORM ***/ 869 870static void 871a8l8_get_tile_rgba(const ushort *src, 872 unsigned w, unsigned h, 873 float *p, 874 unsigned dst_stride) 875{ 876 unsigned i, j; 877 878 for (i = 0; i < h; i++) { 879 float *pRow = p; 880 for (j = 0; j < w; j++, pRow += 4) { 881 ushort p = *src++; 882 pRow[0] = 883 pRow[1] = 884 pRow[2] = ubyte_to_float(p & 0xff); 885 pRow[3] = ubyte_to_float(p >> 8); 886 } 887 p += dst_stride; 888 } 889} 890 891 892static void 893a8l8_put_tile_rgba(ushort *dst, 894 unsigned w, unsigned h, 895 const float *p, 896 unsigned src_stride) 897{ 898 unsigned i, j; 899 900 for (i = 0; i < h; i++) { 901 const float *pRow = p; 902 for (j = 0; j < w; j++, pRow += 4) { 903 unsigned r, a; 904 r = float_to_ubyte(pRow[0]); 905 a = float_to_ubyte(pRow[3]); 906 *dst++ = (a << 8) | r; 907 } 908 p += src_stride; 909 } 910} 911 912 913 914 915/*** PIPE_FORMAT_Z32_UNORM ***/ 916 917/** 918 * Return each Z value as four floats in [0,1]. 919 */ 920static void 921z32_get_tile_rgba(const unsigned *src, 922 unsigned w, unsigned h, 923 float *p, 924 unsigned dst_stride) 925{ 926 const double scale = 1.0 / (double) 0xffffffff; 927 unsigned i, j; 928 929 for (i = 0; i < h; i++) { 930 float *pRow = p; 931 for (j = 0; j < w; j++, pRow += 4) { 932 pRow[0] = 933 pRow[1] = 934 pRow[2] = 935 pRow[3] = (float) (*src++ * scale); 936 } 937 p += dst_stride; 938 } 939} 940 941 942/*** PIPE_FORMAT_S8Z24_UNORM ***/ 943 944/** 945 * Return Z component as four float in [0,1]. Stencil part ignored. 946 */ 947static void 948s8z24_get_tile_rgba(const unsigned *src, 949 unsigned w, unsigned h, 950 float *p, 951 unsigned dst_stride) 952{ 953 const double scale = 1.0 / ((1 << 24) - 1); 954 unsigned i, j; 955 956 for (i = 0; i < h; i++) { 957 float *pRow = p; 958 for (j = 0; j < w; j++, pRow += 4) { 959 pRow[0] = 960 pRow[1] = 961 pRow[2] = 962 pRow[3] = (float) (scale * (*src++ & 0xffffff)); 963 } 964 p += dst_stride; 965 } 966} 967 968 969/*** PIPE_FORMAT_Z24S8_UNORM ***/ 970 971/** 972 * Return Z component as four float in [0,1]. Stencil part ignored. 973 */ 974static void 975z24s8_get_tile_rgba(const unsigned *src, 976 unsigned w, unsigned h, 977 float *p, 978 unsigned dst_stride) 979{ 980 const double scale = 1.0 / ((1 << 24) - 1); 981 unsigned i, j; 982 983 for (i = 0; i < h; i++) { 984 float *pRow = p; 985 for (j = 0; j < w; j++, pRow += 4) { 986 pRow[0] = 987 pRow[1] = 988 pRow[2] = 989 pRow[3] = (float) (scale * (*src++ >> 8)); 990 } 991 p += dst_stride; 992 } 993} 994 995 996/*** PIPE_FORMAT_Z32_FLOAT ***/ 997 998/** 999 * Return each Z value as four floats in [0,1]. 1000 */ 1001static void 1002z32f_get_tile_rgba(const float *src, 1003 unsigned w, unsigned h, 1004 float *p, 1005 unsigned dst_stride) 1006{ 1007 unsigned i, j; 1008 1009 for (i = 0; i < h; i++) { 1010 float *pRow = p; 1011 for (j = 0; j < w; j++, pRow += 4) { 1012 pRow[0] = 1013 pRow[1] = 1014 pRow[2] = 1015 pRow[3] = *src++; 1016 } 1017 p += dst_stride; 1018 } 1019} 1020 1021 1022/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/ 1023 1024/** 1025 * Convert YCbCr (or YCrCb) to RGBA. 1026 */ 1027static void 1028ycbcr_get_tile_rgba(const ushort *src, 1029 unsigned w, unsigned h, 1030 float *p, 1031 unsigned dst_stride, 1032 boolean rev) 1033{ 1034 const float scale = 1.0f / 255.0f; 1035 unsigned i, j; 1036 1037 for (i = 0; i < h; i++) { 1038 float *pRow = p; 1039 /* do two texels at a time */ 1040 for (j = 0; j < (w & ~1); j += 2, src += 2) { 1041 const ushort t0 = src[0]; 1042 const ushort t1 = src[1]; 1043 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ 1044 const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */ 1045 ubyte cb, cr; 1046 float r, g, b; 1047 1048 if (rev) { 1049 cb = t1 & 0xff; /* chroma U */ 1050 cr = t0 & 0xff; /* chroma V */ 1051 } 1052 else { 1053 cb = t0 & 0xff; /* chroma U */ 1054 cr = t1 & 0xff; /* chroma V */ 1055 } 1056 1057 /* even pixel: y0,cr,cb */ 1058 r = 1.164f * (y0-16) + 1.596f * (cr-128); 1059 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); 1060 b = 1.164f * (y0-16) + 2.018f * (cb-128); 1061 pRow[0] = r * scale; 1062 pRow[1] = g * scale; 1063 pRow[2] = b * scale; 1064 pRow[3] = 1.0f; 1065 pRow += 4; 1066 1067 /* odd pixel: use y1,cr,cb */ 1068 r = 1.164f * (y1-16) + 1.596f * (cr-128); 1069 g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128); 1070 b = 1.164f * (y1-16) + 2.018f * (cb-128); 1071 pRow[0] = r * scale; 1072 pRow[1] = g * scale; 1073 pRow[2] = b * scale; 1074 pRow[3] = 1.0f; 1075 pRow += 4; 1076 1077 } 1078 /* do the last texel */ 1079 if (w & 1) { 1080 const ushort t0 = src[0]; 1081 const ushort t1 = src[1]; 1082 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ 1083 ubyte cb, cr; 1084 float r, g, b; 1085 1086 if (rev) { 1087 cb = t1 & 0xff; /* chroma U */ 1088 cr = t0 & 0xff; /* chroma V */ 1089 } 1090 else { 1091 cb = t0 & 0xff; /* chroma U */ 1092 cr = t1 & 0xff; /* chroma V */ 1093 } 1094 1095 /* even pixel: y0,cr,cb */ 1096 r = 1.164f * (y0-16) + 1.596f * (cr-128); 1097 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); 1098 b = 1.164f * (y0-16) + 2.018f * (cb-128); 1099 pRow[0] = r * scale; 1100 pRow[1] = g * scale; 1101 pRow[2] = b * scale; 1102 pRow[3] = 1.0f; 1103 pRow += 4; 1104 } 1105 p += dst_stride; 1106 } 1107} 1108 1109 1110static void 1111fake_get_tile_rgba(const ushort *src, 1112 unsigned w, unsigned h, 1113 float *p, 1114 unsigned dst_stride) 1115{ 1116 unsigned i, j; 1117 1118 for (i = 0; i < h; i++) { 1119 float *pRow = p; 1120 for (j = 0; j < w; j++, pRow += 4) { 1121 pRow[0] = 1122 pRow[1] = 1123 pRow[2] = 1124 pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f; 1125 } 1126 p += dst_stride; 1127 } 1128} 1129 1130 1131void 1132pipe_tile_raw_to_rgba(enum pipe_format format, 1133 void *src, 1134 uint w, uint h, 1135 float *dst, unsigned dst_stride) 1136{ 1137 switch (format) { 1138 case PIPE_FORMAT_A8R8G8B8_UNORM: 1139 a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 1140 break; 1141 case PIPE_FORMAT_X8R8G8B8_UNORM: 1142 x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 1143 break; 1144 case PIPE_FORMAT_B8G8R8A8_UNORM: 1145 b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 1146 break; 1147 case PIPE_FORMAT_A1R5G5B5_UNORM: 1148 a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 1149 break; 1150 case PIPE_FORMAT_A4R4G4B4_UNORM: 1151 a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 1152 break; 1153 case PIPE_FORMAT_R5G6B5_UNORM: 1154 r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 1155 break; 1156 case PIPE_FORMAT_R8G8B8_UNORM: 1157 r8g8b8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); 1158 break; 1159 case PIPE_FORMAT_L8_UNORM: 1160 l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); 1161 break; 1162 case PIPE_FORMAT_A8_UNORM: 1163 a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); 1164 break; 1165 case PIPE_FORMAT_I8_UNORM: 1166 i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); 1167 break; 1168 case PIPE_FORMAT_A8L8_UNORM: 1169 a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 1170 break; 1171 case PIPE_FORMAT_R16_SNORM: 1172 r16_get_tile_rgba((short *) src, w, h, dst, dst_stride); 1173 break; 1174 case PIPE_FORMAT_R16G16B16A16_SNORM: 1175 r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride); 1176 break; 1177 case PIPE_FORMAT_A8R8G8B8_SRGB: 1178 a8r8g8b8_srgb_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 1179 break; 1180 case PIPE_FORMAT_A8L8_SRGB: 1181 a8l8_srgb_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 1182 break; 1183 case PIPE_FORMAT_L8_SRGB: 1184 l8_srgb_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); 1185 break; 1186 case PIPE_FORMAT_Z16_UNORM: 1187 z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); 1188 break; 1189 case PIPE_FORMAT_Z32_UNORM: 1190 z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 1191 break; 1192 case PIPE_FORMAT_S8Z24_UNORM: 1193 case PIPE_FORMAT_X8Z24_UNORM: 1194 s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 1195 break; 1196 case PIPE_FORMAT_Z24S8_UNORM: 1197 case PIPE_FORMAT_Z24X8_UNORM: 1198 z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); 1199 break; 1200 case PIPE_FORMAT_Z32_FLOAT: 1201 z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride); 1202 break; 1203 case PIPE_FORMAT_YCBCR: 1204 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE); 1205 break; 1206 case PIPE_FORMAT_YCBCR_REV: 1207 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE); 1208 break; 1209 default: 1210 debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format)); 1211 fake_get_tile_rgba(src, w, h, dst, dst_stride); 1212 } 1213} 1214 1215 1216void 1217pipe_get_tile_rgba(struct pipe_transfer *pt, 1218 uint x, uint y, uint w, uint h, 1219 float *p) 1220{ 1221 unsigned dst_stride = w * 4; 1222 void *packed; 1223 enum pipe_format format = pt->texture->format; 1224 1225 if (pipe_clip_tile(x, y, &w, &h, pt)) 1226 return; 1227 1228 packed = MALLOC(pf_get_nblocks(format, w, h) * pf_get_blocksize(format)); 1229 1230 if (!packed) 1231 return; 1232 1233 if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV) 1234 assert((x & 1) == 0); 1235 1236 pipe_get_tile_raw(pt, x, y, w, h, packed, 0); 1237 1238 pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride); 1239 1240 FREE(packed); 1241} 1242 1243 1244void 1245pipe_put_tile_rgba(struct pipe_transfer *pt, 1246 uint x, uint y, uint w, uint h, 1247 const float *p) 1248{ 1249 unsigned src_stride = w * 4; 1250 void *packed; 1251 enum pipe_format format = pt->texture->format; 1252 1253 if (pipe_clip_tile(x, y, &w, &h, pt)) 1254 return; 1255 1256 packed = MALLOC(pf_get_nblocks(format, w, h) * pf_get_blocksize(format)); 1257 1258 if (!packed) 1259 return; 1260 1261 switch (format) { 1262 case PIPE_FORMAT_A8R8G8B8_UNORM: 1263 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); 1264 break; 1265 case PIPE_FORMAT_X8R8G8B8_UNORM: 1266 x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); 1267 break; 1268 case PIPE_FORMAT_B8G8R8A8_UNORM: 1269 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); 1270 break; 1271 case PIPE_FORMAT_A1R5G5B5_UNORM: 1272 a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1273 break; 1274 case PIPE_FORMAT_R5G6B5_UNORM: 1275 r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1276 break; 1277 case PIPE_FORMAT_R8G8B8_UNORM: 1278 r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); 1279 break; 1280 case PIPE_FORMAT_R8G8B8A8_UNORM: 1281 assert(0); 1282 break; 1283 case PIPE_FORMAT_A4R4G4B4_UNORM: 1284 a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1285 break; 1286 case PIPE_FORMAT_L8_UNORM: 1287 l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); 1288 break; 1289 case PIPE_FORMAT_A8_UNORM: 1290 a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); 1291 break; 1292 case PIPE_FORMAT_I8_UNORM: 1293 i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); 1294 break; 1295 case PIPE_FORMAT_A8L8_UNORM: 1296 a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1297 break; 1298 case PIPE_FORMAT_R16_SNORM: 1299 r16_put_tile_rgba((short *) packed, w, h, p, src_stride); 1300 break; 1301 case PIPE_FORMAT_R16G16B16A16_SNORM: 1302 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); 1303 break; 1304 case PIPE_FORMAT_A8R8G8B8_SRGB: 1305 a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); 1306 break; 1307 case PIPE_FORMAT_A8L8_SRGB: 1308 a8l8_srgb_put_tile_rgba((ushort *) packed, w, h, p, src_stride); 1309 break; 1310 case PIPE_FORMAT_L8_SRGB: 1311 l8_srgb_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); 1312 break; 1313 case PIPE_FORMAT_Z16_UNORM: 1314 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ 1315 break; 1316 case PIPE_FORMAT_Z32_UNORM: 1317 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 1318 break; 1319 case PIPE_FORMAT_S8Z24_UNORM: 1320 case PIPE_FORMAT_X8Z24_UNORM: 1321 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 1322 break; 1323 case PIPE_FORMAT_Z24S8_UNORM: 1324 case PIPE_FORMAT_Z24X8_UNORM: 1325 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ 1326 break; 1327 default: 1328 debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format)); 1329 } 1330 1331 pipe_put_tile_raw(pt, x, y, w, h, packed, 0); 1332 1333 FREE(packed); 1334} 1335 1336 1337/** 1338 * Get a block of Z values, converted to 32-bit range. 1339 */ 1340void 1341pipe_get_tile_z(struct pipe_transfer *pt, 1342 uint x, uint y, uint w, uint h, 1343 uint *z) 1344{ 1345 struct pipe_screen *screen = pt->texture->screen; 1346 const uint dstStride = w; 1347 ubyte *map; 1348 uint *pDest = z; 1349 uint i, j; 1350 enum pipe_format format = pt->texture->format; 1351 1352 if (pipe_clip_tile(x, y, &w, &h, pt)) 1353 return; 1354 1355 map = (ubyte *)screen->transfer_map(screen, pt); 1356 if (!map) { 1357 assert(0); 1358 return; 1359 } 1360 1361 switch (format) { 1362 case PIPE_FORMAT_Z32_UNORM: 1363 { 1364 const uint *ptrc 1365 = (const uint *)(map + y * pt->stride + x*4); 1366 for (i = 0; i < h; i++) { 1367 memcpy(pDest, ptrc, 4 * w); 1368 pDest += dstStride; 1369 ptrc += pt->stride/4; 1370 } 1371 } 1372 break; 1373 case PIPE_FORMAT_S8Z24_UNORM: 1374 case PIPE_FORMAT_X8Z24_UNORM: 1375 { 1376 const uint *ptrc 1377 = (const uint *)(map + y * pt->stride + x*4); 1378 for (i = 0; i < h; i++) { 1379 for (j = 0; j < w; j++) { 1380 /* convert 24-bit Z to 32-bit Z */ 1381 pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff); 1382 } 1383 pDest += dstStride; 1384 ptrc += pt->stride/4; 1385 } 1386 } 1387 break; 1388 case PIPE_FORMAT_Z24S8_UNORM: 1389 case PIPE_FORMAT_Z24X8_UNORM: 1390 { 1391 const uint *ptrc 1392 = (const uint *)(map + y * pt->stride + x*4); 1393 for (i = 0; i < h; i++) { 1394 for (j = 0; j < w; j++) { 1395 /* convert 24-bit Z to 32-bit Z */ 1396 pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff); 1397 } 1398 pDest += dstStride; 1399 ptrc += pt->stride/4; 1400 } 1401 } 1402 break; 1403 case PIPE_FORMAT_Z16_UNORM: 1404 { 1405 const ushort *ptrc 1406 = (const ushort *)(map + y * pt->stride + x*2); 1407 for (i = 0; i < h; i++) { 1408 for (j = 0; j < w; j++) { 1409 /* convert 16-bit Z to 32-bit Z */ 1410 pDest[j] = (ptrc[j] << 16) | ptrc[j]; 1411 } 1412 pDest += dstStride; 1413 ptrc += pt->stride/2; 1414 } 1415 } 1416 break; 1417 default: 1418 assert(0); 1419 } 1420 1421 screen->transfer_unmap(screen, pt); 1422} 1423 1424 1425void 1426pipe_put_tile_z(struct pipe_transfer *pt, 1427 uint x, uint y, uint w, uint h, 1428 const uint *zSrc) 1429{ 1430 struct pipe_screen *screen = pt->texture->screen; 1431 const uint srcStride = w; 1432 const uint *ptrc = zSrc; 1433 ubyte *map; 1434 uint i, j; 1435 enum pipe_format format = pt->texture->format; 1436 1437 if (pipe_clip_tile(x, y, &w, &h, pt)) 1438 return; 1439 1440 map = (ubyte *)screen->transfer_map(screen, pt); 1441 if (!map) { 1442 assert(0); 1443 return; 1444 } 1445 1446 switch (format) { 1447 case PIPE_FORMAT_Z32_UNORM: 1448 { 1449 uint *pDest = (uint *) (map + y * pt->stride + x*4); 1450 for (i = 0; i < h; i++) { 1451 memcpy(pDest, ptrc, 4 * w); 1452 pDest += pt->stride/4; 1453 ptrc += srcStride; 1454 } 1455 } 1456 break; 1457 case PIPE_FORMAT_S8Z24_UNORM: 1458 { 1459 uint *pDest = (uint *) (map + y * pt->stride + x*4); 1460 assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE); 1461 for (i = 0; i < h; i++) { 1462 for (j = 0; j < w; j++) { 1463 /* convert 32-bit Z to 24-bit Z, preserve stencil */ 1464 pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8; 1465 } 1466 pDest += pt->stride/4; 1467 ptrc += srcStride; 1468 } 1469 } 1470 break; 1471 case PIPE_FORMAT_X8Z24_UNORM: 1472 { 1473 uint *pDest = (uint *) (map + y * pt->stride + x*4); 1474 for (i = 0; i < h; i++) { 1475 for (j = 0; j < w; j++) { 1476 /* convert 32-bit Z to 24-bit Z (0 stencil) */ 1477 pDest[j] = ptrc[j] >> 8; 1478 } 1479 pDest += pt->stride/4; 1480 ptrc += srcStride; 1481 } 1482 } 1483 break; 1484 case PIPE_FORMAT_Z24S8_UNORM: 1485 { 1486 uint *pDest = (uint *) (map + y * pt->stride + x*4); 1487 assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE); 1488 for (i = 0; i < h; i++) { 1489 for (j = 0; j < w; j++) { 1490 /* convert 32-bit Z to 24-bit Z, preserve stencil */ 1491 pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00); 1492 } 1493 pDest += pt->stride/4; 1494 ptrc += srcStride; 1495 } 1496 } 1497 break; 1498 case PIPE_FORMAT_Z24X8_UNORM: 1499 { 1500 uint *pDest = (uint *) (map + y * pt->stride + x*4); 1501 for (i = 0; i < h; i++) { 1502 for (j = 0; j < w; j++) { 1503 /* convert 32-bit Z to 24-bit Z (0 stencil) */ 1504 pDest[j] = ptrc[j] & 0xffffff00; 1505 } 1506 pDest += pt->stride/4; 1507 ptrc += srcStride; 1508 } 1509 } 1510 break; 1511 case PIPE_FORMAT_Z16_UNORM: 1512 { 1513 ushort *pDest = (ushort *) (map + y * pt->stride + x*2); 1514 for (i = 0; i < h; i++) { 1515 for (j = 0; j < w; j++) { 1516 /* convert 32-bit Z to 16-bit Z */ 1517 pDest[j] = ptrc[j] >> 16; 1518 } 1519 pDest += pt->stride/2; 1520 ptrc += srcStride; 1521 } 1522 } 1523 break; 1524 default: 1525 assert(0); 1526 } 1527 1528 screen->transfer_unmap(screen, pt); 1529} 1530 1531 1532