00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00035 #include "pipe/p_defines.h"
00036 #include "pipe/p_inlines.h"
00037
00038 #include "util/u_math.h"
00039 #include "util/u_memory.h"
00040 #include "util/u_rect.h"
00041 #include "util/u_tile.h"
00042
00043
00048 void
00049 pipe_get_tile_raw(struct pipe_surface *ps,
00050 uint x, uint y, uint w, uint h,
00051 void *dst, int dst_stride)
00052 {
00053 const void *src;
00054
00055 if (dst_stride == 0)
00056 dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
00057
00058 if (pipe_clip_tile(x, y, &w, &h, ps))
00059 return;
00060
00061 src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ);
00062 assert(src);
00063 if(!src)
00064 return;
00065
00066 pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y);
00067
00068 pipe_surface_unmap(ps);
00069 }
00070
00071
00076 void
00077 pipe_put_tile_raw(struct pipe_surface *ps,
00078 uint x, uint y, uint w, uint h,
00079 const void *src, int src_stride)
00080 {
00081 void *dst;
00082
00083 if (src_stride == 0)
00084 src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
00085
00086 if (pipe_clip_tile(x, y, &w, &h, ps))
00087 return;
00088
00089 dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE);
00090 assert(dst);
00091 if(!dst)
00092 return;
00093
00094 pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0);
00095
00096 pipe_surface_unmap(ps);
00097 }
00098
00099
00100
00101
00103 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
00104
00105 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
00106 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
00107
00108
00109
00110
00111
00112 static void
00113 a8r8g8b8_get_tile_rgba(const unsigned *src,
00114 unsigned w, unsigned h,
00115 float *p,
00116 unsigned dst_stride)
00117 {
00118 unsigned i, j;
00119
00120 for (i = 0; i < h; i++) {
00121 float *pRow = p;
00122 for (j = 0; j < w; j++, pRow += 4) {
00123 const unsigned pixel = *src++;
00124 pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
00125 pRow[1] = ubyte_to_float((pixel >> 8) & 0xff);
00126 pRow[2] = ubyte_to_float((pixel >> 0) & 0xff);
00127 pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
00128 }
00129 p += dst_stride;
00130 }
00131 }
00132
00133
00134 static void
00135 a8r8g8b8_put_tile_rgba(unsigned *dst,
00136 unsigned w, unsigned h,
00137 const float *p,
00138 unsigned src_stride)
00139 {
00140 unsigned i, j;
00141
00142 for (i = 0; i < h; i++) {
00143 const float *pRow = p;
00144 for (j = 0; j < w; j++, pRow += 4) {
00145 unsigned r, g, b, a;
00146 r = float_to_ubyte(pRow[0]);
00147 g = float_to_ubyte(pRow[1]);
00148 b = float_to_ubyte(pRow[2]);
00149 a = float_to_ubyte(pRow[3]);
00150 *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
00151 }
00152 p += src_stride;
00153 }
00154 }
00155
00156
00157
00158
00159 static void
00160 x8r8g8b8_get_tile_rgba(const unsigned *src,
00161 unsigned w, unsigned h,
00162 float *p,
00163 unsigned dst_stride)
00164 {
00165 unsigned i, j;
00166
00167 for (i = 0; i < h; i++) {
00168 float *pRow = p;
00169 for (j = 0; j < w; j++, pRow += 4) {
00170 const unsigned pixel = *src++;
00171 pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
00172 pRow[1] = ubyte_to_float((pixel >> 8) & 0xff);
00173 pRow[2] = ubyte_to_float((pixel >> 0) & 0xff);
00174 pRow[3] = ubyte_to_float(0xff);
00175 }
00176 p += dst_stride;
00177 }
00178 }
00179
00180
00181 static void
00182 x8r8g8b8_put_tile_rgba(unsigned *dst,
00183 unsigned w, unsigned h,
00184 const float *p,
00185 unsigned src_stride)
00186 {
00187 unsigned i, j;
00188
00189 for (i = 0; i < h; i++) {
00190 const float *pRow = p;
00191 for (j = 0; j < w; j++, pRow += 4) {
00192 unsigned r, g, b;
00193 r = float_to_ubyte(pRow[0]);
00194 g = float_to_ubyte(pRow[1]);
00195 b = float_to_ubyte(pRow[2]);
00196 *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
00197 }
00198 p += src_stride;
00199 }
00200 }
00201
00202
00203
00204
00205 static void
00206 b8g8r8a8_get_tile_rgba(const unsigned *src,
00207 unsigned w, unsigned h,
00208 float *p,
00209 unsigned dst_stride)
00210 {
00211 unsigned i, j;
00212
00213 for (i = 0; i < h; i++) {
00214 float *pRow = p;
00215 for (j = 0; j < w; j++, pRow += 4) {
00216 const unsigned pixel = *src++;
00217 pRow[0] = ubyte_to_float((pixel >> 8) & 0xff);
00218 pRow[1] = ubyte_to_float((pixel >> 16) & 0xff);
00219 pRow[2] = ubyte_to_float((pixel >> 24) & 0xff);
00220 pRow[3] = ubyte_to_float((pixel >> 0) & 0xff);
00221 }
00222 p += dst_stride;
00223 }
00224 }
00225
00226
00227 static void
00228 b8g8r8a8_put_tile_rgba(unsigned *dst,
00229 unsigned w, unsigned h,
00230 const float *p,
00231 unsigned src_stride)
00232 {
00233 unsigned i, j;
00234
00235 for (i = 0; i < h; i++) {
00236 const float *pRow = p;
00237 for (j = 0; j < w; j++, pRow += 4) {
00238 unsigned r, g, b, a;
00239 r = float_to_ubyte(pRow[0]);
00240 g = float_to_ubyte(pRow[1]);
00241 b = float_to_ubyte(pRow[2]);
00242 a = float_to_ubyte(pRow[3]);
00243 *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
00244 }
00245 p += src_stride;
00246 }
00247 }
00248
00249
00250
00251
00252 static void
00253 a1r5g5b5_get_tile_rgba(const ushort *src,
00254 unsigned w, unsigned h,
00255 float *p,
00256 unsigned dst_stride)
00257 {
00258 unsigned i, j;
00259
00260 for (i = 0; i < h; i++) {
00261 float *pRow = p;
00262 for (j = 0; j < w; j++, pRow += 4) {
00263 const ushort pixel = *src++;
00264 pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
00265 pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
00266 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
00267 pRow[3] = ((pixel >> 15) ) * 1.0f;
00268 }
00269 p += dst_stride;
00270 }
00271 }
00272
00273
00274 static void
00275 a1r5g5b5_put_tile_rgba(ushort *dst,
00276 unsigned w, unsigned h,
00277 const float *p,
00278 unsigned src_stride)
00279 {
00280 unsigned i, j;
00281
00282 for (i = 0; i < h; i++) {
00283 const float *pRow = p;
00284 for (j = 0; j < w; j++, pRow += 4) {
00285 unsigned r, g, b, a;
00286 r = float_to_ubyte(pRow[0]);
00287 g = float_to_ubyte(pRow[1]);
00288 b = float_to_ubyte(pRow[2]);
00289 a = float_to_ubyte(pRow[3]);
00290 r = r >> 3;
00291 g = g >> 3;
00292 b = b >> 3;
00293 a = a >> 7;
00294 *dst++ = (a << 15) | (r << 10) | (g << 5) | b;
00295 }
00296 p += src_stride;
00297 }
00298 }
00299
00300
00301
00302
00303 static void
00304 a4r4g4b4_get_tile_rgba(const ushort *src,
00305 unsigned w, unsigned h,
00306 float *p,
00307 unsigned dst_stride)
00308 {
00309 unsigned i, j;
00310
00311 for (i = 0; i < h; i++) {
00312 float *pRow = p;
00313 for (j = 0; j < w; j++, pRow += 4) {
00314 const ushort pixel = *src++;
00315 pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f);
00316 pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f);
00317 pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f);
00318 pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f);
00319 }
00320 p += dst_stride;
00321 }
00322 }
00323
00324
00325 static void
00326 a4r4g4b4_put_tile_rgba(ushort *dst,
00327 unsigned w, unsigned h,
00328 const float *p,
00329 unsigned src_stride)
00330 {
00331 unsigned i, j;
00332
00333 for (i = 0; i < h; i++) {
00334 const float *pRow = p;
00335 for (j = 0; j < w; j++, pRow += 4) {
00336 unsigned r, g, b, a;
00337 r = float_to_ubyte(pRow[0]);
00338 g = float_to_ubyte(pRow[1]);
00339 b = float_to_ubyte(pRow[2]);
00340 a = float_to_ubyte(pRow[3]);
00341 r >>= 4;
00342 g >>= 4;
00343 b >>= 4;
00344 a >>= 4;
00345 *dst++ = (a << 12) | (r << 16) | (g << 4) | b;
00346 }
00347 p += src_stride;
00348 }
00349 }
00350
00351
00352
00353
00354 static void
00355 r5g6b5_get_tile_rgba(const ushort *src,
00356 unsigned w, unsigned h,
00357 float *p,
00358 unsigned dst_stride)
00359 {
00360 unsigned i, j;
00361
00362 for (i = 0; i < h; i++) {
00363 float *pRow = p;
00364 for (j = 0; j < w; j++, pRow += 4) {
00365 const ushort pixel = *src++;
00366 pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f);
00367 pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f);
00368 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
00369 pRow[3] = 1.0f;
00370 }
00371 p += dst_stride;
00372 }
00373 }
00374
00375
00376 static void
00377 r5g6b5_put_tile_rgba(ushort *dst,
00378 unsigned w, unsigned h,
00379 const float *p,
00380 unsigned src_stride)
00381 {
00382 unsigned i, j;
00383
00384 for (i = 0; i < h; i++) {
00385 const float *pRow = p;
00386 for (j = 0; j < w; j++, pRow += 4) {
00387 uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0);
00388 uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0);
00389 uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0);
00390 *dst++ = (r << 11) | (g << 5) | (b);
00391 }
00392 p += src_stride;
00393 }
00394 }
00395
00396
00397
00398
00399
00403 static void
00404 z16_get_tile_rgba(const ushort *src,
00405 unsigned w, unsigned h,
00406 float *p,
00407 unsigned dst_stride)
00408 {
00409 const float scale = 1.0f / 65535.0f;
00410 unsigned i, j;
00411
00412 for (i = 0; i < h; i++) {
00413 float *pRow = p;
00414 for (j = 0; j < w; j++, pRow += 4) {
00415 pRow[0] =
00416 pRow[1] =
00417 pRow[2] =
00418 pRow[3] = *src++ * scale;
00419 }
00420 p += dst_stride;
00421 }
00422 }
00423
00424
00425
00426
00427
00428
00429 static void
00430 l8_get_tile_rgba(const ubyte *src,
00431 unsigned w, unsigned h,
00432 float *p,
00433 unsigned dst_stride)
00434 {
00435 unsigned i, j;
00436
00437 for (i = 0; i < h; i++) {
00438 float *pRow = p;
00439 for (j = 0; j < w; j++, src++, pRow += 4) {
00440 pRow[0] =
00441 pRow[1] =
00442 pRow[2] = ubyte_to_float(*src);
00443 pRow[3] = 1.0;
00444 }
00445 p += dst_stride;
00446 }
00447 }
00448
00449
00450 static void
00451 l8_put_tile_rgba(ubyte *dst,
00452 unsigned w, unsigned h,
00453 const float *p,
00454 unsigned src_stride)
00455 {
00456 unsigned i, j;
00457
00458 for (i = 0; i < h; i++) {
00459 const float *pRow = p;
00460 for (j = 0; j < w; j++, pRow += 4) {
00461 unsigned r;
00462 r = float_to_ubyte(pRow[0]);
00463 *dst++ = r;
00464 }
00465 p += src_stride;
00466 }
00467 }
00468
00469
00470
00471
00472
00473 static void
00474 a8_get_tile_rgba(const ubyte *src,
00475 unsigned w, unsigned h,
00476 float *p,
00477 unsigned dst_stride)
00478 {
00479 unsigned i, j;
00480
00481 for (i = 0; i < h; i++) {
00482 float *pRow = p;
00483 for (j = 0; j < w; j++, src++, pRow += 4) {
00484 pRow[0] =
00485 pRow[1] =
00486 pRow[2] = 0.0;
00487 pRow[3] = ubyte_to_float(*src);
00488 }
00489 p += dst_stride;
00490 }
00491 }
00492
00493
00494 static void
00495 a8_put_tile_rgba(ubyte *dst,
00496 unsigned w, unsigned h,
00497 const float *p,
00498 unsigned src_stride)
00499 {
00500 unsigned i, j;
00501
00502 for (i = 0; i < h; i++) {
00503 const float *pRow = p;
00504 for (j = 0; j < w; j++, pRow += 4) {
00505 unsigned a;
00506 a = float_to_ubyte(pRow[3]);
00507 *dst++ = a;
00508 }
00509 p += src_stride;
00510 }
00511 }
00512
00513
00514
00515
00516
00517 static void
00518 r16_get_tile_rgba(const short *src,
00519 unsigned w, unsigned h,
00520 float *p,
00521 unsigned dst_stride)
00522 {
00523 unsigned i, j;
00524
00525 for (i = 0; i < h; i++) {
00526 float *pRow = p;
00527 for (j = 0; j < w; j++, src++, pRow += 4) {
00528 pRow[0] = SHORT_TO_FLOAT(src[0]);
00529 pRow[1] =
00530 pRow[2] = 0.0;
00531 pRow[3] = 1.0;
00532 }
00533 p += dst_stride;
00534 }
00535 }
00536
00537
00538 static void
00539 r16_put_tile_rgba(short *dst,
00540 unsigned w, unsigned h,
00541 const float *p,
00542 unsigned src_stride)
00543 {
00544 unsigned i, j;
00545
00546 for (i = 0; i < h; i++) {
00547 const float *pRow = p;
00548 for (j = 0; j < w; j++, dst++, pRow += 4) {
00549 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
00550 }
00551 p += src_stride;
00552 }
00553 }
00554
00555
00556
00557
00558 static void
00559 r16g16b16a16_get_tile_rgba(const short *src,
00560 unsigned w, unsigned h,
00561 float *p,
00562 unsigned dst_stride)
00563 {
00564 unsigned i, j;
00565
00566 for (i = 0; i < h; i++) {
00567 float *pRow = p;
00568 for (j = 0; j < w; j++, src += 4, pRow += 4) {
00569 pRow[0] = SHORT_TO_FLOAT(src[0]);
00570 pRow[1] = SHORT_TO_FLOAT(src[1]);
00571 pRow[2] = SHORT_TO_FLOAT(src[2]);
00572 pRow[3] = SHORT_TO_FLOAT(src[3]);
00573 }
00574 p += dst_stride;
00575 }
00576 }
00577
00578
00579 static void
00580 r16g16b16a16_put_tile_rgba(short *dst,
00581 unsigned w, unsigned h,
00582 const float *p,
00583 unsigned src_stride)
00584 {
00585 unsigned i, j;
00586
00587 for (i = 0; i < h; i++) {
00588 const float *pRow = p;
00589 for (j = 0; j < w; j++, dst += 4, pRow += 4) {
00590 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
00591 UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
00592 UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
00593 UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
00594 }
00595 p += src_stride;
00596 }
00597 }
00598
00599
00600
00601
00602
00603 static void
00604 i8_get_tile_rgba(const ubyte *src,
00605 unsigned w, unsigned h,
00606 float *p,
00607 unsigned dst_stride)
00608 {
00609 unsigned i, j;
00610
00611 for (i = 0; i < h; i++) {
00612 float *pRow = p;
00613 for (j = 0; j < w; j++, src++, pRow += 4) {
00614 pRow[0] =
00615 pRow[1] =
00616 pRow[2] =
00617 pRow[3] = ubyte_to_float(*src);
00618 }
00619 p += dst_stride;
00620 }
00621 }
00622
00623
00624 static void
00625 i8_put_tile_rgba(ubyte *dst,
00626 unsigned w, unsigned h,
00627 const float *p,
00628 unsigned src_stride)
00629 {
00630 unsigned i, j;
00631
00632 for (i = 0; i < h; i++) {
00633 const float *pRow = p;
00634 for (j = 0; j < w; j++, pRow += 4) {
00635 unsigned r;
00636 r = float_to_ubyte(pRow[0]);
00637 *dst++ = r;
00638 }
00639 p += src_stride;
00640 }
00641 }
00642
00643
00644
00645
00646 static void
00647 a8l8_get_tile_rgba(const ushort *src,
00648 unsigned w, unsigned h,
00649 float *p,
00650 unsigned dst_stride)
00651 {
00652 unsigned i, j;
00653
00654 for (i = 0; i < h; i++) {
00655 float *pRow = p;
00656 for (j = 0; j < w; j++, pRow += 4) {
00657 ushort p = *src++;
00658 pRow[0] =
00659 pRow[1] =
00660 pRow[2] = ubyte_to_float(p & 0xff);
00661 pRow[3] = ubyte_to_float(p >> 8);
00662 }
00663 p += dst_stride;
00664 }
00665 }
00666
00667
00668 static void
00669 a8l8_put_tile_rgba(ushort *dst,
00670 unsigned w, unsigned h,
00671 const float *p,
00672 unsigned src_stride)
00673 {
00674 unsigned i, j;
00675
00676 for (i = 0; i < h; i++) {
00677 const float *pRow = p;
00678 for (j = 0; j < w; j++, pRow += 4) {
00679 unsigned r, a;
00680 r = float_to_ubyte(pRow[0]);
00681 a = float_to_ubyte(pRow[3]);
00682 *dst++ = (a << 8) | r;
00683 }
00684 p += src_stride;
00685 }
00686 }
00687
00688
00689
00690
00691
00692
00696 static void
00697 z32_get_tile_rgba(const unsigned *src,
00698 unsigned w, unsigned h,
00699 float *p,
00700 unsigned dst_stride)
00701 {
00702 const double scale = 1.0 / (double) 0xffffffff;
00703 unsigned i, j;
00704
00705 for (i = 0; i < h; i++) {
00706 float *pRow = p;
00707 for (j = 0; j < w; j++, pRow += 4) {
00708 pRow[0] =
00709 pRow[1] =
00710 pRow[2] =
00711 pRow[3] = (float) (*src++ * scale);
00712 }
00713 p += dst_stride;
00714 }
00715 }
00716
00717
00718
00719
00723 static void
00724 s8z24_get_tile_rgba(const unsigned *src,
00725 unsigned w, unsigned h,
00726 float *p,
00727 unsigned dst_stride)
00728 {
00729 const double scale = 1.0 / ((1 << 24) - 1);
00730 unsigned i, j;
00731
00732 for (i = 0; i < h; i++) {
00733 float *pRow = p;
00734 for (j = 0; j < w; j++, pRow += 4) {
00735 pRow[0] =
00736 pRow[1] =
00737 pRow[2] =
00738 pRow[3] = (float) (scale * (*src++ & 0xffffff));
00739 }
00740 p += dst_stride;
00741 }
00742 }
00743
00744
00745
00746
00750 static void
00751 z24s8_get_tile_rgba(const unsigned *src,
00752 unsigned w, unsigned h,
00753 float *p,
00754 unsigned dst_stride)
00755 {
00756 const double scale = 1.0 / ((1 << 24) - 1);
00757 unsigned i, j;
00758
00759 for (i = 0; i < h; i++) {
00760 float *pRow = p;
00761 for (j = 0; j < w; j++, pRow += 4) {
00762 pRow[0] =
00763 pRow[1] =
00764 pRow[2] =
00765 pRow[3] = (float) (scale * (*src++ >> 8));
00766 }
00767 p += dst_stride;
00768 }
00769 }
00770
00771
00772
00773
00777 static void
00778 z32f_get_tile_rgba(const float *src,
00779 unsigned w, unsigned h,
00780 float *p,
00781 unsigned dst_stride)
00782 {
00783 unsigned i, j;
00784
00785 for (i = 0; i < h; i++) {
00786 float *pRow = p;
00787 for (j = 0; j < w; j++, pRow += 4) {
00788 pRow[0] =
00789 pRow[1] =
00790 pRow[2] =
00791 pRow[3] = *src++;
00792 }
00793 p += dst_stride;
00794 }
00795 }
00796
00797
00798
00799
00803 static void
00804 ycbcr_get_tile_rgba(const ushort *src,
00805 unsigned w, unsigned h,
00806 float *p,
00807 unsigned dst_stride,
00808 boolean rev)
00809 {
00810 const float scale = 1.0f / 255.0f;
00811 unsigned i, j;
00812
00813 for (i = 0; i < h; i++) {
00814 float *pRow = p;
00815
00816 for (j = 0; j < (w & ~1); j += 2, src += 2) {
00817 const ushort t0 = src[0];
00818 const ushort t1 = src[1];
00819 const ubyte y0 = (t0 >> 8) & 0xff;
00820 const ubyte y1 = (t1 >> 8) & 0xff;
00821 ubyte cb, cr;
00822 float r, g, b;
00823
00824 if (rev) {
00825 cb = t1 & 0xff;
00826 cr = t0 & 0xff;
00827 }
00828 else {
00829 cb = t0 & 0xff;
00830 cr = t1 & 0xff;
00831 }
00832
00833
00834 r = 1.164f * (y0-16) + 1.596f * (cr-128);
00835 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
00836 b = 1.164f * (y0-16) + 2.018f * (cb-128);
00837 pRow[0] = r * scale;
00838 pRow[1] = g * scale;
00839 pRow[2] = b * scale;
00840 pRow[3] = 1.0f;
00841 pRow += 4;
00842
00843
00844 r = 1.164f * (y1-16) + 1.596f * (cr-128);
00845 g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
00846 b = 1.164f * (y1-16) + 2.018f * (cb-128);
00847 pRow[0] = r * scale;
00848 pRow[1] = g * scale;
00849 pRow[2] = b * scale;
00850 pRow[3] = 1.0f;
00851 pRow += 4;
00852
00853 }
00854
00855 if (w & 1) {
00856 const ushort t0 = src[0];
00857 const ushort t1 = src[1];
00858 const ubyte y0 = (t0 >> 8) & 0xff;
00859 ubyte cb, cr;
00860 float r, g, b;
00861
00862 if (rev) {
00863 cb = t1 & 0xff;
00864 cr = t0 & 0xff;
00865 }
00866 else {
00867 cb = t0 & 0xff;
00868 cr = t1 & 0xff;
00869 }
00870
00871
00872 r = 1.164f * (y0-16) + 1.596f * (cr-128);
00873 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
00874 b = 1.164f * (y0-16) + 2.018f * (cb-128);
00875 pRow[0] = r * scale;
00876 pRow[1] = g * scale;
00877 pRow[2] = b * scale;
00878 pRow[3] = 1.0f;
00879 pRow += 4;
00880 }
00881 p += dst_stride;
00882 }
00883 }
00884
00885
00886 static void
00887 fake_get_tile_rgba(const ushort *src,
00888 unsigned w, unsigned h,
00889 float *p,
00890 unsigned dst_stride)
00891 {
00892 unsigned i, j;
00893
00894 for (i = 0; i < h; i++) {
00895 float *pRow = p;
00896 for (j = 0; j < w; j++, pRow += 4) {
00897 pRow[0] =
00898 pRow[1] =
00899 pRow[2] =
00900 pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f;
00901 }
00902 p += dst_stride;
00903 }
00904 }
00905
00906
00907 void
00908 pipe_tile_raw_to_rgba(enum pipe_format format,
00909 void *src,
00910 uint w, uint h,
00911 float *dst, unsigned dst_stride)
00912 {
00913 switch (format) {
00914 case PIPE_FORMAT_A8R8G8B8_UNORM:
00915 a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00916 break;
00917 case PIPE_FORMAT_X8R8G8B8_UNORM:
00918 x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00919 break;
00920 case PIPE_FORMAT_B8G8R8A8_UNORM:
00921 b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00922 break;
00923 case PIPE_FORMAT_A1R5G5B5_UNORM:
00924 a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00925 break;
00926 case PIPE_FORMAT_A4R4G4B4_UNORM:
00927 a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00928 break;
00929 case PIPE_FORMAT_R5G6B5_UNORM:
00930 r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00931 break;
00932 case PIPE_FORMAT_L8_UNORM:
00933 l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
00934 break;
00935 case PIPE_FORMAT_A8_UNORM:
00936 a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
00937 break;
00938 case PIPE_FORMAT_I8_UNORM:
00939 i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
00940 break;
00941 case PIPE_FORMAT_A8L8_UNORM:
00942 a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00943 break;
00944 case PIPE_FORMAT_R16_SNORM:
00945 r16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
00946 break;
00947 case PIPE_FORMAT_R16G16B16A16_SNORM:
00948 r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
00949 break;
00950 case PIPE_FORMAT_Z16_UNORM:
00951 z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00952 break;
00953 case PIPE_FORMAT_Z32_UNORM:
00954 z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00955 break;
00956 case PIPE_FORMAT_S8Z24_UNORM:
00957 case PIPE_FORMAT_X8Z24_UNORM:
00958 s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00959 break;
00960 case PIPE_FORMAT_Z24S8_UNORM:
00961 z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00962 break;
00963 case PIPE_FORMAT_Z32_FLOAT:
00964 z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
00965 break;
00966 case PIPE_FORMAT_YCBCR:
00967 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE);
00968 break;
00969 case PIPE_FORMAT_YCBCR_REV:
00970 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
00971 break;
00972 default:
00973 debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
00974 fake_get_tile_rgba(src, w, h, dst, dst_stride);
00975 }
00976 }
00977
00978
00979 void
00980 pipe_get_tile_rgba(struct pipe_surface *ps,
00981 uint x, uint y, uint w, uint h,
00982 float *p)
00983 {
00984 unsigned dst_stride = w * 4;
00985 void *packed;
00986
00987 if (pipe_clip_tile(x, y, &w, &h, ps))
00988 return;
00989
00990 packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
00991
00992 if (!packed)
00993 return;
00994
00995 if(ps->format == PIPE_FORMAT_YCBCR || ps->format == PIPE_FORMAT_YCBCR_REV)
00996 assert((x & 1) == 0);
00997
00998 pipe_get_tile_raw(ps, x, y, w, h, packed, 0);
00999
01000 pipe_tile_raw_to_rgba(ps->format, packed, w, h, p, dst_stride);
01001
01002 FREE(packed);
01003 }
01004
01005
01006 void
01007 pipe_put_tile_rgba(struct pipe_surface *ps,
01008 uint x, uint y, uint w, uint h,
01009 const float *p)
01010 {
01011 unsigned src_stride = w * 4;
01012 void *packed;
01013
01014 if (pipe_clip_tile(x, y, &w, &h, ps))
01015 return;
01016
01017 packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
01018
01019 if (!packed)
01020 return;
01021
01022 switch (ps->format) {
01023 case PIPE_FORMAT_A8R8G8B8_UNORM:
01024 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
01025 break;
01026 case PIPE_FORMAT_X8R8G8B8_UNORM:
01027 x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
01028 break;
01029 case PIPE_FORMAT_B8G8R8A8_UNORM:
01030 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
01031 break;
01032 case PIPE_FORMAT_A1R5G5B5_UNORM:
01033 a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
01034 break;
01035 case PIPE_FORMAT_R5G6B5_UNORM:
01036 r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
01037 break;
01038 case PIPE_FORMAT_R8G8B8A8_UNORM:
01039 assert(0);
01040 break;
01041 case PIPE_FORMAT_A4R4G4B4_UNORM:
01042 a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
01043 break;
01044 case PIPE_FORMAT_L8_UNORM:
01045 l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
01046 break;
01047 case PIPE_FORMAT_A8_UNORM:
01048 a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
01049 break;
01050 case PIPE_FORMAT_I8_UNORM:
01051 i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
01052 break;
01053 case PIPE_FORMAT_A8L8_UNORM:
01054 a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
01055 break;
01056 case PIPE_FORMAT_R16_SNORM:
01057 r16_put_tile_rgba((short *) packed, w, h, p, src_stride);
01058 break;
01059 case PIPE_FORMAT_R16G16B16A16_SNORM:
01060 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
01061 break;
01062 case PIPE_FORMAT_Z16_UNORM:
01063
01064 break;
01065 case PIPE_FORMAT_Z32_UNORM:
01066
01067 break;
01068 case PIPE_FORMAT_S8Z24_UNORM:
01069 case PIPE_FORMAT_X8Z24_UNORM:
01070
01071 break;
01072 case PIPE_FORMAT_Z24S8_UNORM:
01073
01074 break;
01075 default:
01076 debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(ps->format));
01077 }
01078
01079 pipe_put_tile_raw(ps, x, y, w, h, packed, 0);
01080
01081 FREE(packed);
01082 }
01083
01084
01088 void
01089 pipe_get_tile_z(struct pipe_surface *ps,
01090 uint x, uint y, uint w, uint h,
01091 uint *z)
01092 {
01093 const uint dstStride = w;
01094 ubyte *map;
01095 uint *pDest = z;
01096 uint i, j;
01097
01098 if (pipe_clip_tile(x, y, &w, &h, ps))
01099 return;
01100
01101 map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ);
01102 if (!map) {
01103 assert(0);
01104 return;
01105 }
01106
01107 switch (ps->format) {
01108 case PIPE_FORMAT_Z32_UNORM:
01109 {
01110 const uint *pSrc
01111 = (const uint *)(map + y * ps->stride + x*4);
01112 for (i = 0; i < h; i++) {
01113 memcpy(pDest, pSrc, 4 * w);
01114 pDest += dstStride;
01115 pSrc += ps->stride/4;
01116 }
01117 }
01118 break;
01119 case PIPE_FORMAT_S8Z24_UNORM:
01120 case PIPE_FORMAT_X8Z24_UNORM:
01121 {
01122 const uint *pSrc
01123 = (const uint *)(map + y * ps->stride + x*4);
01124 for (i = 0; i < h; i++) {
01125 for (j = 0; j < w; j++) {
01126
01127 pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff);
01128 }
01129 pDest += dstStride;
01130 pSrc += ps->stride/4;
01131 }
01132 }
01133 break;
01134 case PIPE_FORMAT_Z16_UNORM:
01135 {
01136 const ushort *pSrc
01137 = (const ushort *)(map + y * ps->stride + x*2);
01138 for (i = 0; i < h; i++) {
01139 for (j = 0; j < w; j++) {
01140
01141 pDest[j] = (pSrc[j] << 16) | pSrc[j];
01142 }
01143 pDest += dstStride;
01144 pSrc += ps->stride/2;
01145 }
01146 }
01147 break;
01148 default:
01149 assert(0);
01150 }
01151
01152 pipe_surface_unmap(ps);
01153 }
01154
01155
01156 void
01157 pipe_put_tile_z(struct pipe_surface *ps,
01158 uint x, uint y, uint w, uint h,
01159 const uint *zSrc)
01160 {
01161 const uint srcStride = w;
01162 const uint *pSrc = zSrc;
01163 ubyte *map;
01164 uint i, j;
01165
01166 if (pipe_clip_tile(x, y, &w, &h, ps))
01167 return;
01168
01169 map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE);
01170 if (!map) {
01171 assert(0);
01172 return;
01173 }
01174
01175 switch (ps->format) {
01176 case PIPE_FORMAT_Z32_UNORM:
01177 {
01178 uint *pDest = (uint *) (map + y * ps->stride + x*4);
01179 for (i = 0; i < h; i++) {
01180 memcpy(pDest, pSrc, 4 * w);
01181 pDest += ps->stride/4;
01182 pSrc += srcStride;
01183 }
01184 }
01185 break;
01186 case PIPE_FORMAT_S8Z24_UNORM:
01187 case PIPE_FORMAT_X8Z24_UNORM:
01188 {
01189 uint *pDest = (uint *) (map + y * ps->stride + x*4);
01190 for (i = 0; i < h; i++) {
01191 for (j = 0; j < w; j++) {
01192
01193 pDest[j] = pSrc[j] >> 8;
01194 }
01195 pDest += ps->stride/4;
01196 pSrc += srcStride;
01197 }
01198 }
01199 break;
01200 case PIPE_FORMAT_Z16_UNORM:
01201 {
01202 ushort *pDest = (ushort *) (map + y * ps->stride + x*2);
01203 for (i = 0; i < h; i++) {
01204 for (j = 0; j < w; j++) {
01205
01206 pDest[j] = pSrc[j] >> 16;
01207 }
01208 pDest += ps->stride/2;
01209 pSrc += srcStride;
01210 }
01211 }
01212 break;
01213 default:
01214 assert(0);
01215 }
01216
01217 pipe_surface_unmap(ps);
01218 }
01219
01220