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