gallium: interface cleanups, remove nblocksx/y from pipe_texture and more
[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_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 */
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 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
112 static void
113 a8r8g8b8_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
134 static void
135 a8r8g8b8_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
159 static void
160 x8r8g8b8_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
181 static void
182 x8r8g8b8_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
205 static void
206 b8g8r8a8_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
227 static void
228 b8g8r8a8_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
252 static void
253 a1r5g5b5_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
274 static void
275 a1r5g5b5_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
303 static void
304 a4r4g4b4_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
325 static void
326 a4r4g4b4_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
354 static void
355 r5g6b5_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
376 static void
377 r5g6b5_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
400 static void
401 r8g8b8_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
422 static void
423 r8g8b8_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 */
449 static void
450 z16_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
475 static void
476 l8_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
496 static void
497 l8_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
519 static void
520 a8_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
540 static void
541 a8_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
563 static void
564 r16_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
584 static void
585 r16_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
604 static void
605 r16g16b16a16_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
625 static void
626 r16g16b16a16_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 */
653 static INLINE float
654 srgb_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 */
681 static INLINE ubyte
682 linear_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
695 static void
696 a8r8g8b8_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
716 static void
717 a8r8g8b8_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
741 static void
742 a8l8_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
762 static void
763 a8l8_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
785 static void
786 l8_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
805 static void
806 l8_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
827 static void
828 i8_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
848 static void
849 i8_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
870 static void
871 a8l8_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
892 static void
893 a8l8_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 */
920 static void
921 z32_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 */
947 static void
948 s8z24_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 */
974 static void
975 z24s8_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 */
1001 static void
1002 z32f_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 */
1027 static void
1028 ycbcr_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
1110 static void
1111 fake_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
1131 void
1132 pipe_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
1216 void
1217 pipe_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
1244 void
1245 pipe_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 */
1340 void
1341 pipe_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
1425 void
1426 pipe_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