gallium: fix a mix-up in the uint[1] do_row() case
[mesa.git] / src / gallium / auxiliary / util / p_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 * Surfaces should already be in a mapped state.
32 */
33
34
35 #include "pipe/p_defines.h"
36 #include "pipe/p_util.h"
37 #include "pipe/p_inlines.h"
38
39 #include "p_tile.h"
40
41
42
43 /**
44 * Move raw block of pixels from surface to user memory.
45 * This should be usable by any hw driver that has mappable surfaces.
46 */
47 void
48 pipe_get_tile_raw(struct pipe_context *pipe,
49 struct pipe_surface *ps,
50 uint x, uint y, uint w, uint h,
51 void *p, int dst_stride)
52 {
53 const uint cpp = ps->cpp;
54 const ubyte *pSrc;
55 const uint src_stride = ps->pitch * cpp;
56 ubyte *pDest;
57 uint i;
58
59 if (dst_stride == 0) {
60 dst_stride = w * cpp;
61 }
62
63 if (pipe_clip_tile(x, y, &w, &h, ps))
64 return;
65
66 pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp;
67 pDest = (ubyte *) p;
68
69 for (i = 0; i < h; i++) {
70 memcpy(pDest, pSrc, w * cpp);
71 pDest += dst_stride;
72 pSrc += src_stride;
73 }
74
75 pipe_surface_unmap(ps);
76 }
77
78
79 /**
80 * Move raw block of pixels from user memory to surface.
81 * This should be usable by any hw driver that has mappable surfaces.
82 */
83 void
84 pipe_put_tile_raw(struct pipe_context *pipe,
85 struct pipe_surface *ps,
86 uint x, uint y, uint w, uint h,
87 const void *p, int src_stride)
88 {
89 const uint cpp = ps->cpp;
90 const ubyte *pSrc;
91 const uint dst_stride = ps->pitch * cpp;
92 ubyte *pDest;
93 uint i;
94
95 if (src_stride == 0) {
96 src_stride = w * cpp;
97 }
98
99 if (pipe_clip_tile(x, y, &w, &h, ps))
100 return;
101
102 pSrc = (const ubyte *) p;
103 pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp;
104
105 for (i = 0; i < h; i++) {
106 memcpy(pDest, pSrc, w * cpp);
107 pDest += dst_stride;
108 pSrc += src_stride;
109 }
110
111 pipe_surface_unmap(ps);
112 }
113
114
115
116
117 /** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
118 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
119
120 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
121 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
122
123
124
125 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
126
127 static void
128 a8r8g8b8_get_tile_rgba(unsigned *src,
129 unsigned w, unsigned h,
130 float *p,
131 unsigned dst_stride)
132 {
133 unsigned i, j;
134
135 for (i = 0; i < h; i++) {
136 float *pRow = p;
137 for (j = 0; j < w; j++, pRow += 4) {
138 const unsigned pixel = *src++;
139 pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
140 pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
141 pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
142 pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
143 }
144 p += dst_stride;
145 }
146 }
147
148
149 static void
150 a8r8g8b8_put_tile_rgba(unsigned *dst,
151 unsigned w, unsigned h,
152 const float *p,
153 unsigned src_stride)
154 {
155 unsigned i, j;
156
157 for (i = 0; i < h; i++) {
158 const float *pRow = p;
159 for (j = 0; j < w; j++, pRow += 4) {
160 unsigned r, g, b, a;
161 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
162 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
163 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
164 UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
165 *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
166 }
167 p += src_stride;
168 }
169 }
170
171
172 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
173
174 static void
175 b8g8r8a8_get_tile_rgba(unsigned *src,
176 unsigned w, unsigned h,
177 float *p,
178 unsigned dst_stride)
179 {
180 unsigned i, j;
181
182 for (i = 0; i < h; i++) {
183 float *pRow = p;
184 for (j = 0; j < w; j++, pRow += 4) {
185 const unsigned pixel = *src++;
186 pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
187 pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
188 pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
189 pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
190 }
191 p += dst_stride;
192 }
193 }
194
195
196 static void
197 b8g8r8a8_put_tile_rgba(unsigned *dst,
198 unsigned w, unsigned h,
199 const float *p,
200 unsigned src_stride)
201 {
202 unsigned i, j;
203
204 for (i = 0; i < h; i++) {
205 const float *pRow = p;
206 for (j = 0; j < w; j++, pRow += 4) {
207 unsigned r, g, b, a;
208 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
209 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
210 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
211 UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
212 *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
213 }
214 p += src_stride;
215 }
216 }
217
218
219 /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
220
221 static void
222 a1r5g5b5_get_tile_rgba(ushort *src,
223 unsigned w, unsigned h,
224 float *p,
225 unsigned dst_stride)
226 {
227 unsigned i, j;
228
229 for (i = 0; i < h; i++) {
230 float *pRow = p;
231 for (j = 0; j < w; j++, pRow += 4) {
232 const ushort pixel = *src++;
233 pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
234 pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
235 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
236 pRow[3] = ((pixel >> 15) ) * 1.0f;
237 }
238 p += dst_stride;
239 }
240 }
241
242
243 /*** PIPE_FORMAT_A4R4G4B4_UNORM ***/
244
245 static void
246 a4r4g4b4_get_tile_rgba(ushort *src,
247 unsigned w, unsigned h,
248 float *p,
249 unsigned dst_stride)
250 {
251 unsigned i, j;
252
253 for (i = 0; i < h; i++) {
254 float *pRow = p;
255 for (j = 0; j < w; j++, pRow += 4) {
256 const ushort pixel = *src++;
257 pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f);
258 pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f);
259 pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f);
260 pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f);
261 }
262 p += dst_stride;
263 }
264 }
265
266
267 /*** PIPE_FORMAT_R5G6B5_UNORM ***/
268
269 static void
270 r5g6b5_get_tile_rgba(ushort *src,
271 unsigned w, unsigned h,
272 float *p,
273 unsigned dst_stride)
274 {
275 unsigned i, j;
276
277 for (i = 0; i < h; i++) {
278 float *pRow = p;
279 for (j = 0; j < w; j++, pRow += 4) {
280 const ushort pixel = *src++;
281 pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f);
282 pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f);
283 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
284 pRow[3] = 1.0f;
285 }
286 p += dst_stride;
287 }
288 }
289
290
291 static void
292 r5g5b5_put_tile_rgba(ushort *dst,
293 unsigned w, unsigned h,
294 const float *p,
295 unsigned src_stride)
296 {
297 unsigned i, j;
298
299 for (i = 0; i < h; i++) {
300 const float *pRow = p;
301 for (j = 0; j < w; j++, pRow += 4) {
302 uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0);
303 uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0);
304 uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0);
305 *dst++ = (r << 11) | (g << 5) | (b);
306 }
307 p += src_stride;
308 }
309 }
310
311
312
313 /*** PIPE_FORMAT_Z16_UNORM ***/
314
315 /**
316 * Return each Z value as four floats in [0,1].
317 */
318 static void
319 z16_get_tile_rgba(ushort *src,
320 unsigned w, unsigned h,
321 float *p,
322 unsigned dst_stride)
323 {
324 const float scale = 1.0f / 65535.0f;
325 unsigned i, j;
326
327 for (i = 0; i < h; i++) {
328 float *pRow = p;
329 for (j = 0; j < w; j++, pRow += 4) {
330 pRow[0] =
331 pRow[1] =
332 pRow[2] =
333 pRow[3] = *src++ * scale;
334 }
335 p += dst_stride;
336 }
337 }
338
339
340
341
342 /*** PIPE_FORMAT_U_L8 ***/
343
344 static void
345 l8_get_tile_rgba(ubyte *src,
346 unsigned w, unsigned h,
347 float *p,
348 unsigned dst_stride)
349 {
350 unsigned i, j;
351
352 for (i = 0; i < h; i++) {
353 float *pRow = p;
354 for (j = 0; j < w; j++, src++, pRow += 4) {
355 pRow[0] =
356 pRow[1] =
357 pRow[2] = UBYTE_TO_FLOAT(*src);
358 pRow[3] = 1.0;
359 }
360 p += dst_stride;
361 }
362 }
363
364
365 /*** PIPE_FORMAT_U_A8 ***/
366
367 static void
368 a8_get_tile_rgba(ubyte *src,
369 unsigned w, unsigned h,
370 float *p,
371 unsigned dst_stride)
372 {
373 unsigned i, j;
374
375 for (i = 0; i < h; i++) {
376 float *pRow = p;
377 for (j = 0; j < w; j++, src++, pRow += 4) {
378 pRow[0] =
379 pRow[1] =
380 pRow[2] = 0.0;
381 pRow[3] = UBYTE_TO_FLOAT(*src);
382 }
383 p += dst_stride;
384 }
385 }
386
387
388 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
389
390 static void
391 r16g16b16a16_get_tile_rgba(short *src,
392 unsigned w, unsigned h,
393 float *p,
394 unsigned dst_stride)
395 {
396 unsigned i, j;
397
398 for (i = 0; i < h; i++) {
399 float *pRow = p;
400 for (j = 0; j < w; j++, src += 4, pRow += 4) {
401 pRow[0] = SHORT_TO_FLOAT(src[0]);
402 pRow[1] = SHORT_TO_FLOAT(src[1]);
403 pRow[2] = SHORT_TO_FLOAT(src[2]);
404 pRow[3] = SHORT_TO_FLOAT(src[3]);
405 }
406 p += dst_stride;
407 }
408 }
409
410
411 static void
412 r16g16b16a16_put_tile_rgba(short *dst,
413 unsigned w, unsigned h,
414 const float *p,
415 unsigned src_stride)
416 {
417 unsigned i, j;
418
419 for (i = 0; i < h; i++) {
420 const float *pRow = p;
421 for (j = 0; j < w; j++, dst += 4, pRow += 4) {
422 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
423 UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
424 UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
425 UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
426 }
427 p += src_stride;
428 }
429 }
430
431
432
433 /*** PIPE_FORMAT_U_I8 ***/
434
435 static void
436 i8_get_tile_rgba(ubyte *src,
437 unsigned w, unsigned h,
438 float *p,
439 unsigned dst_stride)
440 {
441 unsigned i, j;
442
443 for (i = 0; i < h; i++) {
444 float *pRow = p;
445 for (j = 0; j < w; j++, src++, pRow += 4) {
446 pRow[0] =
447 pRow[1] =
448 pRow[2] =
449 pRow[3] = UBYTE_TO_FLOAT(*src);
450 }
451 p += dst_stride;
452 }
453 }
454
455
456 /*** PIPE_FORMAT_U_A8_L8 ***/
457
458 static void
459 a8_l8_get_tile_rgba(ushort *src,
460 unsigned w, unsigned h,
461 float *p,
462 unsigned dst_stride)
463 {
464 unsigned i, j;
465
466 for (i = 0; i < h; i++) {
467 float *pRow = p;
468 for (j = 0; j < w; j++, pRow += 4) {
469 ushort p = *src++;
470 pRow[0] =
471 pRow[1] =
472 pRow[2] = UBYTE_TO_FLOAT(p & 0xff);
473 pRow[3] = UBYTE_TO_FLOAT(p >> 8);
474 }
475 p += dst_stride;
476 }
477 }
478
479
480
481
482 /*** PIPE_FORMAT_Z32_UNORM ***/
483
484 /**
485 * Return each Z value as four floats in [0,1].
486 */
487 static void
488 z32_get_tile_rgba(unsigned *src,
489 unsigned w, unsigned h,
490 float *p,
491 unsigned dst_stride)
492 {
493 const double scale = 1.0 / (double) 0xffffffff;
494 unsigned i, j;
495
496 for (i = 0; i < h; i++) {
497 float *pRow = p;
498 for (j = 0; j < w; j++, pRow += 4) {
499 pRow[0] =
500 pRow[1] =
501 pRow[2] =
502 pRow[3] = (float) (*src++ * scale);
503 }
504 p += dst_stride;
505 }
506 }
507
508
509 /*** PIPE_FORMAT_S8Z24_UNORM ***/
510
511 /**
512 * Return Z component as four float in [0,1]. Stencil part ignored.
513 */
514 static void
515 s8z24_get_tile_rgba(unsigned *src,
516 unsigned w, unsigned h,
517 float *p,
518 unsigned dst_stride)
519 {
520 const double scale = 1.0 / ((1 << 24) - 1);
521 unsigned i, j;
522
523 for (i = 0; i < h; i++) {
524 float *pRow = p;
525 for (j = 0; j < w; j++, pRow += 4) {
526 pRow[0] =
527 pRow[1] =
528 pRow[2] =
529 pRow[3] = (float) (scale * (*src++ & 0xffffff));
530 }
531 p += dst_stride;
532 }
533 }
534
535
536 /*** PIPE_FORMAT_Z24S8_UNORM ***/
537
538 /**
539 * Return Z component as four float in [0,1]. Stencil part ignored.
540 */
541 static void
542 z24s8_get_tile_rgba(unsigned *src,
543 unsigned w, unsigned h,
544 float *p,
545 unsigned dst_stride)
546 {
547 const double scale = 1.0 / ((1 << 24) - 1);
548 unsigned i, j;
549
550 for (i = 0; i < h; i++) {
551 float *pRow = p;
552 for (j = 0; j < w; j++, pRow += 4) {
553 pRow[0] =
554 pRow[1] =
555 pRow[2] =
556 pRow[3] = (float) (scale * (*src++ >> 8));
557 }
558 p += dst_stride;
559 }
560 }
561
562
563 void
564 pipe_get_tile_rgba(struct pipe_context *pipe,
565 struct pipe_surface *ps,
566 uint x, uint y, uint w, uint h,
567 float *p)
568 {
569 unsigned dst_stride = w * 4;
570 void *packed;
571
572 if (pipe_clip_tile(x, y, &w, &h, ps))
573 return;
574
575 packed = MALLOC(h * w * ps->cpp);
576
577 if (!packed)
578 return;
579
580 pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp);
581
582 switch (ps->format) {
583 case PIPE_FORMAT_A8R8G8B8_UNORM:
584 a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
585 break;
586 case PIPE_FORMAT_B8G8R8A8_UNORM:
587 b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
588 break;
589 case PIPE_FORMAT_A1R5G5B5_UNORM:
590 a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
591 break;
592 case PIPE_FORMAT_A4R4G4B4_UNORM:
593 a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
594 break;
595 case PIPE_FORMAT_R5G6B5_UNORM:
596 r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
597 break;
598 case PIPE_FORMAT_U_L8:
599 l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
600 break;
601 case PIPE_FORMAT_U_A8:
602 a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
603 break;
604 case PIPE_FORMAT_U_I8:
605 i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
606 break;
607 case PIPE_FORMAT_U_A8_L8:
608 a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
609 break;
610 case PIPE_FORMAT_R16G16B16A16_SNORM:
611 r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride);
612 break;
613 case PIPE_FORMAT_Z16_UNORM:
614 z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
615 break;
616 case PIPE_FORMAT_Z32_UNORM:
617 z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
618 break;
619 case PIPE_FORMAT_S8Z24_UNORM:
620 s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
621 break;
622 case PIPE_FORMAT_Z24S8_UNORM:
623 z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
624 break;
625 default:
626 assert(0);
627 }
628
629 FREE(packed);
630 }
631
632
633 void
634 pipe_put_tile_rgba(struct pipe_context *pipe,
635 struct pipe_surface *ps,
636 uint x, uint y, uint w, uint h,
637 const float *p)
638 {
639 unsigned src_stride = w * 4;
640 void *packed;
641
642 if (pipe_clip_tile(x, y, &w, &h, ps))
643 return;
644
645 packed = MALLOC(h * w * ps->cpp);
646
647 if (!packed)
648 return;
649
650 switch (ps->format) {
651 case PIPE_FORMAT_A8R8G8B8_UNORM:
652 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
653 break;
654 case PIPE_FORMAT_B8G8R8A8_UNORM:
655 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
656 break;
657 case PIPE_FORMAT_A1R5G5B5_UNORM:
658 /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
659 break;
660 case PIPE_FORMAT_R5G6B5_UNORM:
661 r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
662 break;
663 case PIPE_FORMAT_R8G8B8A8_UNORM:
664 break;
665 case PIPE_FORMAT_U_L8:
666 /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
667 break;
668 case PIPE_FORMAT_U_A8:
669 /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
670 break;
671 case PIPE_FORMAT_U_I8:
672 /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
673 break;
674 case PIPE_FORMAT_U_A8_L8:
675 /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
676 break;
677 case PIPE_FORMAT_R16G16B16A16_SNORM:
678 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
679 break;
680 case PIPE_FORMAT_Z16_UNORM:
681 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
682 break;
683 case PIPE_FORMAT_Z32_UNORM:
684 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
685 break;
686 case PIPE_FORMAT_S8Z24_UNORM:
687 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
688 break;
689 case PIPE_FORMAT_Z24S8_UNORM:
690 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
691 break;
692 default:
693 assert(0);
694 }
695
696 pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp);
697
698 FREE(packed);
699 }
700
701
702 /**
703 * Get a block of Z values, converted to 32-bit range.
704 */
705 void
706 pipe_get_tile_z(struct pipe_context *pipe,
707 struct pipe_surface *ps,
708 uint x, uint y, uint w, uint h,
709 uint *z)
710 {
711 const uint dstStride = w;
712 uint *pDest = z;
713 uint i, j;
714
715 if (pipe_clip_tile(x, y, &w, &h, ps))
716 return;
717
718 switch (ps->format) {
719 case PIPE_FORMAT_Z32_UNORM:
720 {
721 const uint *pSrc
722 = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
723 for (i = 0; i < h; i++) {
724 memcpy(pDest, pSrc, 4 * w);
725 pDest += dstStride;
726 pSrc += ps->pitch;
727 }
728 }
729 break;
730 case PIPE_FORMAT_S8Z24_UNORM:
731 {
732 const uint *pSrc
733 = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
734 for (i = 0; i < h; i++) {
735 for (j = 0; j < w; j++) {
736 /* convert 24-bit Z to 32-bit Z */
737 pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff);
738 }
739 pDest += dstStride;
740 pSrc += ps->pitch;
741 }
742 }
743 break;
744 case PIPE_FORMAT_Z16_UNORM:
745 {
746 const ushort *pSrc
747 = (const ushort *) pipe_surface_map(ps) + (y * ps->pitch + x);
748 for (i = 0; i < h; i++) {
749 for (j = 0; j < w; j++) {
750 /* convert 16-bit Z to 32-bit Z */
751 pDest[j] = (pSrc[j] << 16) | pSrc[j];
752 }
753 pDest += dstStride;
754 pSrc += ps->pitch;
755 }
756 }
757 break;
758 default:
759 assert(0);
760 }
761
762 pipe_surface_unmap(ps);
763 }
764
765
766 void
767 pipe_put_tile_z(struct pipe_context *pipe,
768 struct pipe_surface *ps,
769 uint x, uint y, uint w, uint h,
770 const uint *zSrc)
771 {
772 const uint srcStride = w;
773 const uint *pSrc = zSrc;
774 uint i, j;
775
776 if (pipe_clip_tile(x, y, &w, &h, ps))
777 return;
778
779 switch (ps->format) {
780 case PIPE_FORMAT_Z32_UNORM:
781 {
782 uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
783 for (i = 0; i < h; i++) {
784 memcpy(pDest, pSrc, 4 * w);
785 pDest += ps->pitch;
786 pSrc += srcStride;
787 }
788 }
789 break;
790 case PIPE_FORMAT_S8Z24_UNORM:
791 {
792 uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x);
793 for (i = 0; i < h; i++) {
794 for (j = 0; j < w; j++) {
795 /* convert 32-bit Z to 24-bit Z (0 stencil) */
796 pDest[j] = pSrc[j] >> 8;
797 }
798 pDest += ps->pitch;
799 pSrc += srcStride;
800 }
801 }
802 break;
803 case PIPE_FORMAT_Z16_UNORM:
804 {
805 ushort *pDest = (ushort *) pipe_surface_map(ps) + (y * ps->pitch + x);
806 for (i = 0; i < h; i++) {
807 for (j = 0; j < w; j++) {
808 /* convert 32-bit Z to 16-bit Z */
809 pDest[j] = pSrc[j] >> 16;
810 }
811 pDest += ps->pitch;
812 pSrc += srcStride;
813 }
814 }
815 break;
816 default:
817 assert(0);
818 }
819
820 pipe_surface_unmap(ps);
821 }
822
823