Merge commit 'origin/master' into gallium-sampler-view
[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_context *pipe,
49 struct pipe_transfer *pt,
50 uint x, uint y, uint w, uint h,
51 void *dst, int dst_stride)
52 {
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 = pipe->transfer_map(pipe, 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 pipe->transfer_unmap(pipe, 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_context *pipe,
77 struct pipe_transfer *pt,
78 uint x, uint y, uint w, uint h,
79 const void *src, int src_stride)
80 {
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 = pipe->transfer_map(pipe, 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 pipe->transfer_unmap(pipe, 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_context *pipe,
1250 struct pipe_transfer *pt,
1251 uint x, uint y, uint w, uint h,
1252 float *p)
1253 {
1254 unsigned dst_stride = w * 4;
1255 void *packed;
1256 enum pipe_format format = pt->texture->format;
1257
1258 if (pipe_clip_tile(x, y, &w, &h, pt))
1259 return;
1260
1261 packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
1262
1263 if (!packed)
1264 return;
1265
1266 if(format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV)
1267 assert((x & 1) == 0);
1268
1269 pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
1270
1271 pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
1272
1273 FREE(packed);
1274 }
1275
1276
1277 void
1278 pipe_get_tile_swizzle(struct pipe_context *pipe,
1279 struct pipe_transfer *pt,
1280 uint x,
1281 uint y,
1282 uint w,
1283 uint h,
1284 uint swizzle_r,
1285 uint swizzle_g,
1286 uint swizzle_b,
1287 uint swizzle_a,
1288 enum pipe_format format,
1289 float *p)
1290 {
1291 unsigned dst_stride = w * 4;
1292 void *packed;
1293 uint i;
1294 float rgba01[6];
1295
1296 if (pipe_clip_tile(x, y, &w, &h, pt)) {
1297 return;
1298 }
1299
1300 packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
1301 if (!packed) {
1302 return;
1303 }
1304
1305 if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
1306 assert((x & 1) == 0);
1307 }
1308
1309 pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
1310
1311 pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
1312
1313 FREE(packed);
1314
1315 if (swizzle_r == PIPE_SWIZZLE_RED &&
1316 swizzle_g == PIPE_SWIZZLE_GREEN &&
1317 swizzle_b == PIPE_SWIZZLE_BLUE &&
1318 swizzle_a == PIPE_SWIZZLE_ALPHA) {
1319 /* no-op, skip */
1320 return;
1321 }
1322
1323 rgba01[PIPE_SWIZZLE_ZERO] = 0.0f;
1324 rgba01[PIPE_SWIZZLE_ONE] = 1.0f;
1325
1326 for (i = 0; i < w * h; i++) {
1327 rgba01[PIPE_SWIZZLE_RED] = p[0];
1328 rgba01[PIPE_SWIZZLE_GREEN] = p[1];
1329 rgba01[PIPE_SWIZZLE_BLUE] = p[2];
1330 rgba01[PIPE_SWIZZLE_ALPHA] = p[3];
1331
1332 *p++ = rgba01[swizzle_r];
1333 *p++ = rgba01[swizzle_g];
1334 *p++ = rgba01[swizzle_b];
1335 *p++ = rgba01[swizzle_a];
1336 }
1337 }
1338
1339
1340 void
1341 pipe_put_tile_rgba(struct pipe_context *pipe,
1342 struct pipe_transfer *pt,
1343 uint x, uint y, uint w, uint h,
1344 const float *p)
1345 {
1346 unsigned src_stride = w * 4;
1347 void *packed;
1348 enum pipe_format format = pt->texture->format;
1349
1350 if (pipe_clip_tile(x, y, &w, &h, pt))
1351 return;
1352
1353 packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
1354
1355 if (!packed)
1356 return;
1357
1358 switch (format) {
1359 case PIPE_FORMAT_B8G8R8A8_UNORM:
1360 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1361 break;
1362 case PIPE_FORMAT_B8G8R8X8_UNORM:
1363 x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1364 break;
1365 case PIPE_FORMAT_A8R8G8B8_UNORM:
1366 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1367 break;
1368 case PIPE_FORMAT_A8B8G8R8_UNORM:
1369 r8g8b8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1370 break;
1371 case PIPE_FORMAT_B5G5R5A1_UNORM:
1372 a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1373 break;
1374 case PIPE_FORMAT_B5G6R5_UNORM:
1375 r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1376 break;
1377 case PIPE_FORMAT_R8G8B8_UNORM:
1378 r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1379 break;
1380 case PIPE_FORMAT_B4G4R4A4_UNORM:
1381 a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1382 break;
1383 case PIPE_FORMAT_L8_UNORM:
1384 l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1385 break;
1386 case PIPE_FORMAT_A8_UNORM:
1387 a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1388 break;
1389 case PIPE_FORMAT_I8_UNORM:
1390 i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1391 break;
1392 case PIPE_FORMAT_L8A8_UNORM:
1393 a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1394 break;
1395 case PIPE_FORMAT_R16_SNORM:
1396 r16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1397 break;
1398 case PIPE_FORMAT_R16G16B16A16_SNORM:
1399 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1400 break;
1401 case PIPE_FORMAT_B8G8R8A8_SRGB:
1402 a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1403 break;
1404 case PIPE_FORMAT_L8A8_SRGB:
1405 a8l8_srgb_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1406 break;
1407 case PIPE_FORMAT_L8_SRGB:
1408 l8_srgb_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1409 break;
1410 case PIPE_FORMAT_Z16_UNORM:
1411 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
1412 break;
1413 case PIPE_FORMAT_Z32_UNORM:
1414 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1415 break;
1416 case PIPE_FORMAT_Z24S8_UNORM:
1417 case PIPE_FORMAT_Z24X8_UNORM:
1418 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1419 break;
1420 case PIPE_FORMAT_S8Z24_UNORM:
1421 case PIPE_FORMAT_X8Z24_UNORM:
1422 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1423 break;
1424 default:
1425 util_format_write_4f(format,
1426 p, src_stride * sizeof(float),
1427 packed, util_format_get_stride(format, w),
1428 0, 0, w, h);
1429 }
1430
1431 pipe_put_tile_raw(pipe, pt, x, y, w, h, packed, 0);
1432
1433 FREE(packed);
1434 }
1435
1436
1437 /**
1438 * Get a block of Z values, converted to 32-bit range.
1439 */
1440 void
1441 pipe_get_tile_z(struct pipe_context *pipe,
1442 struct pipe_transfer *pt,
1443 uint x, uint y, uint w, uint h,
1444 uint *z)
1445 {
1446 const uint dstStride = w;
1447 ubyte *map;
1448 uint *pDest = z;
1449 uint i, j;
1450 enum pipe_format format = pt->texture->format;
1451
1452 if (pipe_clip_tile(x, y, &w, &h, pt))
1453 return;
1454
1455 map = (ubyte *)pipe->transfer_map(pipe, pt);
1456 if (!map) {
1457 assert(0);
1458 return;
1459 }
1460
1461 switch (format) {
1462 case PIPE_FORMAT_Z32_UNORM:
1463 {
1464 const uint *ptrc
1465 = (const uint *)(map + y * pt->stride + x*4);
1466 for (i = 0; i < h; i++) {
1467 memcpy(pDest, ptrc, 4 * w);
1468 pDest += dstStride;
1469 ptrc += pt->stride/4;
1470 }
1471 }
1472 break;
1473 case PIPE_FORMAT_Z24S8_UNORM:
1474 case PIPE_FORMAT_Z24X8_UNORM:
1475 {
1476 const uint *ptrc
1477 = (const uint *)(map + y * pt->stride + x*4);
1478 for (i = 0; i < h; i++) {
1479 for (j = 0; j < w; j++) {
1480 /* convert 24-bit Z to 32-bit Z */
1481 pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff);
1482 }
1483 pDest += dstStride;
1484 ptrc += pt->stride/4;
1485 }
1486 }
1487 break;
1488 case PIPE_FORMAT_S8Z24_UNORM:
1489 case PIPE_FORMAT_X8Z24_UNORM:
1490 {
1491 const uint *ptrc
1492 = (const uint *)(map + y * pt->stride + x*4);
1493 for (i = 0; i < h; i++) {
1494 for (j = 0; j < w; j++) {
1495 /* convert 24-bit Z to 32-bit Z */
1496 pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff);
1497 }
1498 pDest += dstStride;
1499 ptrc += pt->stride/4;
1500 }
1501 }
1502 break;
1503 case PIPE_FORMAT_Z16_UNORM:
1504 {
1505 const ushort *ptrc
1506 = (const ushort *)(map + y * pt->stride + x*2);
1507 for (i = 0; i < h; i++) {
1508 for (j = 0; j < w; j++) {
1509 /* convert 16-bit Z to 32-bit Z */
1510 pDest[j] = (ptrc[j] << 16) | ptrc[j];
1511 }
1512 pDest += dstStride;
1513 ptrc += pt->stride/2;
1514 }
1515 }
1516 break;
1517 default:
1518 assert(0);
1519 }
1520
1521 pipe->transfer_unmap(pipe, pt);
1522 }
1523
1524
1525 void
1526 pipe_put_tile_z(struct pipe_context *pipe,
1527 struct pipe_transfer *pt,
1528 uint x, uint y, uint w, uint h,
1529 const uint *zSrc)
1530 {
1531 const uint srcStride = w;
1532 const uint *ptrc = zSrc;
1533 ubyte *map;
1534 uint i, j;
1535 enum pipe_format format = pt->texture->format;
1536
1537 if (pipe_clip_tile(x, y, &w, &h, pt))
1538 return;
1539
1540 map = (ubyte *)pipe->transfer_map(pipe, pt);
1541 if (!map) {
1542 assert(0);
1543 return;
1544 }
1545
1546 switch (format) {
1547 case PIPE_FORMAT_Z32_UNORM:
1548 {
1549 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1550 for (i = 0; i < h; i++) {
1551 memcpy(pDest, ptrc, 4 * w);
1552 pDest += pt->stride/4;
1553 ptrc += srcStride;
1554 }
1555 }
1556 break;
1557 case PIPE_FORMAT_Z24S8_UNORM:
1558 {
1559 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1560 assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
1561 for (i = 0; i < h; i++) {
1562 for (j = 0; j < w; j++) {
1563 /* convert 32-bit Z to 24-bit Z, preserve stencil */
1564 pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
1565 }
1566 pDest += pt->stride/4;
1567 ptrc += srcStride;
1568 }
1569 }
1570 break;
1571 case PIPE_FORMAT_Z24X8_UNORM:
1572 {
1573 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1574 for (i = 0; i < h; i++) {
1575 for (j = 0; j < w; j++) {
1576 /* convert 32-bit Z to 24-bit Z (0 stencil) */
1577 pDest[j] = ptrc[j] >> 8;
1578 }
1579 pDest += pt->stride/4;
1580 ptrc += srcStride;
1581 }
1582 }
1583 break;
1584 case PIPE_FORMAT_S8Z24_UNORM:
1585 {
1586 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1587 assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
1588 for (i = 0; i < h; i++) {
1589 for (j = 0; j < w; j++) {
1590 /* convert 32-bit Z to 24-bit Z, preserve stencil */
1591 pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
1592 }
1593 pDest += pt->stride/4;
1594 ptrc += srcStride;
1595 }
1596 }
1597 break;
1598 case PIPE_FORMAT_X8Z24_UNORM:
1599 {
1600 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1601 for (i = 0; i < h; i++) {
1602 for (j = 0; j < w; j++) {
1603 /* convert 32-bit Z to 24-bit Z (0 stencil) */
1604 pDest[j] = ptrc[j] & 0xffffff00;
1605 }
1606 pDest += pt->stride/4;
1607 ptrc += srcStride;
1608 }
1609 }
1610 break;
1611 case PIPE_FORMAT_Z16_UNORM:
1612 {
1613 ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
1614 for (i = 0; i < h; i++) {
1615 for (j = 0; j < w; j++) {
1616 /* convert 32-bit Z to 16-bit Z */
1617 pDest[j] = ptrc[j] >> 16;
1618 }
1619 pDest += pt->stride/2;
1620 ptrc += srcStride;
1621 }
1622 }
1623 break;
1624 default:
1625 assert(0);
1626 }
1627
1628 pipe->transfer_unmap(pipe, pt);
1629 }
1630
1631