Merge branch 'gallium-vertex-linear' into gallium-tex-surfaces
[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 struct pipe_screen *screen = pipe->screen;
54 const uint cpp = ps->cpp;
55 const ubyte *pSrc;
56 const uint src_stride = ps->pitch * cpp;
57 ubyte *pDest;
58 uint i;
59
60 if (dst_stride == 0) {
61 dst_stride = w * cpp;
62 }
63
64 if (pipe_clip_tile(x, y, &w, &h, ps))
65 return;
66
67 pSrc = (const ubyte *) screen->surface_map(screen, ps,
68 PIPE_BUFFER_USAGE_CPU_READ);
69 assert(pSrc); /* XXX: proper error handling! */
70
71 pSrc += (y * ps->pitch + x) * cpp;
72 pDest = (ubyte *) p;
73
74 for (i = 0; i < h; i++) {
75 memcpy(pDest, pSrc, w * cpp);
76 pDest += dst_stride;
77 pSrc += src_stride;
78 }
79
80 screen->surface_unmap(screen, ps);
81 }
82
83
84 /**
85 * Move raw block of pixels from user memory to surface.
86 * This should be usable by any hw driver that has mappable surfaces.
87 */
88 void
89 pipe_put_tile_raw(struct pipe_context *pipe,
90 struct pipe_surface *ps,
91 uint x, uint y, uint w, uint h,
92 const void *p, int src_stride)
93 {
94 struct pipe_screen *screen = pipe->screen;
95 const uint cpp = ps->cpp;
96 const ubyte *pSrc;
97 const uint dst_stride = ps->pitch * cpp;
98 ubyte *pDest;
99 uint i;
100
101 if (src_stride == 0) {
102 src_stride = w * cpp;
103 }
104
105 if (pipe_clip_tile(x, y, &w, &h, ps))
106 return;
107
108 pSrc = (const ubyte *) p;
109
110 pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
111 assert(pDest); /* XXX: proper error handling */
112
113 pDest += (y * ps->pitch + x) * cpp;
114
115 for (i = 0; i < h; i++) {
116 memcpy(pDest, pSrc, w * cpp);
117 pDest += dst_stride;
118 pSrc += src_stride;
119 }
120
121 screen->surface_unmap(screen, ps);
122 }
123
124
125
126
127 /** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
128 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
129
130 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
131 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
132
133
134
135 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
136
137 static void
138 a8r8g8b8_get_tile_rgba(unsigned *src,
139 unsigned w, unsigned h,
140 float *p,
141 unsigned dst_stride)
142 {
143 unsigned i, j;
144
145 for (i = 0; i < h; i++) {
146 float *pRow = p;
147 for (j = 0; j < w; j++, pRow += 4) {
148 const unsigned pixel = *src++;
149 pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
150 pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
151 pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
152 pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
153 }
154 p += dst_stride;
155 }
156 }
157
158
159 static void
160 a8r8g8b8_put_tile_rgba(unsigned *dst,
161 unsigned w, unsigned h,
162 const float *p,
163 unsigned src_stride)
164 {
165 unsigned i, j;
166
167 for (i = 0; i < h; i++) {
168 const float *pRow = p;
169 for (j = 0; j < w; j++, pRow += 4) {
170 unsigned r, g, b, a;
171 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
172 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
173 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
174 UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
175 *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
176 }
177 p += src_stride;
178 }
179 }
180
181
182 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
183
184 static void
185 x8r8g8b8_get_tile_rgba(unsigned *src,
186 unsigned w, unsigned h,
187 float *p,
188 unsigned dst_stride)
189 {
190 unsigned i, j;
191
192 for (i = 0; i < h; i++) {
193 float *pRow = p;
194 for (j = 0; j < w; j++, pRow += 4) {
195 const unsigned pixel = *src++;
196 pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
197 pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
198 pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
199 pRow[3] = UBYTE_TO_FLOAT(0xff);
200 }
201 p += dst_stride;
202 }
203 }
204
205
206 static void
207 x8r8g8b8_put_tile_rgba(unsigned *dst,
208 unsigned w, unsigned h,
209 const float *p,
210 unsigned src_stride)
211 {
212 unsigned i, j;
213
214 for (i = 0; i < h; i++) {
215 const float *pRow = p;
216 for (j = 0; j < w; j++, pRow += 4) {
217 unsigned r, g, b;
218 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
219 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
220 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
221 *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
222 }
223 p += src_stride;
224 }
225 }
226
227
228 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
229
230 static void
231 b8g8r8a8_get_tile_rgba(unsigned *src,
232 unsigned w, unsigned h,
233 float *p,
234 unsigned dst_stride)
235 {
236 unsigned i, j;
237
238 for (i = 0; i < h; i++) {
239 float *pRow = p;
240 for (j = 0; j < w; j++, pRow += 4) {
241 const unsigned pixel = *src++;
242 pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
243 pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
244 pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
245 pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
246 }
247 p += dst_stride;
248 }
249 }
250
251
252 static void
253 b8g8r8a8_put_tile_rgba(unsigned *dst,
254 unsigned w, unsigned h,
255 const float *p,
256 unsigned src_stride)
257 {
258 unsigned i, j;
259
260 for (i = 0; i < h; i++) {
261 const float *pRow = p;
262 for (j = 0; j < w; j++, pRow += 4) {
263 unsigned r, g, b, a;
264 UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]);
265 UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]);
266 UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]);
267 UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]);
268 *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
269 }
270 p += src_stride;
271 }
272 }
273
274
275 /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
276
277 static void
278 a1r5g5b5_get_tile_rgba(ushort *src,
279 unsigned w, unsigned h,
280 float *p,
281 unsigned dst_stride)
282 {
283 unsigned i, j;
284
285 for (i = 0; i < h; i++) {
286 float *pRow = p;
287 for (j = 0; j < w; j++, pRow += 4) {
288 const ushort pixel = *src++;
289 pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
290 pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
291 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
292 pRow[3] = ((pixel >> 15) ) * 1.0f;
293 }
294 p += dst_stride;
295 }
296 }
297
298
299 /*** PIPE_FORMAT_A4R4G4B4_UNORM ***/
300
301 static void
302 a4r4g4b4_get_tile_rgba(ushort *src,
303 unsigned w, unsigned h,
304 float *p,
305 unsigned dst_stride)
306 {
307 unsigned i, j;
308
309 for (i = 0; i < h; i++) {
310 float *pRow = p;
311 for (j = 0; j < w; j++, pRow += 4) {
312 const ushort pixel = *src++;
313 pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f);
314 pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f);
315 pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f);
316 pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f);
317 }
318 p += dst_stride;
319 }
320 }
321
322
323 /*** PIPE_FORMAT_R5G6B5_UNORM ***/
324
325 static void
326 r5g6b5_get_tile_rgba(ushort *src,
327 unsigned w, unsigned h,
328 float *p,
329 unsigned dst_stride)
330 {
331 unsigned i, j;
332
333 for (i = 0; i < h; i++) {
334 float *pRow = p;
335 for (j = 0; j < w; j++, pRow += 4) {
336 const ushort pixel = *src++;
337 pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f);
338 pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f);
339 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
340 pRow[3] = 1.0f;
341 }
342 p += dst_stride;
343 }
344 }
345
346
347 static void
348 r5g5b5_put_tile_rgba(ushort *dst,
349 unsigned w, unsigned h,
350 const float *p,
351 unsigned src_stride)
352 {
353 unsigned i, j;
354
355 for (i = 0; i < h; i++) {
356 const float *pRow = p;
357 for (j = 0; j < w; j++, pRow += 4) {
358 uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0);
359 uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0);
360 uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0);
361 *dst++ = (r << 11) | (g << 5) | (b);
362 }
363 p += src_stride;
364 }
365 }
366
367
368
369 /*** PIPE_FORMAT_Z16_UNORM ***/
370
371 /**
372 * Return each Z value as four floats in [0,1].
373 */
374 static void
375 z16_get_tile_rgba(ushort *src,
376 unsigned w, unsigned h,
377 float *p,
378 unsigned dst_stride)
379 {
380 const float scale = 1.0f / 65535.0f;
381 unsigned i, j;
382
383 for (i = 0; i < h; i++) {
384 float *pRow = p;
385 for (j = 0; j < w; j++, pRow += 4) {
386 pRow[0] =
387 pRow[1] =
388 pRow[2] =
389 pRow[3] = *src++ * scale;
390 }
391 p += dst_stride;
392 }
393 }
394
395
396
397
398 /*** PIPE_FORMAT_L8_UNORM ***/
399
400 static void
401 l8_get_tile_rgba(ubyte *src,
402 unsigned w, unsigned h,
403 float *p,
404 unsigned dst_stride)
405 {
406 unsigned i, j;
407
408 for (i = 0; i < h; i++) {
409 float *pRow = p;
410 for (j = 0; j < w; j++, src++, pRow += 4) {
411 pRow[0] =
412 pRow[1] =
413 pRow[2] = UBYTE_TO_FLOAT(*src);
414 pRow[3] = 1.0;
415 }
416 p += dst_stride;
417 }
418 }
419
420
421 /*** PIPE_FORMAT_A8_UNORM ***/
422
423 static void
424 a8_get_tile_rgba(ubyte *src,
425 unsigned w, unsigned h,
426 float *p,
427 unsigned dst_stride)
428 {
429 unsigned i, j;
430
431 for (i = 0; i < h; i++) {
432 float *pRow = p;
433 for (j = 0; j < w; j++, src++, pRow += 4) {
434 pRow[0] =
435 pRow[1] =
436 pRow[2] = 0.0;
437 pRow[3] = UBYTE_TO_FLOAT(*src);
438 }
439 p += dst_stride;
440 }
441 }
442
443
444 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
445
446 static void
447 r16g16b16a16_get_tile_rgba(short *src,
448 unsigned w, unsigned h,
449 float *p,
450 unsigned dst_stride)
451 {
452 unsigned i, j;
453
454 for (i = 0; i < h; i++) {
455 float *pRow = p;
456 for (j = 0; j < w; j++, src += 4, pRow += 4) {
457 pRow[0] = SHORT_TO_FLOAT(src[0]);
458 pRow[1] = SHORT_TO_FLOAT(src[1]);
459 pRow[2] = SHORT_TO_FLOAT(src[2]);
460 pRow[3] = SHORT_TO_FLOAT(src[3]);
461 }
462 p += dst_stride;
463 }
464 }
465
466
467 static void
468 r16g16b16a16_put_tile_rgba(short *dst,
469 unsigned w, unsigned h,
470 const float *p,
471 unsigned src_stride)
472 {
473 unsigned i, j;
474
475 for (i = 0; i < h; i++) {
476 const float *pRow = p;
477 for (j = 0; j < w; j++, dst += 4, pRow += 4) {
478 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
479 UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
480 UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
481 UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
482 }
483 p += src_stride;
484 }
485 }
486
487
488
489 /*** PIPE_FORMAT_I8_UNORM ***/
490
491 static void
492 i8_get_tile_rgba(ubyte *src,
493 unsigned w, unsigned h,
494 float *p,
495 unsigned dst_stride)
496 {
497 unsigned i, j;
498
499 for (i = 0; i < h; i++) {
500 float *pRow = p;
501 for (j = 0; j < w; j++, src++, pRow += 4) {
502 pRow[0] =
503 pRow[1] =
504 pRow[2] =
505 pRow[3] = UBYTE_TO_FLOAT(*src);
506 }
507 p += dst_stride;
508 }
509 }
510
511
512 /*** PIPE_FORMAT_A8L8_UNORM ***/
513
514 static void
515 a8_l8_get_tile_rgba(ushort *src,
516 unsigned w, unsigned h,
517 float *p,
518 unsigned dst_stride)
519 {
520 unsigned i, j;
521
522 for (i = 0; i < h; i++) {
523 float *pRow = p;
524 for (j = 0; j < w; j++, pRow += 4) {
525 ushort p = *src++;
526 pRow[0] =
527 pRow[1] =
528 pRow[2] = UBYTE_TO_FLOAT(p & 0xff);
529 pRow[3] = UBYTE_TO_FLOAT(p >> 8);
530 }
531 p += dst_stride;
532 }
533 }
534
535
536
537
538 /*** PIPE_FORMAT_Z32_UNORM ***/
539
540 /**
541 * Return each Z value as four floats in [0,1].
542 */
543 static void
544 z32_get_tile_rgba(unsigned *src,
545 unsigned w, unsigned h,
546 float *p,
547 unsigned dst_stride)
548 {
549 const double scale = 1.0 / (double) 0xffffffff;
550 unsigned i, j;
551
552 for (i = 0; i < h; i++) {
553 float *pRow = p;
554 for (j = 0; j < w; j++, pRow += 4) {
555 pRow[0] =
556 pRow[1] =
557 pRow[2] =
558 pRow[3] = (float) (*src++ * scale);
559 }
560 p += dst_stride;
561 }
562 }
563
564
565 /*** PIPE_FORMAT_S8Z24_UNORM ***/
566
567 /**
568 * Return Z component as four float in [0,1]. Stencil part ignored.
569 */
570 static void
571 s8z24_get_tile_rgba(unsigned *src,
572 unsigned w, unsigned h,
573 float *p,
574 unsigned dst_stride)
575 {
576 const double scale = 1.0 / ((1 << 24) - 1);
577 unsigned i, j;
578
579 for (i = 0; i < h; i++) {
580 float *pRow = p;
581 for (j = 0; j < w; j++, pRow += 4) {
582 pRow[0] =
583 pRow[1] =
584 pRow[2] =
585 pRow[3] = (float) (scale * (*src++ & 0xffffff));
586 }
587 p += dst_stride;
588 }
589 }
590
591
592 /*** PIPE_FORMAT_Z24S8_UNORM ***/
593
594 /**
595 * Return Z component as four float in [0,1]. Stencil part ignored.
596 */
597 static void
598 z24s8_get_tile_rgba(unsigned *src,
599 unsigned w, unsigned h,
600 float *p,
601 unsigned dst_stride)
602 {
603 const double scale = 1.0 / ((1 << 24) - 1);
604 unsigned i, j;
605
606 for (i = 0; i < h; i++) {
607 float *pRow = p;
608 for (j = 0; j < w; j++, pRow += 4) {
609 pRow[0] =
610 pRow[1] =
611 pRow[2] =
612 pRow[3] = (float) (scale * (*src++ >> 8));
613 }
614 p += dst_stride;
615 }
616 }
617
618
619 /*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
620
621 /**
622 * Convert YCbCr (or YCrCb) to RGBA.
623 */
624 static void
625 ycbcr_get_tile_rgba(ushort *src,
626 unsigned w, unsigned h,
627 float *p,
628 unsigned dst_stride,
629 boolean rev)
630 {
631 const float scale = 1.0f / 255.0f;
632 unsigned i, j;
633
634 /* we're assuming we're being asked for an even number of texels */
635 assert((w & 1) == 0);
636
637 for (i = 0; i < h; i++) {
638 float *pRow = p;
639 /* do two texels at a time */
640 for (j = 0; j < w; j += 2, src += 2) {
641 const ushort t0 = src[0];
642 const ushort t1 = src[1];
643 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
644 const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */
645 ubyte cb, cr;
646 float r, g, b;
647
648 if (rev) {
649 cb = t1 & 0xff; /* chroma U */
650 cr = t0 & 0xff; /* chroma V */
651 }
652 else {
653 cb = t0 & 0xff; /* chroma U */
654 cr = t1 & 0xff; /* chroma V */
655 }
656
657 /* even pixel: y0,cr,cb */
658 r = 1.164f * (y0-16) + 1.596f * (cr-128);
659 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
660 b = 1.164f * (y0-16) + 2.018f * (cb-128);
661 pRow[0] = r * scale;
662 pRow[1] = g * scale;
663 pRow[2] = b * scale;
664 pRow[3] = 1.0f;
665 pRow += 4;
666
667 /* odd pixel: use y1,cr,cb */
668 r = 1.164f * (y1-16) + 1.596f * (cr-128);
669 g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
670 b = 1.164f * (y1-16) + 2.018f * (cb-128);
671 pRow[0] = r * scale;
672 pRow[1] = g * scale;
673 pRow[2] = b * scale;
674 pRow[3] = 1.0f;
675 pRow += 4;
676
677 }
678 p += dst_stride;
679 }
680 }
681
682
683 void
684 pipe_get_tile_rgba(struct pipe_context *pipe,
685 struct pipe_surface *ps,
686 uint x, uint y, uint w, uint h,
687 float *p)
688 {
689 unsigned dst_stride = w * 4;
690 void *packed;
691
692 if (pipe_clip_tile(x, y, &w, &h, ps))
693 return;
694
695 packed = MALLOC(h * w * ps->cpp);
696
697 if (!packed)
698 return;
699
700 pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp);
701
702 switch (ps->format) {
703 case PIPE_FORMAT_A8R8G8B8_UNORM:
704 a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
705 break;
706 case PIPE_FORMAT_X8R8G8B8_UNORM:
707 x8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
708 break;
709 case PIPE_FORMAT_B8G8R8A8_UNORM:
710 b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
711 break;
712 case PIPE_FORMAT_A1R5G5B5_UNORM:
713 a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
714 break;
715 case PIPE_FORMAT_A4R4G4B4_UNORM:
716 a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
717 break;
718 case PIPE_FORMAT_R5G6B5_UNORM:
719 r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
720 break;
721 case PIPE_FORMAT_L8_UNORM:
722 l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
723 break;
724 case PIPE_FORMAT_A8_UNORM:
725 a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
726 break;
727 case PIPE_FORMAT_I8_UNORM:
728 i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride);
729 break;
730 case PIPE_FORMAT_A8L8_UNORM:
731 a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
732 break;
733 case PIPE_FORMAT_R16G16B16A16_SNORM:
734 r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride);
735 break;
736 case PIPE_FORMAT_Z16_UNORM:
737 z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride);
738 break;
739 case PIPE_FORMAT_Z32_UNORM:
740 z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
741 break;
742 case PIPE_FORMAT_S8Z24_UNORM:
743 case PIPE_FORMAT_X8Z24_UNORM:
744 s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
745 break;
746 case PIPE_FORMAT_Z24S8_UNORM:
747 z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
748 break;
749 case PIPE_FORMAT_YCBCR:
750 assert((x & 1) == 0);
751 ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE);
752 break;
753 case PIPE_FORMAT_YCBCR_REV:
754 assert((x & 1) == 0);
755 ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE);
756 break;
757 default:
758 assert(0);
759 }
760
761 FREE(packed);
762 }
763
764
765 void
766 pipe_put_tile_rgba(struct pipe_context *pipe,
767 struct pipe_surface *ps,
768 uint x, uint y, uint w, uint h,
769 const float *p)
770 {
771 unsigned src_stride = w * 4;
772 void *packed;
773
774 if (pipe_clip_tile(x, y, &w, &h, ps))
775 return;
776
777 packed = MALLOC(h * w * ps->cpp);
778
779 if (!packed)
780 return;
781
782 switch (ps->format) {
783 case PIPE_FORMAT_A8R8G8B8_UNORM:
784 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
785 break;
786 case PIPE_FORMAT_X8R8G8B8_UNORM:
787 x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
788 break;
789 case PIPE_FORMAT_B8G8R8A8_UNORM:
790 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
791 break;
792 case PIPE_FORMAT_A1R5G5B5_UNORM:
793 /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
794 break;
795 case PIPE_FORMAT_R5G6B5_UNORM:
796 r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
797 break;
798 case PIPE_FORMAT_R8G8B8A8_UNORM:
799 break;
800 case PIPE_FORMAT_L8_UNORM:
801 /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
802 break;
803 case PIPE_FORMAT_A8_UNORM:
804 /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
805 break;
806 case PIPE_FORMAT_I8_UNORM:
807 /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
808 break;
809 case PIPE_FORMAT_A8L8_UNORM:
810 /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
811 break;
812 case PIPE_FORMAT_R16G16B16A16_SNORM:
813 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
814 break;
815 case PIPE_FORMAT_Z16_UNORM:
816 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
817 break;
818 case PIPE_FORMAT_Z32_UNORM:
819 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
820 break;
821 case PIPE_FORMAT_S8Z24_UNORM:
822 case PIPE_FORMAT_X8Z24_UNORM:
823 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
824 break;
825 case PIPE_FORMAT_Z24S8_UNORM:
826 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
827 break;
828 default:
829 assert(0);
830 }
831
832 pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp);
833
834 FREE(packed);
835 }
836
837
838 /**
839 * Get a block of Z values, converted to 32-bit range.
840 */
841 void
842 pipe_get_tile_z(struct pipe_context *pipe,
843 struct pipe_surface *ps,
844 uint x, uint y, uint w, uint h,
845 uint *z)
846 {
847 struct pipe_screen *screen = pipe->screen;
848 const uint dstStride = w;
849 void *map;
850 uint *pDest = z;
851 uint i, j;
852
853 if (pipe_clip_tile(x, y, &w, &h, ps))
854 return;
855
856 map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
857 if (!map) {
858 assert(0);
859 return;
860 }
861
862 switch (ps->format) {
863 case PIPE_FORMAT_Z32_UNORM:
864 {
865 const uint *pSrc
866 = (const uint *)map + (y * ps->pitch + x);
867 for (i = 0; i < h; i++) {
868 memcpy(pDest, pSrc, 4 * w);
869 pDest += dstStride;
870 pSrc += ps->pitch;
871 }
872 }
873 break;
874 case PIPE_FORMAT_S8Z24_UNORM:
875 case PIPE_FORMAT_X8Z24_UNORM:
876 {
877 const uint *pSrc
878 = (const uint *)map + (y * ps->pitch + x);
879 for (i = 0; i < h; i++) {
880 for (j = 0; j < w; j++) {
881 /* convert 24-bit Z to 32-bit Z */
882 pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff);
883 }
884 pDest += dstStride;
885 pSrc += ps->pitch;
886 }
887 }
888 break;
889 case PIPE_FORMAT_Z16_UNORM:
890 {
891 const ushort *pSrc
892 = (const ushort *)map + (y * ps->pitch + x);
893 for (i = 0; i < h; i++) {
894 for (j = 0; j < w; j++) {
895 /* convert 16-bit Z to 32-bit Z */
896 pDest[j] = (pSrc[j] << 16) | pSrc[j];
897 }
898 pDest += dstStride;
899 pSrc += ps->pitch;
900 }
901 }
902 break;
903 default:
904 assert(0);
905 }
906
907 screen->surface_unmap(screen, ps);
908 }
909
910
911 void
912 pipe_put_tile_z(struct pipe_context *pipe,
913 struct pipe_surface *ps,
914 uint x, uint y, uint w, uint h,
915 const uint *zSrc)
916 {
917 struct pipe_screen *screen = pipe->screen;
918 const uint srcStride = w;
919 const uint *pSrc = zSrc;
920 void *map;
921 uint i, j;
922
923 if (pipe_clip_tile(x, y, &w, &h, ps))
924 return;
925
926 map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
927 if (!map) {
928 assert(0);
929 return;
930 }
931
932 switch (ps->format) {
933 case PIPE_FORMAT_Z32_UNORM:
934 {
935 uint *pDest = (uint *) map + (y * ps->pitch + x);
936 for (i = 0; i < h; i++) {
937 memcpy(pDest, pSrc, 4 * w);
938 pDest += ps->pitch;
939 pSrc += srcStride;
940 }
941 }
942 break;
943 case PIPE_FORMAT_S8Z24_UNORM:
944 case PIPE_FORMAT_X8Z24_UNORM:
945 {
946 uint *pDest = (uint *) map + (y * ps->pitch + x);
947 for (i = 0; i < h; i++) {
948 for (j = 0; j < w; j++) {
949 /* convert 32-bit Z to 24-bit Z (0 stencil) */
950 pDest[j] = pSrc[j] >> 8;
951 }
952 pDest += ps->pitch;
953 pSrc += srcStride;
954 }
955 }
956 break;
957 case PIPE_FORMAT_Z16_UNORM:
958 {
959 ushort *pDest = (ushort *) map + (y * ps->pitch + x);
960 for (i = 0; i < h; i++) {
961 for (j = 0; j < w; j++) {
962 /* convert 32-bit Z to 16-bit Z */
963 pDest[j] = pSrc[j] >> 16;
964 }
965 pDest += ps->pitch;
966 pSrc += srcStride;
967 }
968 }
969 break;
970 default:
971 assert(0);
972 }
973
974 screen->surface_unmap(screen, ps);
975 }
976
977