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