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