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