Merge branch 'mesa_7_6_branch'
[mesa.git] / src / gallium / auxiliary / util / u_tile.c
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 */
46 void
47 pipe_get_tile_raw(struct pipe_transfer *pt,
48 uint x, uint y, uint w, uint h,
49 void *dst, int dst_stride)
50 {
51 struct pipe_screen *screen = pt->texture->screen;
52 const void *src;
53
54 if (dst_stride == 0)
55 dst_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
56
57 if (pipe_clip_tile(x, y, &w, &h, pt))
58 return;
59
60 src = screen->transfer_map(screen, pt);
61 assert(src);
62 if(!src)
63 return;
64
65 util_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
66
67 screen->transfer_unmap(screen, pt);
68 }
69
70
71 /**
72 * Move raw block of pixels from user memory to transfer object.
73 */
74 void
75 pipe_put_tile_raw(struct pipe_transfer *pt,
76 uint x, uint y, uint w, uint h,
77 const void *src, int src_stride)
78 {
79 struct pipe_screen *screen = pt->texture->screen;
80 void *dst;
81
82 if (src_stride == 0)
83 src_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
84
85 if (pipe_clip_tile(x, y, &w, &h, pt))
86 return;
87
88 dst = screen->transfer_map(screen, pt);
89 assert(dst);
90 if(!dst)
91 return;
92
93 util_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
94
95 screen->transfer_unmap(screen, pt);
96 }
97
98
99
100
101 /** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
102 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
103
104 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
105 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
106
107
108
109 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
110
111 static void
112 a8r8g8b8_get_tile_rgba(const unsigned *src,
113 unsigned w, unsigned h,
114 float *p,
115 unsigned dst_stride)
116 {
117 unsigned i, j;
118
119 for (i = 0; i < h; i++) {
120 float *pRow = p;
121 for (j = 0; j < w; j++, pRow += 4) {
122 const unsigned pixel = *src++;
123 pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
124 pRow[1] = ubyte_to_float((pixel >> 8) & 0xff);
125 pRow[2] = ubyte_to_float((pixel >> 0) & 0xff);
126 pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
127 }
128 p += dst_stride;
129 }
130 }
131
132
133 static void
134 a8r8g8b8_put_tile_rgba(unsigned *dst,
135 unsigned w, unsigned h,
136 const float *p,
137 unsigned src_stride)
138 {
139 unsigned i, j;
140
141 for (i = 0; i < h; i++) {
142 const float *pRow = p;
143 for (j = 0; j < w; j++, pRow += 4) {
144 unsigned r, g, b, a;
145 r = float_to_ubyte(pRow[0]);
146 g = float_to_ubyte(pRow[1]);
147 b = float_to_ubyte(pRow[2]);
148 a = float_to_ubyte(pRow[3]);
149 *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
150 }
151 p += src_stride;
152 }
153 }
154
155
156 /*** PIPE_FORMAT_X8R8G8B8_UNORM ***/
157
158 static void
159 x8r8g8b8_get_tile_rgba(const unsigned *src,
160 unsigned w, unsigned h,
161 float *p,
162 unsigned dst_stride)
163 {
164 unsigned i, j;
165
166 for (i = 0; i < h; i++) {
167 float *pRow = p;
168 for (j = 0; j < w; j++, pRow += 4) {
169 const unsigned pixel = *src++;
170 pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
171 pRow[1] = ubyte_to_float((pixel >> 8) & 0xff);
172 pRow[2] = ubyte_to_float((pixel >> 0) & 0xff);
173 pRow[3] = 1.0F;
174 }
175 p += dst_stride;
176 }
177 }
178
179
180 static void
181 x8r8g8b8_put_tile_rgba(unsigned *dst,
182 unsigned w, unsigned h,
183 const float *p,
184 unsigned src_stride)
185 {
186 unsigned i, j;
187
188 for (i = 0; i < h; i++) {
189 const float *pRow = p;
190 for (j = 0; j < w; j++, pRow += 4) {
191 unsigned r, g, b;
192 r = float_to_ubyte(pRow[0]);
193 g = float_to_ubyte(pRow[1]);
194 b = float_to_ubyte(pRow[2]);
195 *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
196 }
197 p += src_stride;
198 }
199 }
200
201
202 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
203
204 static void
205 b8g8r8a8_get_tile_rgba(const unsigned *src,
206 unsigned w, unsigned h,
207 float *p,
208 unsigned dst_stride)
209 {
210 unsigned i, j;
211
212 for (i = 0; i < h; i++) {
213 float *pRow = p;
214 for (j = 0; j < w; j++, pRow += 4) {
215 const unsigned pixel = *src++;
216 pRow[0] = ubyte_to_float((pixel >> 8) & 0xff);
217 pRow[1] = ubyte_to_float((pixel >> 16) & 0xff);
218 pRow[2] = ubyte_to_float((pixel >> 24) & 0xff);
219 pRow[3] = ubyte_to_float((pixel >> 0) & 0xff);
220 }
221 p += dst_stride;
222 }
223 }
224
225
226 static void
227 b8g8r8a8_put_tile_rgba(unsigned *dst,
228 unsigned w, unsigned h,
229 const float *p,
230 unsigned src_stride)
231 {
232 unsigned i, j;
233
234 for (i = 0; i < h; i++) {
235 const float *pRow = p;
236 for (j = 0; j < w; j++, pRow += 4) {
237 unsigned r, g, b, a;
238 r = float_to_ubyte(pRow[0]);
239 g = float_to_ubyte(pRow[1]);
240 b = float_to_ubyte(pRow[2]);
241 a = float_to_ubyte(pRow[3]);
242 *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
243 }
244 p += src_stride;
245 }
246 }
247
248
249 /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
250
251 static void
252 a1r5g5b5_get_tile_rgba(const ushort *src,
253 unsigned w, unsigned h,
254 float *p,
255 unsigned dst_stride)
256 {
257 unsigned i, j;
258
259 for (i = 0; i < h; i++) {
260 float *pRow = p;
261 for (j = 0; j < w; j++, pRow += 4) {
262 const ushort pixel = *src++;
263 pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
264 pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
265 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
266 pRow[3] = ((pixel >> 15) ) * 1.0f;
267 }
268 p += dst_stride;
269 }
270 }
271
272
273 static void
274 a1r5g5b5_put_tile_rgba(ushort *dst,
275 unsigned w, unsigned h,
276 const float *p,
277 unsigned src_stride)
278 {
279 unsigned i, j;
280
281 for (i = 0; i < h; i++) {
282 const float *pRow = p;
283 for (j = 0; j < w; j++, pRow += 4) {
284 unsigned r, g, b, a;
285 r = float_to_ubyte(pRow[0]);
286 g = float_to_ubyte(pRow[1]);
287 b = float_to_ubyte(pRow[2]);
288 a = float_to_ubyte(pRow[3]);
289 r = r >> 3; /* 5 bits */
290 g = g >> 3; /* 5 bits */
291 b = b >> 3; /* 5 bits */
292 a = a >> 7; /* 1 bit */
293 *dst++ = (a << 15) | (r << 10) | (g << 5) | b;
294 }
295 p += src_stride;
296 }
297 }
298
299
300 /*** PIPE_FORMAT_A4R4G4B4_UNORM ***/
301
302 static void
303 a4r4g4b4_get_tile_rgba(const ushort *src,
304 unsigned w, unsigned h,
305 float *p,
306 unsigned dst_stride)
307 {
308 unsigned i, j;
309
310 for (i = 0; i < h; i++) {
311 float *pRow = p;
312 for (j = 0; j < w; j++, pRow += 4) {
313 const ushort pixel = *src++;
314 pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f);
315 pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f);
316 pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f);
317 pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f);
318 }
319 p += dst_stride;
320 }
321 }
322
323
324 static void
325 a4r4g4b4_put_tile_rgba(ushort *dst,
326 unsigned w, unsigned h,
327 const float *p,
328 unsigned src_stride)
329 {
330 unsigned i, j;
331
332 for (i = 0; i < h; i++) {
333 const float *pRow = p;
334 for (j = 0; j < w; j++, pRow += 4) {
335 unsigned r, g, b, a;
336 r = float_to_ubyte(pRow[0]);
337 g = float_to_ubyte(pRow[1]);
338 b = float_to_ubyte(pRow[2]);
339 a = float_to_ubyte(pRow[3]);
340 r >>= 4;
341 g >>= 4;
342 b >>= 4;
343 a >>= 4;
344 *dst++ = (a << 12) | (r << 16) | (g << 4) | b;
345 }
346 p += src_stride;
347 }
348 }
349
350
351 /*** PIPE_FORMAT_R5G6B5_UNORM ***/
352
353 static void
354 r5g6b5_get_tile_rgba(const ushort *src,
355 unsigned w, unsigned h,
356 float *p,
357 unsigned dst_stride)
358 {
359 unsigned i, j;
360
361 for (i = 0; i < h; i++) {
362 float *pRow = p;
363 for (j = 0; j < w; j++, pRow += 4) {
364 const ushort pixel = *src++;
365 pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f);
366 pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f);
367 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
368 pRow[3] = 1.0f;
369 }
370 p += dst_stride;
371 }
372 }
373
374
375 static void
376 r5g6b5_put_tile_rgba(ushort *dst,
377 unsigned w, unsigned h,
378 const float *p,
379 unsigned src_stride)
380 {
381 unsigned i, j;
382
383 for (i = 0; i < h; i++) {
384 const float *pRow = p;
385 for (j = 0; j < w; j++, pRow += 4) {
386 uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0);
387 uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0);
388 uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0);
389 *dst++ = (r << 11) | (g << 5) | (b);
390 }
391 p += src_stride;
392 }
393 }
394
395
396
397 /*** PIPE_FORMAT_R8G8B8_UNORM ***/
398
399 static void
400 r8g8b8_get_tile_rgba(const ubyte *src,
401 unsigned w, unsigned h,
402 float *p,
403 unsigned dst_stride)
404 {
405 unsigned i, j;
406
407 for (i = 0; i < h; i++) {
408 float *pRow = p;
409 for (j = 0; j < w; j++, pRow += 4) {
410 pRow[0] = ubyte_to_float(src[0]);
411 pRow[1] = ubyte_to_float(src[1]);
412 pRow[2] = ubyte_to_float(src[2]);
413 pRow[3] = 1.0f;
414 src += 3;
415 }
416 p += dst_stride;
417 }
418 }
419
420
421 static void
422 r8g8b8_put_tile_rgba(ubyte *dst,
423 unsigned w, unsigned h,
424 const float *p,
425 unsigned src_stride)
426 {
427 unsigned i, j;
428
429 for (i = 0; i < h; i++) {
430 const float *pRow = p;
431 for (j = 0; j < w; j++, pRow += 4) {
432 dst[0] = float_to_ubyte(pRow[0]);
433 dst[1] = float_to_ubyte(pRow[1]);
434 dst[2] = float_to_ubyte(pRow[2]);
435 dst += 3;
436 }
437 p += src_stride;
438 }
439 }
440
441
442
443 /*** PIPE_FORMAT_Z16_UNORM ***/
444
445 /**
446 * Return each Z value as four floats in [0,1].
447 */
448 static void
449 z16_get_tile_rgba(const ushort *src,
450 unsigned w, unsigned h,
451 float *p,
452 unsigned dst_stride)
453 {
454 const float scale = 1.0f / 65535.0f;
455 unsigned i, j;
456
457 for (i = 0; i < h; i++) {
458 float *pRow = p;
459 for (j = 0; j < w; j++, pRow += 4) {
460 pRow[0] =
461 pRow[1] =
462 pRow[2] =
463 pRow[3] = *src++ * scale;
464 }
465 p += dst_stride;
466 }
467 }
468
469
470
471
472 /*** PIPE_FORMAT_L8_UNORM ***/
473
474 static void
475 l8_get_tile_rgba(const ubyte *src,
476 unsigned w, unsigned h,
477 float *p,
478 unsigned dst_stride)
479 {
480 unsigned i, j;
481
482 for (i = 0; i < h; i++) {
483 float *pRow = p;
484 for (j = 0; j < w; j++, src++, pRow += 4) {
485 pRow[0] =
486 pRow[1] =
487 pRow[2] = ubyte_to_float(*src);
488 pRow[3] = 1.0;
489 }
490 p += dst_stride;
491 }
492 }
493
494
495 static void
496 l8_put_tile_rgba(ubyte *dst,
497 unsigned w, unsigned h,
498 const float *p,
499 unsigned src_stride)
500 {
501 unsigned i, j;
502
503 for (i = 0; i < h; i++) {
504 const float *pRow = p;
505 for (j = 0; j < w; j++, pRow += 4) {
506 unsigned r;
507 r = float_to_ubyte(pRow[0]);
508 *dst++ = (ubyte) r;
509 }
510 p += src_stride;
511 }
512 }
513
514
515
516 /*** PIPE_FORMAT_A8_UNORM ***/
517
518 static void
519 a8_get_tile_rgba(const ubyte *src,
520 unsigned w, unsigned h,
521 float *p,
522 unsigned dst_stride)
523 {
524 unsigned i, j;
525
526 for (i = 0; i < h; i++) {
527 float *pRow = p;
528 for (j = 0; j < w; j++, src++, pRow += 4) {
529 pRow[0] =
530 pRow[1] =
531 pRow[2] = 0.0;
532 pRow[3] = ubyte_to_float(*src);
533 }
534 p += dst_stride;
535 }
536 }
537
538
539 static void
540 a8_put_tile_rgba(ubyte *dst,
541 unsigned w, unsigned h,
542 const float *p,
543 unsigned src_stride)
544 {
545 unsigned i, j;
546
547 for (i = 0; i < h; i++) {
548 const float *pRow = p;
549 for (j = 0; j < w; j++, pRow += 4) {
550 unsigned a;
551 a = float_to_ubyte(pRow[3]);
552 *dst++ = (ubyte) a;
553 }
554 p += src_stride;
555 }
556 }
557
558
559
560 /*** PIPE_FORMAT_R16_SNORM ***/
561
562 static void
563 r16_get_tile_rgba(const short *src,
564 unsigned w, unsigned h,
565 float *p,
566 unsigned dst_stride)
567 {
568 unsigned i, j;
569
570 for (i = 0; i < h; i++) {
571 float *pRow = p;
572 for (j = 0; j < w; j++, src++, pRow += 4) {
573 pRow[0] = SHORT_TO_FLOAT(src[0]);
574 pRow[1] =
575 pRow[2] = 0.0;
576 pRow[3] = 1.0;
577 }
578 p += dst_stride;
579 }
580 }
581
582
583 static void
584 r16_put_tile_rgba(short *dst,
585 unsigned w, unsigned h,
586 const float *p,
587 unsigned src_stride)
588 {
589 unsigned i, j;
590
591 for (i = 0; i < h; i++) {
592 const float *pRow = p;
593 for (j = 0; j < w; j++, dst++, pRow += 4) {
594 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
595 }
596 p += src_stride;
597 }
598 }
599
600
601 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
602
603 static void
604 r16g16b16a16_get_tile_rgba(const short *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 += 4, pRow += 4) {
614 pRow[0] = SHORT_TO_FLOAT(src[0]);
615 pRow[1] = SHORT_TO_FLOAT(src[1]);
616 pRow[2] = SHORT_TO_FLOAT(src[2]);
617 pRow[3] = SHORT_TO_FLOAT(src[3]);
618 }
619 p += dst_stride;
620 }
621 }
622
623
624 static void
625 r16g16b16a16_put_tile_rgba(short *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++, dst += 4, pRow += 4) {
635 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
636 UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
637 UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
638 UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
639 }
640 p += src_stride;
641 }
642 }
643
644
645 /*** PIPE_FORMAT_R8G8B8A8_SRGB ***/
646
647 /**
648 * Convert an 8-bit sRGB value from non-linear space to a
649 * linear RGB value in [0, 1].
650 * Implemented with a 256-entry lookup table.
651 */
652 static INLINE float
653 srgb_to_linear(ubyte cs8)
654 {
655 static float table[256];
656 static boolean tableReady = FALSE;
657 if (!tableReady) {
658 /* compute lookup table now */
659 uint i;
660 for (i = 0; i < 256; i++) {
661 const float cs = ubyte_to_float(i);
662 if (cs <= 0.04045) {
663 table[i] = cs / 12.92f;
664 }
665 else {
666 table[i] = (float) powf((cs + 0.055) / 1.055, 2.4);
667 }
668 }
669 tableReady = TRUE;
670 }
671 return table[cs8];
672 }
673
674
675 /**
676 * Convert linear float in [0,1] to an srgb ubyte value in [0,255].
677 * XXX this hasn't been tested (render to srgb surface).
678 * XXX this needs optimization.
679 */
680 static INLINE ubyte
681 linear_to_srgb(float cl)
682 {
683 if (cl >= 1.0F)
684 return 255;
685 else if (cl >= 0.0031308F)
686 return float_to_ubyte(1.055F * powf(cl, 0.41666F) - 0.055F);
687 else if (cl > 0.0F)
688 return float_to_ubyte(12.92F * cl);
689 else
690 return 0.0;
691 }
692
693
694 static void
695 a8r8g8b8_srgb_get_tile_rgba(const unsigned *src,
696 unsigned w, unsigned h,
697 float *p,
698 unsigned dst_stride)
699 {
700 unsigned i, j;
701
702 for (i = 0; i < h; i++) {
703 float *pRow = p;
704 for (j = 0; j < w; j++, pRow += 4) {
705 const unsigned pixel = *src++;
706 pRow[0] = srgb_to_linear((pixel >> 16) & 0xff);
707 pRow[1] = srgb_to_linear((pixel >> 8) & 0xff);
708 pRow[2] = srgb_to_linear((pixel >> 0) & 0xff);
709 pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
710 }
711 p += dst_stride;
712 }
713 }
714
715 static void
716 a8r8g8b8_srgb_put_tile_rgba(unsigned *dst,
717 unsigned w, unsigned h,
718 const float *p,
719 unsigned src_stride)
720 {
721 unsigned i, j;
722
723 for (i = 0; i < h; i++) {
724 const float *pRow = p;
725 for (j = 0; j < w; j++, pRow += 4) {
726 unsigned r, g, b, a;
727 r = linear_to_srgb(pRow[0]);
728 g = linear_to_srgb(pRow[1]);
729 b = linear_to_srgb(pRow[2]);
730 a = float_to_ubyte(pRow[3]);
731 *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
732 }
733 p += src_stride;
734 }
735 }
736
737
738 /*** PIPE_FORMAT_A8L8_SRGB ***/
739
740 static void
741 a8l8_srgb_get_tile_rgba(const ushort *src,
742 unsigned w, unsigned h,
743 float *p,
744 unsigned dst_stride)
745 {
746 unsigned i, j;
747
748 for (i = 0; i < h; i++) {
749 float *pRow = p;
750 for (j = 0; j < w; j++, pRow += 4) {
751 ushort p = *src++;
752 pRow[0] =
753 pRow[1] =
754 pRow[2] = srgb_to_linear(p & 0xff);
755 pRow[3] = ubyte_to_float(p >> 8);
756 }
757 p += dst_stride;
758 }
759 }
760
761 static void
762 a8l8_srgb_put_tile_rgba(ushort *dst,
763 unsigned w, unsigned h,
764 const float *p,
765 unsigned src_stride)
766 {
767 unsigned i, j;
768
769 for (i = 0; i < h; i++) {
770 const float *pRow = p;
771 for (j = 0; j < w; j++, pRow += 4) {
772 unsigned r, a;
773 r = linear_to_srgb(pRow[0]);
774 a = float_to_ubyte(pRow[3]);
775 *dst++ = (a << 8) | r;
776 }
777 p += src_stride;
778 }
779 }
780
781
782 /*** PIPE_FORMAT_L8_SRGB ***/
783
784 static void
785 l8_srgb_get_tile_rgba(const ubyte *src,
786 unsigned w, unsigned h,
787 float *p,
788 unsigned dst_stride)
789 {
790 unsigned i, j;
791
792 for (i = 0; i < h; i++) {
793 float *pRow = p;
794 for (j = 0; j < w; j++, src++, pRow += 4) {
795 pRow[0] =
796 pRow[1] =
797 pRow[2] = srgb_to_linear(*src);
798 pRow[3] = 1.0;
799 }
800 p += dst_stride;
801 }
802 }
803
804 static void
805 l8_srgb_put_tile_rgba(ubyte *dst,
806 unsigned w, unsigned h,
807 const float *p,
808 unsigned src_stride)
809 {
810 unsigned i, j;
811
812 for (i = 0; i < h; i++) {
813 const float *pRow = p;
814 for (j = 0; j < w; j++, pRow += 4) {
815 unsigned r;
816 r = linear_to_srgb(pRow[0]);
817 *dst++ = (ubyte) r;
818 }
819 p += src_stride;
820 }
821 }
822
823
824 /*** PIPE_FORMAT_I8_UNORM ***/
825
826 static void
827 i8_get_tile_rgba(const ubyte *src,
828 unsigned w, unsigned h,
829 float *p,
830 unsigned dst_stride)
831 {
832 unsigned i, j;
833
834 for (i = 0; i < h; i++) {
835 float *pRow = p;
836 for (j = 0; j < w; j++, src++, pRow += 4) {
837 pRow[0] =
838 pRow[1] =
839 pRow[2] =
840 pRow[3] = ubyte_to_float(*src);
841 }
842 p += dst_stride;
843 }
844 }
845
846
847 static void
848 i8_put_tile_rgba(ubyte *dst,
849 unsigned w, unsigned h,
850 const float *p,
851 unsigned src_stride)
852 {
853 unsigned i, j;
854
855 for (i = 0; i < h; i++) {
856 const float *pRow = p;
857 for (j = 0; j < w; j++, pRow += 4) {
858 unsigned r;
859 r = float_to_ubyte(pRow[0]);
860 *dst++ = (ubyte) r;
861 }
862 p += src_stride;
863 }
864 }
865
866
867 /*** PIPE_FORMAT_A8L8_UNORM ***/
868
869 static void
870 a8l8_get_tile_rgba(const ushort *src,
871 unsigned w, unsigned h,
872 float *p,
873 unsigned dst_stride)
874 {
875 unsigned i, j;
876
877 for (i = 0; i < h; i++) {
878 float *pRow = p;
879 for (j = 0; j < w; j++, pRow += 4) {
880 ushort p = *src++;
881 pRow[0] =
882 pRow[1] =
883 pRow[2] = ubyte_to_float(p & 0xff);
884 pRow[3] = ubyte_to_float(p >> 8);
885 }
886 p += dst_stride;
887 }
888 }
889
890
891 static void
892 a8l8_put_tile_rgba(ushort *dst,
893 unsigned w, unsigned h,
894 const float *p,
895 unsigned src_stride)
896 {
897 unsigned i, j;
898
899 for (i = 0; i < h; i++) {
900 const float *pRow = p;
901 for (j = 0; j < w; j++, pRow += 4) {
902 unsigned r, a;
903 r = float_to_ubyte(pRow[0]);
904 a = float_to_ubyte(pRow[3]);
905 *dst++ = (a << 8) | r;
906 }
907 p += src_stride;
908 }
909 }
910
911
912
913
914 /*** PIPE_FORMAT_Z32_UNORM ***/
915
916 /**
917 * Return each Z value as four floats in [0,1].
918 */
919 static void
920 z32_get_tile_rgba(const unsigned *src,
921 unsigned w, unsigned h,
922 float *p,
923 unsigned dst_stride)
924 {
925 const double scale = 1.0 / (double) 0xffffffff;
926 unsigned i, j;
927
928 for (i = 0; i < h; i++) {
929 float *pRow = p;
930 for (j = 0; j < w; j++, pRow += 4) {
931 pRow[0] =
932 pRow[1] =
933 pRow[2] =
934 pRow[3] = (float) (*src++ * scale);
935 }
936 p += dst_stride;
937 }
938 }
939
940
941 /*** PIPE_FORMAT_S8Z24_UNORM ***/
942
943 /**
944 * Return Z component as four float in [0,1]. Stencil part ignored.
945 */
946 static void
947 s8z24_get_tile_rgba(const unsigned *src,
948 unsigned w, unsigned h,
949 float *p,
950 unsigned dst_stride)
951 {
952 const double scale = 1.0 / ((1 << 24) - 1);
953 unsigned i, j;
954
955 for (i = 0; i < h; i++) {
956 float *pRow = p;
957 for (j = 0; j < w; j++, pRow += 4) {
958 pRow[0] =
959 pRow[1] =
960 pRow[2] =
961 pRow[3] = (float) (scale * (*src++ & 0xffffff));
962 }
963 p += dst_stride;
964 }
965 }
966
967
968 /*** PIPE_FORMAT_Z24S8_UNORM ***/
969
970 /**
971 * Return Z component as four float in [0,1]. Stencil part ignored.
972 */
973 static void
974 z24s8_get_tile_rgba(const unsigned *src,
975 unsigned w, unsigned h,
976 float *p,
977 unsigned dst_stride)
978 {
979 const double scale = 1.0 / ((1 << 24) - 1);
980 unsigned i, j;
981
982 for (i = 0; i < h; i++) {
983 float *pRow = p;
984 for (j = 0; j < w; j++, pRow += 4) {
985 pRow[0] =
986 pRow[1] =
987 pRow[2] =
988 pRow[3] = (float) (scale * (*src++ >> 8));
989 }
990 p += dst_stride;
991 }
992 }
993
994
995 /*** PIPE_FORMAT_Z32_FLOAT ***/
996
997 /**
998 * Return each Z value as four floats in [0,1].
999 */
1000 static void
1001 z32f_get_tile_rgba(const float *src,
1002 unsigned w, unsigned h,
1003 float *p,
1004 unsigned dst_stride)
1005 {
1006 unsigned i, j;
1007
1008 for (i = 0; i < h; i++) {
1009 float *pRow = p;
1010 for (j = 0; j < w; j++, pRow += 4) {
1011 pRow[0] =
1012 pRow[1] =
1013 pRow[2] =
1014 pRow[3] = *src++;
1015 }
1016 p += dst_stride;
1017 }
1018 }
1019
1020
1021 /*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
1022
1023 /**
1024 * Convert YCbCr (or YCrCb) to RGBA.
1025 */
1026 static void
1027 ycbcr_get_tile_rgba(const ushort *src,
1028 unsigned w, unsigned h,
1029 float *p,
1030 unsigned dst_stride,
1031 boolean rev)
1032 {
1033 const float scale = 1.0f / 255.0f;
1034 unsigned i, j;
1035
1036 for (i = 0; i < h; i++) {
1037 float *pRow = p;
1038 /* do two texels at a time */
1039 for (j = 0; j < (w & ~1); j += 2, src += 2) {
1040 const ushort t0 = src[0];
1041 const ushort t1 = src[1];
1042 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
1043 const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */
1044 ubyte cb, cr;
1045 float r, g, b;
1046
1047 if (rev) {
1048 cb = t1 & 0xff; /* chroma U */
1049 cr = t0 & 0xff; /* chroma V */
1050 }
1051 else {
1052 cb = t0 & 0xff; /* chroma U */
1053 cr = t1 & 0xff; /* chroma V */
1054 }
1055
1056 /* even pixel: y0,cr,cb */
1057 r = 1.164f * (y0-16) + 1.596f * (cr-128);
1058 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1059 b = 1.164f * (y0-16) + 2.018f * (cb-128);
1060 pRow[0] = r * scale;
1061 pRow[1] = g * scale;
1062 pRow[2] = b * scale;
1063 pRow[3] = 1.0f;
1064 pRow += 4;
1065
1066 /* odd pixel: use y1,cr,cb */
1067 r = 1.164f * (y1-16) + 1.596f * (cr-128);
1068 g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1069 b = 1.164f * (y1-16) + 2.018f * (cb-128);
1070 pRow[0] = r * scale;
1071 pRow[1] = g * scale;
1072 pRow[2] = b * scale;
1073 pRow[3] = 1.0f;
1074 pRow += 4;
1075
1076 }
1077 /* do the last texel */
1078 if (w & 1) {
1079 const ushort t0 = src[0];
1080 const ushort t1 = src[1];
1081 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
1082 ubyte cb, cr;
1083 float r, g, b;
1084
1085 if (rev) {
1086 cb = t1 & 0xff; /* chroma U */
1087 cr = t0 & 0xff; /* chroma V */
1088 }
1089 else {
1090 cb = t0 & 0xff; /* chroma U */
1091 cr = t1 & 0xff; /* chroma V */
1092 }
1093
1094 /* even pixel: y0,cr,cb */
1095 r = 1.164f * (y0-16) + 1.596f * (cr-128);
1096 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1097 b = 1.164f * (y0-16) + 2.018f * (cb-128);
1098 pRow[0] = r * scale;
1099 pRow[1] = g * scale;
1100 pRow[2] = b * scale;
1101 pRow[3] = 1.0f;
1102 pRow += 4;
1103 }
1104 p += dst_stride;
1105 }
1106 }
1107
1108
1109 static void
1110 fake_get_tile_rgba(const ushort *src,
1111 unsigned w, unsigned h,
1112 float *p,
1113 unsigned dst_stride)
1114 {
1115 unsigned i, j;
1116
1117 for (i = 0; i < h; i++) {
1118 float *pRow = p;
1119 for (j = 0; j < w; j++, pRow += 4) {
1120 pRow[0] =
1121 pRow[1] =
1122 pRow[2] =
1123 pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f;
1124 }
1125 p += dst_stride;
1126 }
1127 }
1128
1129
1130 void
1131 pipe_tile_raw_to_rgba(enum pipe_format format,
1132 void *src,
1133 uint w, uint h,
1134 float *dst, unsigned dst_stride)
1135 {
1136 switch (format) {
1137 case PIPE_FORMAT_A8R8G8B8_UNORM:
1138 a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1139 break;
1140 case PIPE_FORMAT_X8R8G8B8_UNORM:
1141 x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1142 break;
1143 case PIPE_FORMAT_B8G8R8A8_UNORM:
1144 b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1145 break;
1146 case PIPE_FORMAT_A1R5G5B5_UNORM:
1147 a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1148 break;
1149 case PIPE_FORMAT_A4R4G4B4_UNORM:
1150 a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1151 break;
1152 case PIPE_FORMAT_R5G6B5_UNORM:
1153 r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1154 break;
1155 case PIPE_FORMAT_R8G8B8_UNORM:
1156 r8g8b8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1157 break;
1158 case PIPE_FORMAT_L8_UNORM:
1159 l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1160 break;
1161 case PIPE_FORMAT_A8_UNORM:
1162 a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1163 break;
1164 case PIPE_FORMAT_I8_UNORM:
1165 i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1166 break;
1167 case PIPE_FORMAT_A8L8_UNORM:
1168 a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1169 break;
1170 case PIPE_FORMAT_R16_SNORM:
1171 r16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
1172 break;
1173 case PIPE_FORMAT_R16G16B16A16_SNORM:
1174 r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
1175 break;
1176 case PIPE_FORMAT_A8R8G8B8_SRGB:
1177 a8r8g8b8_srgb_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1178 break;
1179 case PIPE_FORMAT_A8L8_SRGB:
1180 a8l8_srgb_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1181 break;
1182 case PIPE_FORMAT_L8_SRGB:
1183 l8_srgb_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1184 break;
1185 case PIPE_FORMAT_Z16_UNORM:
1186 z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1187 break;
1188 case PIPE_FORMAT_Z32_UNORM:
1189 z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1190 break;
1191 case PIPE_FORMAT_S8Z24_UNORM:
1192 case PIPE_FORMAT_X8Z24_UNORM:
1193 s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1194 break;
1195 case PIPE_FORMAT_Z24S8_UNORM:
1196 case PIPE_FORMAT_Z24X8_UNORM:
1197 z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1198 break;
1199 case PIPE_FORMAT_Z32_FLOAT:
1200 z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
1201 break;
1202 case PIPE_FORMAT_YCBCR:
1203 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE);
1204 break;
1205 case PIPE_FORMAT_YCBCR_REV:
1206 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
1207 break;
1208 default:
1209 debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
1210 fake_get_tile_rgba(src, w, h, dst, dst_stride);
1211 }
1212 }
1213
1214
1215 void
1216 pipe_get_tile_rgba(struct pipe_transfer *pt,
1217 uint x, uint y, uint w, uint h,
1218 float *p)
1219 {
1220 unsigned dst_stride = w * 4;
1221 void *packed;
1222
1223 if (pipe_clip_tile(x, y, &w, &h, pt))
1224 return;
1225
1226 packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
1227
1228 if (!packed)
1229 return;
1230
1231 if(pt->format == PIPE_FORMAT_YCBCR || pt->format == PIPE_FORMAT_YCBCR_REV)
1232 assert((x & 1) == 0);
1233
1234 pipe_get_tile_raw(pt, x, y, w, h, packed, 0);
1235
1236 pipe_tile_raw_to_rgba(pt->format, packed, w, h, p, dst_stride);
1237
1238 FREE(packed);
1239 }
1240
1241
1242 void
1243 pipe_put_tile_rgba(struct pipe_transfer *pt,
1244 uint x, uint y, uint w, uint h,
1245 const float *p)
1246 {
1247 unsigned src_stride = w * 4;
1248 void *packed;
1249
1250 if (pipe_clip_tile(x, y, &w, &h, pt))
1251 return;
1252
1253 packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
1254
1255 if (!packed)
1256 return;
1257
1258 switch (pt->format) {
1259 case PIPE_FORMAT_A8R8G8B8_UNORM:
1260 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1261 break;
1262 case PIPE_FORMAT_X8R8G8B8_UNORM:
1263 x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1264 break;
1265 case PIPE_FORMAT_B8G8R8A8_UNORM:
1266 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1267 break;
1268 case PIPE_FORMAT_A1R5G5B5_UNORM:
1269 a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1270 break;
1271 case PIPE_FORMAT_R5G6B5_UNORM:
1272 r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1273 break;
1274 case PIPE_FORMAT_R8G8B8_UNORM:
1275 r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1276 break;
1277 case PIPE_FORMAT_R8G8B8A8_UNORM:
1278 assert(0);
1279 break;
1280 case PIPE_FORMAT_A4R4G4B4_UNORM:
1281 a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1282 break;
1283 case PIPE_FORMAT_L8_UNORM:
1284 l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1285 break;
1286 case PIPE_FORMAT_A8_UNORM:
1287 a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1288 break;
1289 case PIPE_FORMAT_I8_UNORM:
1290 i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1291 break;
1292 case PIPE_FORMAT_A8L8_UNORM:
1293 a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1294 break;
1295 case PIPE_FORMAT_R16_SNORM:
1296 r16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1297 break;
1298 case PIPE_FORMAT_R16G16B16A16_SNORM:
1299 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1300 break;
1301 case PIPE_FORMAT_A8R8G8B8_SRGB:
1302 a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1303 break;
1304 case PIPE_FORMAT_A8L8_SRGB:
1305 a8l8_srgb_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1306 break;
1307 case PIPE_FORMAT_L8_SRGB:
1308 l8_srgb_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1309 break;
1310 case PIPE_FORMAT_Z16_UNORM:
1311 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
1312 break;
1313 case PIPE_FORMAT_Z32_UNORM:
1314 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1315 break;
1316 case PIPE_FORMAT_S8Z24_UNORM:
1317 case PIPE_FORMAT_X8Z24_UNORM:
1318 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1319 break;
1320 case PIPE_FORMAT_Z24S8_UNORM:
1321 case PIPE_FORMAT_Z24X8_UNORM:
1322 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1323 break;
1324 default:
1325 debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(pt->format));
1326 }
1327
1328 pipe_put_tile_raw(pt, x, y, w, h, packed, 0);
1329
1330 FREE(packed);
1331 }
1332
1333
1334 /**
1335 * Get a block of Z values, converted to 32-bit range.
1336 */
1337 void
1338 pipe_get_tile_z(struct pipe_transfer *pt,
1339 uint x, uint y, uint w, uint h,
1340 uint *z)
1341 {
1342 struct pipe_screen *screen = pt->texture->screen;
1343 const uint dstStride = w;
1344 ubyte *map;
1345 uint *pDest = z;
1346 uint i, j;
1347
1348 if (pipe_clip_tile(x, y, &w, &h, pt))
1349 return;
1350
1351 map = (ubyte *)screen->transfer_map(screen, pt);
1352 if (!map) {
1353 assert(0);
1354 return;
1355 }
1356
1357 switch (pt->format) {
1358 case PIPE_FORMAT_Z32_UNORM:
1359 {
1360 const uint *ptrc
1361 = (const uint *)(map + y * pt->stride + x*4);
1362 for (i = 0; i < h; i++) {
1363 memcpy(pDest, ptrc, 4 * w);
1364 pDest += dstStride;
1365 ptrc += pt->stride/4;
1366 }
1367 }
1368 break;
1369 case PIPE_FORMAT_S8Z24_UNORM:
1370 case PIPE_FORMAT_X8Z24_UNORM:
1371 {
1372 const uint *ptrc
1373 = (const uint *)(map + y * pt->stride + x*4);
1374 for (i = 0; i < h; i++) {
1375 for (j = 0; j < w; j++) {
1376 /* convert 24-bit Z to 32-bit Z */
1377 pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff);
1378 }
1379 pDest += dstStride;
1380 ptrc += pt->stride/4;
1381 }
1382 }
1383 break;
1384 case PIPE_FORMAT_Z24S8_UNORM:
1385 case PIPE_FORMAT_Z24X8_UNORM:
1386 {
1387 const uint *ptrc
1388 = (const uint *)(map + y * pt->stride + x*4);
1389 for (i = 0; i < h; i++) {
1390 for (j = 0; j < w; j++) {
1391 /* convert 24-bit Z to 32-bit Z */
1392 pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff);
1393 }
1394 pDest += dstStride;
1395 ptrc += pt->stride/4;
1396 }
1397 }
1398 break;
1399 case PIPE_FORMAT_Z16_UNORM:
1400 {
1401 const ushort *ptrc
1402 = (const ushort *)(map + y * pt->stride + x*2);
1403 for (i = 0; i < h; i++) {
1404 for (j = 0; j < w; j++) {
1405 /* convert 16-bit Z to 32-bit Z */
1406 pDest[j] = (ptrc[j] << 16) | ptrc[j];
1407 }
1408 pDest += dstStride;
1409 ptrc += pt->stride/2;
1410 }
1411 }
1412 break;
1413 default:
1414 assert(0);
1415 }
1416
1417 screen->transfer_unmap(screen, pt);
1418 }
1419
1420
1421 void
1422 pipe_put_tile_z(struct pipe_transfer *pt,
1423 uint x, uint y, uint w, uint h,
1424 const uint *zSrc)
1425 {
1426 struct pipe_screen *screen = pt->texture->screen;
1427 const uint srcStride = w;
1428 const uint *ptrc = zSrc;
1429 ubyte *map;
1430 uint i, j;
1431
1432 if (pipe_clip_tile(x, y, &w, &h, pt))
1433 return;
1434
1435 map = (ubyte *)screen->transfer_map(screen, pt);
1436 if (!map) {
1437 assert(0);
1438 return;
1439 }
1440
1441 switch (pt->format) {
1442 case PIPE_FORMAT_Z32_UNORM:
1443 {
1444 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1445 for (i = 0; i < h; i++) {
1446 memcpy(pDest, ptrc, 4 * w);
1447 pDest += pt->stride/4;
1448 ptrc += srcStride;
1449 }
1450 }
1451 break;
1452 case PIPE_FORMAT_S8Z24_UNORM:
1453 {
1454 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1455 assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
1456 for (i = 0; i < h; i++) {
1457 for (j = 0; j < w; j++) {
1458 /* convert 32-bit Z to 24-bit Z, preserve stencil */
1459 pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
1460 }
1461 pDest += pt->stride/4;
1462 ptrc += srcStride;
1463 }
1464 }
1465 break;
1466 case PIPE_FORMAT_X8Z24_UNORM:
1467 {
1468 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1469 for (i = 0; i < h; i++) {
1470 for (j = 0; j < w; j++) {
1471 /* convert 32-bit Z to 24-bit Z (0 stencil) */
1472 pDest[j] = ptrc[j] >> 8;
1473 }
1474 pDest += pt->stride/4;
1475 ptrc += srcStride;
1476 }
1477 }
1478 break;
1479 case PIPE_FORMAT_Z24S8_UNORM:
1480 {
1481 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1482 assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
1483 for (i = 0; i < h; i++) {
1484 for (j = 0; j < w; j++) {
1485 /* convert 32-bit Z to 24-bit Z, preserve stencil */
1486 pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
1487 }
1488 pDest += pt->stride/4;
1489 ptrc += srcStride;
1490 }
1491 }
1492 break;
1493 case PIPE_FORMAT_Z24X8_UNORM:
1494 {
1495 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1496 for (i = 0; i < h; i++) {
1497 for (j = 0; j < w; j++) {
1498 /* convert 32-bit Z to 24-bit Z (0 stencil) */
1499 pDest[j] = ptrc[j] & 0xffffff00;
1500 }
1501 pDest += pt->stride/4;
1502 ptrc += srcStride;
1503 }
1504 }
1505 break;
1506 case PIPE_FORMAT_Z16_UNORM:
1507 {
1508 ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
1509 for (i = 0; i < h; i++) {
1510 for (j = 0; j < w; j++) {
1511 /* convert 32-bit Z to 16-bit Z */
1512 pDest[j] = ptrc[j] >> 16;
1513 }
1514 pDest += pt->stride/2;
1515 ptrc += srcStride;
1516 }
1517 }
1518 break;
1519 default:
1520 assert(0);
1521 }
1522
1523 screen->transfer_unmap(screen, pt);
1524 }
1525
1526