Merge branch '7.8'
[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 */
32
33
34 #include "pipe/p_defines.h"
35 #include "util/u_inlines.h"
36
37 #include "util/u_format.h"
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 transfer object to user memory.
46 */
47 void
48 pipe_get_tile_raw(struct pipe_context *pipe,
49 struct pipe_transfer *pt,
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 = util_format_get_stride(pt->texture->format, w);
57
58 if (pipe_clip_tile(x, y, &w, &h, pt))
59 return;
60
61 src = pipe->transfer_map(pipe, pt);
62 assert(src);
63 if(!src)
64 return;
65
66 util_copy_rect(dst, pt->texture->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
67
68 pipe->transfer_unmap(pipe, pt);
69 }
70
71
72 /**
73 * Move raw block of pixels from user memory to transfer object.
74 */
75 void
76 pipe_put_tile_raw(struct pipe_context *pipe,
77 struct pipe_transfer *pt,
78 uint x, uint y, uint w, uint h,
79 const void *src, int src_stride)
80 {
81 void *dst;
82 enum pipe_format format = pt->texture->format;
83
84 if (src_stride == 0)
85 src_stride = util_format_get_stride(format, w);
86
87 if (pipe_clip_tile(x, y, &w, &h, pt))
88 return;
89
90 dst = pipe->transfer_map(pipe, pt);
91 assert(dst);
92 if(!dst)
93 return;
94
95 util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0);
96
97 pipe->transfer_unmap(pipe, pt);
98 }
99
100
101
102
103 /** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
104 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
105
106 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
107 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
108
109
110
111 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
112
113 static void
114 a8r8g8b8_get_tile_rgba(const unsigned *src,
115 unsigned w, unsigned h,
116 float *p,
117 unsigned dst_stride)
118 {
119 unsigned i, j;
120
121 for (i = 0; i < h; i++) {
122 float *pRow = p;
123 for (j = 0; j < w; j++, pRow += 4) {
124 const unsigned pixel = *src++;
125 pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
126 pRow[1] = ubyte_to_float((pixel >> 8) & 0xff);
127 pRow[2] = ubyte_to_float((pixel >> 0) & 0xff);
128 pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
129 }
130 p += dst_stride;
131 }
132 }
133
134
135 static void
136 a8r8g8b8_put_tile_rgba(unsigned *dst,
137 unsigned w, unsigned h,
138 const float *p,
139 unsigned src_stride)
140 {
141 unsigned i, j;
142
143 for (i = 0; i < h; i++) {
144 const float *pRow = p;
145 for (j = 0; j < w; j++, pRow += 4) {
146 unsigned r, g, b, a;
147 r = float_to_ubyte(pRow[0]);
148 g = float_to_ubyte(pRow[1]);
149 b = float_to_ubyte(pRow[2]);
150 a = float_to_ubyte(pRow[3]);
151 *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
152 }
153 p += src_stride;
154 }
155 }
156
157
158 /*** PIPE_FORMAT_B8G8R8X8_UNORM ***/
159
160 static void
161 x8r8g8b8_get_tile_rgba(const unsigned *src,
162 unsigned w, unsigned h,
163 float *p,
164 unsigned dst_stride)
165 {
166 unsigned i, j;
167
168 for (i = 0; i < h; i++) {
169 float *pRow = p;
170 for (j = 0; j < w; j++, pRow += 4) {
171 const unsigned pixel = *src++;
172 pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
173 pRow[1] = ubyte_to_float((pixel >> 8) & 0xff);
174 pRow[2] = ubyte_to_float((pixel >> 0) & 0xff);
175 pRow[3] = 1.0F;
176 }
177 p += dst_stride;
178 }
179 }
180
181
182 static void
183 x8r8g8b8_put_tile_rgba(unsigned *dst,
184 unsigned w, unsigned h,
185 const float *p,
186 unsigned src_stride)
187 {
188 unsigned i, j;
189
190 for (i = 0; i < h; i++) {
191 const float *pRow = p;
192 for (j = 0; j < w; j++, pRow += 4) {
193 unsigned r, g, b;
194 r = float_to_ubyte(pRow[0]);
195 g = float_to_ubyte(pRow[1]);
196 b = float_to_ubyte(pRow[2]);
197 *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
198 }
199 p += src_stride;
200 }
201 }
202
203
204 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
205
206 static void
207 b8g8r8a8_get_tile_rgba(const unsigned *src,
208 unsigned w, unsigned h,
209 float *p,
210 unsigned dst_stride)
211 {
212 unsigned i, j;
213
214 for (i = 0; i < h; i++) {
215 float *pRow = p;
216 for (j = 0; j < w; j++, pRow += 4) {
217 const unsigned pixel = *src++;
218 pRow[0] = ubyte_to_float((pixel >> 8) & 0xff);
219 pRow[1] = ubyte_to_float((pixel >> 16) & 0xff);
220 pRow[2] = ubyte_to_float((pixel >> 24) & 0xff);
221 pRow[3] = ubyte_to_float((pixel >> 0) & 0xff);
222 }
223 p += dst_stride;
224 }
225 }
226
227
228 static void
229 b8g8r8a8_put_tile_rgba(unsigned *dst,
230 unsigned w, unsigned h,
231 const float *p,
232 unsigned src_stride)
233 {
234 unsigned i, j;
235
236 for (i = 0; i < h; i++) {
237 const float *pRow = p;
238 for (j = 0; j < w; j++, pRow += 4) {
239 unsigned r, g, b, a;
240 r = float_to_ubyte(pRow[0]);
241 g = float_to_ubyte(pRow[1]);
242 b = float_to_ubyte(pRow[2]);
243 a = float_to_ubyte(pRow[3]);
244 *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
245 }
246 p += src_stride;
247 }
248 }
249
250
251 /*** PIPE_FORMAT_A8B8G8R8_UNORM ***/
252
253 static void
254 r8g8b8a8_get_tile_rgba(const unsigned *src,
255 unsigned w, unsigned h,
256 float *p,
257 unsigned dst_stride)
258 {
259 unsigned i, j;
260
261 for (i = 0; i < h; i++) {
262 float *pRow = p;
263 for (j = 0; j < w; j++, pRow += 4) {
264 const unsigned pixel = *src++;
265 pRow[0] = ubyte_to_float((pixel >> 24) & 0xff);
266 pRow[1] = ubyte_to_float((pixel >> 16) & 0xff);
267 pRow[2] = ubyte_to_float((pixel >> 8) & 0xff);
268 pRow[3] = ubyte_to_float((pixel >> 0) & 0xff);
269 }
270 p += dst_stride;
271 }
272 }
273
274
275 static void
276 r8g8b8a8_put_tile_rgba(unsigned *dst,
277 unsigned w, unsigned h,
278 const float *p,
279 unsigned src_stride)
280 {
281 unsigned i, j;
282
283 for (i = 0; i < h; i++) {
284 const float *pRow = p;
285 for (j = 0; j < w; j++, pRow += 4) {
286 unsigned r, g, b, a;
287 r = float_to_ubyte(pRow[0]);
288 g = float_to_ubyte(pRow[1]);
289 b = float_to_ubyte(pRow[2]);
290 a = float_to_ubyte(pRow[3]);
291 *dst++ = (r << 24) | (g << 16) | (b << 8) | a;
292 }
293 p += src_stride;
294 }
295 }
296
297
298 /*** PIPE_FORMAT_B5G5R5X1_UNORM ***/
299
300 static void
301 x1r5g5b5_get_tile_rgba(const ushort *src,
302 unsigned w, unsigned h,
303 float *p,
304 unsigned dst_stride)
305 {
306 unsigned i, j;
307
308 for (i = 0; i < h; i++) {
309 float *pRow = p;
310 for (j = 0; j < w; j++, pRow += 4) {
311 const ushort pixel = *src++;
312 pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
313 pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
314 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
315 pRow[3] = 1.0f;
316 }
317 p += dst_stride;
318 }
319 }
320
321
322 static void
323 x1r5g5b5_put_tile_rgba(ushort *dst,
324 unsigned w, unsigned h,
325 const float *p,
326 unsigned src_stride)
327 {
328 unsigned i, j;
329
330 for (i = 0; i < h; i++) {
331 const float *pRow = p;
332 for (j = 0; j < w; j++, pRow += 4) {
333 unsigned r, g, b;
334 r = float_to_ubyte(pRow[0]);
335 g = float_to_ubyte(pRow[1]);
336 b = float_to_ubyte(pRow[2]);
337 r = r >> 3; /* 5 bits */
338 g = g >> 3; /* 5 bits */
339 b = b >> 3; /* 5 bits */
340 *dst++ = (1 << 15) | (r << 10) | (g << 5) | b;
341 }
342 p += src_stride;
343 }
344 }
345
346
347 /*** PIPE_FORMAT_B5G5R5A1_UNORM ***/
348
349 static void
350 a1r5g5b5_get_tile_rgba(const ushort *src,
351 unsigned w, unsigned h,
352 float *p,
353 unsigned dst_stride)
354 {
355 unsigned i, j;
356
357 for (i = 0; i < h; i++) {
358 float *pRow = p;
359 for (j = 0; j < w; j++, pRow += 4) {
360 const ushort pixel = *src++;
361 pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
362 pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
363 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
364 pRow[3] = ((pixel >> 15) ) * 1.0f;
365 }
366 p += dst_stride;
367 }
368 }
369
370
371 static void
372 a1r5g5b5_put_tile_rgba(ushort *dst,
373 unsigned w, unsigned h,
374 const float *p,
375 unsigned src_stride)
376 {
377 unsigned i, j;
378
379 for (i = 0; i < h; i++) {
380 const float *pRow = p;
381 for (j = 0; j < w; j++, pRow += 4) {
382 unsigned r, g, b, a;
383 r = float_to_ubyte(pRow[0]);
384 g = float_to_ubyte(pRow[1]);
385 b = float_to_ubyte(pRow[2]);
386 a = float_to_ubyte(pRow[3]);
387 r = r >> 3; /* 5 bits */
388 g = g >> 3; /* 5 bits */
389 b = b >> 3; /* 5 bits */
390 a = a >> 7; /* 1 bit */
391 *dst++ = (a << 15) | (r << 10) | (g << 5) | b;
392 }
393 p += src_stride;
394 }
395 }
396
397
398 /*** PIPE_FORMAT_B4G4R4A4_UNORM ***/
399
400 static void
401 a4r4g4b4_get_tile_rgba(const ushort *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++, pRow += 4) {
411 const ushort pixel = *src++;
412 pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f);
413 pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f);
414 pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f);
415 pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f);
416 }
417 p += dst_stride;
418 }
419 }
420
421
422 static void
423 a4r4g4b4_put_tile_rgba(ushort *dst,
424 unsigned w, unsigned h,
425 const float *p,
426 unsigned src_stride)
427 {
428 unsigned i, j;
429
430 for (i = 0; i < h; i++) {
431 const float *pRow = p;
432 for (j = 0; j < w; j++, pRow += 4) {
433 unsigned r, g, b, a;
434 r = float_to_ubyte(pRow[0]);
435 g = float_to_ubyte(pRow[1]);
436 b = float_to_ubyte(pRow[2]);
437 a = float_to_ubyte(pRow[3]);
438 r >>= 4;
439 g >>= 4;
440 b >>= 4;
441 a >>= 4;
442 *dst++ = (a << 12) | (r << 8) | (g << 4) | b;
443 }
444 p += src_stride;
445 }
446 }
447
448
449 /*** PIPE_FORMAT_B5G6R5_UNORM ***/
450
451 static void
452 r5g6b5_get_tile_rgba(const ushort *src,
453 unsigned w, unsigned h,
454 float *p,
455 unsigned dst_stride)
456 {
457 unsigned i, j;
458
459 for (i = 0; i < h; i++) {
460 float *pRow = p;
461 for (j = 0; j < w; j++, pRow += 4) {
462 const ushort pixel = *src++;
463 pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f);
464 pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f);
465 pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
466 pRow[3] = 1.0f;
467 }
468 p += dst_stride;
469 }
470 }
471
472
473 static void
474 r5g6b5_put_tile_rgba(ushort *dst,
475 unsigned w, unsigned h,
476 const float *p,
477 unsigned src_stride)
478 {
479 unsigned i, j;
480
481 for (i = 0; i < h; i++) {
482 const float *pRow = p;
483 for (j = 0; j < w; j++, pRow += 4) {
484 uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0);
485 uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0);
486 uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0);
487 *dst++ = (r << 11) | (g << 5) | (b);
488 }
489 p += src_stride;
490 }
491 }
492
493
494
495 /*** PIPE_FORMAT_R8G8B8_UNORM ***/
496
497 static void
498 r8g8b8_get_tile_rgba(const ubyte *src,
499 unsigned w, unsigned h,
500 float *p,
501 unsigned dst_stride)
502 {
503 unsigned i, j;
504
505 for (i = 0; i < h; i++) {
506 float *pRow = p;
507 for (j = 0; j < w; j++, pRow += 4) {
508 pRow[0] = ubyte_to_float(src[0]);
509 pRow[1] = ubyte_to_float(src[1]);
510 pRow[2] = ubyte_to_float(src[2]);
511 pRow[3] = 1.0f;
512 src += 3;
513 }
514 p += dst_stride;
515 }
516 }
517
518
519 static void
520 r8g8b8_put_tile_rgba(ubyte *dst,
521 unsigned w, unsigned h,
522 const float *p,
523 unsigned src_stride)
524 {
525 unsigned i, j;
526
527 for (i = 0; i < h; i++) {
528 const float *pRow = p;
529 for (j = 0; j < w; j++, pRow += 4) {
530 dst[0] = float_to_ubyte(pRow[0]);
531 dst[1] = float_to_ubyte(pRow[1]);
532 dst[2] = float_to_ubyte(pRow[2]);
533 dst += 3;
534 }
535 p += src_stride;
536 }
537 }
538
539
540
541 /*** PIPE_FORMAT_Z16_UNORM ***/
542
543 /**
544 * Return each Z value as four floats in [0,1].
545 */
546 static void
547 z16_get_tile_rgba(const ushort *src,
548 unsigned w, unsigned h,
549 float *p,
550 unsigned dst_stride)
551 {
552 const float scale = 1.0f / 65535.0f;
553 unsigned i, j;
554
555 for (i = 0; i < h; i++) {
556 float *pRow = p;
557 for (j = 0; j < w; j++, pRow += 4) {
558 pRow[0] =
559 pRow[1] =
560 pRow[2] =
561 pRow[3] = *src++ * scale;
562 }
563 p += dst_stride;
564 }
565 }
566
567
568
569
570 /*** PIPE_FORMAT_L8_UNORM ***/
571
572 static void
573 l8_get_tile_rgba(const ubyte *src,
574 unsigned w, unsigned h,
575 float *p,
576 unsigned dst_stride)
577 {
578 unsigned i, j;
579
580 for (i = 0; i < h; i++) {
581 float *pRow = p;
582 for (j = 0; j < w; j++, src++, pRow += 4) {
583 pRow[0] =
584 pRow[1] =
585 pRow[2] = ubyte_to_float(*src);
586 pRow[3] = 1.0;
587 }
588 p += dst_stride;
589 }
590 }
591
592
593 static void
594 l8_put_tile_rgba(ubyte *dst,
595 unsigned w, unsigned h,
596 const float *p,
597 unsigned src_stride)
598 {
599 unsigned i, j;
600
601 for (i = 0; i < h; i++) {
602 const float *pRow = p;
603 for (j = 0; j < w; j++, pRow += 4) {
604 unsigned r;
605 r = float_to_ubyte(pRow[0]);
606 *dst++ = (ubyte) r;
607 }
608 p += src_stride;
609 }
610 }
611
612
613
614 /*** PIPE_FORMAT_A8_UNORM ***/
615
616 static void
617 a8_get_tile_rgba(const ubyte *src,
618 unsigned w, unsigned h,
619 float *p,
620 unsigned dst_stride)
621 {
622 unsigned i, j;
623
624 for (i = 0; i < h; i++) {
625 float *pRow = p;
626 for (j = 0; j < w; j++, src++, pRow += 4) {
627 pRow[0] =
628 pRow[1] =
629 pRow[2] = 0.0;
630 pRow[3] = ubyte_to_float(*src);
631 }
632 p += dst_stride;
633 }
634 }
635
636
637 static void
638 a8_put_tile_rgba(ubyte *dst,
639 unsigned w, unsigned h,
640 const float *p,
641 unsigned src_stride)
642 {
643 unsigned i, j;
644
645 for (i = 0; i < h; i++) {
646 const float *pRow = p;
647 for (j = 0; j < w; j++, pRow += 4) {
648 unsigned a;
649 a = float_to_ubyte(pRow[3]);
650 *dst++ = (ubyte) a;
651 }
652 p += src_stride;
653 }
654 }
655
656
657
658 /*** PIPE_FORMAT_R16_SNORM ***/
659
660 static void
661 r16_get_tile_rgba(const short *src,
662 unsigned w, unsigned h,
663 float *p,
664 unsigned dst_stride)
665 {
666 unsigned i, j;
667
668 for (i = 0; i < h; i++) {
669 float *pRow = p;
670 for (j = 0; j < w; j++, src++, pRow += 4) {
671 pRow[0] = SHORT_TO_FLOAT(src[0]);
672 pRow[1] =
673 pRow[2] = 0.0;
674 pRow[3] = 1.0;
675 }
676 p += dst_stride;
677 }
678 }
679
680
681 static void
682 r16_put_tile_rgba(short *dst,
683 unsigned w, unsigned h,
684 const float *p,
685 unsigned src_stride)
686 {
687 unsigned i, j;
688
689 for (i = 0; i < h; i++) {
690 const float *pRow = p;
691 for (j = 0; j < w; j++, dst++, pRow += 4) {
692 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
693 }
694 p += src_stride;
695 }
696 }
697
698
699 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
700
701 static void
702 r16g16b16a16_get_tile_rgba(const short *src,
703 unsigned w, unsigned h,
704 float *p,
705 unsigned dst_stride)
706 {
707 unsigned i, j;
708
709 for (i = 0; i < h; i++) {
710 float *pRow = p;
711 for (j = 0; j < w; j++, src += 4, pRow += 4) {
712 pRow[0] = SHORT_TO_FLOAT(src[0]);
713 pRow[1] = SHORT_TO_FLOAT(src[1]);
714 pRow[2] = SHORT_TO_FLOAT(src[2]);
715 pRow[3] = SHORT_TO_FLOAT(src[3]);
716 }
717 p += dst_stride;
718 }
719 }
720
721
722 static void
723 r16g16b16a16_put_tile_rgba(short *dst,
724 unsigned w, unsigned h,
725 const float *p,
726 unsigned src_stride)
727 {
728 unsigned i, j;
729
730 for (i = 0; i < h; i++) {
731 const float *pRow = p;
732 for (j = 0; j < w; j++, dst += 4, pRow += 4) {
733 UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
734 UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
735 UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
736 UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
737 }
738 p += src_stride;
739 }
740 }
741
742
743 /*** PIPE_FORMAT_A8B8G8R8_SRGB ***/
744
745 /**
746 * Convert an 8-bit sRGB value from non-linear space to a
747 * linear RGB value in [0, 1].
748 * Implemented with a 256-entry lookup table.
749 */
750 static INLINE float
751 srgb_to_linear(ubyte cs8)
752 {
753 static float table[256];
754 static boolean tableReady = FALSE;
755 if (!tableReady) {
756 /* compute lookup table now */
757 uint i;
758 for (i = 0; i < 256; i++) {
759 const float cs = ubyte_to_float(i);
760 if (cs <= 0.04045) {
761 table[i] = cs / 12.92f;
762 }
763 else {
764 table[i] = (float) powf((cs + 0.055) / 1.055, 2.4);
765 }
766 }
767 tableReady = TRUE;
768 }
769 return table[cs8];
770 }
771
772
773 /**
774 * Convert linear float in [0,1] to an srgb ubyte value in [0,255].
775 * XXX this hasn't been tested (render to srgb surface).
776 * XXX this needs optimization.
777 */
778 static INLINE ubyte
779 linear_to_srgb(float cl)
780 {
781 if (cl >= 1.0F)
782 return 255;
783 else if (cl >= 0.0031308F)
784 return float_to_ubyte(1.055F * powf(cl, 0.41666F) - 0.055F);
785 else if (cl > 0.0F)
786 return float_to_ubyte(12.92F * cl);
787 else
788 return 0.0;
789 }
790
791
792 static void
793 a8r8g8b8_srgb_get_tile_rgba(const unsigned *src,
794 unsigned w, unsigned h,
795 float *p,
796 unsigned dst_stride)
797 {
798 unsigned i, j;
799
800 for (i = 0; i < h; i++) {
801 float *pRow = p;
802 for (j = 0; j < w; j++, pRow += 4) {
803 const unsigned pixel = *src++;
804 pRow[0] = srgb_to_linear((pixel >> 16) & 0xff);
805 pRow[1] = srgb_to_linear((pixel >> 8) & 0xff);
806 pRow[2] = srgb_to_linear((pixel >> 0) & 0xff);
807 pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
808 }
809 p += dst_stride;
810 }
811 }
812
813 static void
814 a8r8g8b8_srgb_put_tile_rgba(unsigned *dst,
815 unsigned w, unsigned h,
816 const float *p,
817 unsigned src_stride)
818 {
819 unsigned i, j;
820
821 for (i = 0; i < h; i++) {
822 const float *pRow = p;
823 for (j = 0; j < w; j++, pRow += 4) {
824 unsigned r, g, b, a;
825 r = linear_to_srgb(pRow[0]);
826 g = linear_to_srgb(pRow[1]);
827 b = linear_to_srgb(pRow[2]);
828 a = float_to_ubyte(pRow[3]);
829 *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
830 }
831 p += src_stride;
832 }
833 }
834
835
836 /*** PIPE_FORMAT_L8A8_SRGB ***/
837
838 static void
839 a8l8_srgb_get_tile_rgba(const ushort *src,
840 unsigned w, unsigned h,
841 float *p,
842 unsigned dst_stride)
843 {
844 unsigned i, j;
845
846 for (i = 0; i < h; i++) {
847 float *pRow = p;
848 for (j = 0; j < w; j++, pRow += 4) {
849 ushort p = *src++;
850 pRow[0] =
851 pRow[1] =
852 pRow[2] = srgb_to_linear(p & 0xff);
853 pRow[3] = ubyte_to_float(p >> 8);
854 }
855 p += dst_stride;
856 }
857 }
858
859 static void
860 a8l8_srgb_put_tile_rgba(ushort *dst,
861 unsigned w, unsigned h,
862 const float *p,
863 unsigned src_stride)
864 {
865 unsigned i, j;
866
867 for (i = 0; i < h; i++) {
868 const float *pRow = p;
869 for (j = 0; j < w; j++, pRow += 4) {
870 unsigned r, a;
871 r = linear_to_srgb(pRow[0]);
872 a = float_to_ubyte(pRow[3]);
873 *dst++ = (a << 8) | r;
874 }
875 p += src_stride;
876 }
877 }
878
879
880 /*** PIPE_FORMAT_L8_SRGB ***/
881
882 static void
883 l8_srgb_get_tile_rgba(const ubyte *src,
884 unsigned w, unsigned h,
885 float *p,
886 unsigned dst_stride)
887 {
888 unsigned i, j;
889
890 for (i = 0; i < h; i++) {
891 float *pRow = p;
892 for (j = 0; j < w; j++, src++, pRow += 4) {
893 pRow[0] =
894 pRow[1] =
895 pRow[2] = srgb_to_linear(*src);
896 pRow[3] = 1.0;
897 }
898 p += dst_stride;
899 }
900 }
901
902 static void
903 l8_srgb_put_tile_rgba(ubyte *dst,
904 unsigned w, unsigned h,
905 const float *p,
906 unsigned src_stride)
907 {
908 unsigned i, j;
909
910 for (i = 0; i < h; i++) {
911 const float *pRow = p;
912 for (j = 0; j < w; j++, pRow += 4) {
913 unsigned r;
914 r = linear_to_srgb(pRow[0]);
915 *dst++ = (ubyte) r;
916 }
917 p += src_stride;
918 }
919 }
920
921
922 /*** PIPE_FORMAT_I8_UNORM ***/
923
924 static void
925 i8_get_tile_rgba(const ubyte *src,
926 unsigned w, unsigned h,
927 float *p,
928 unsigned dst_stride)
929 {
930 unsigned i, j;
931
932 for (i = 0; i < h; i++) {
933 float *pRow = p;
934 for (j = 0; j < w; j++, src++, pRow += 4) {
935 pRow[0] =
936 pRow[1] =
937 pRow[2] =
938 pRow[3] = ubyte_to_float(*src);
939 }
940 p += dst_stride;
941 }
942 }
943
944
945 static void
946 i8_put_tile_rgba(ubyte *dst,
947 unsigned w, unsigned h,
948 const float *p,
949 unsigned src_stride)
950 {
951 unsigned i, j;
952
953 for (i = 0; i < h; i++) {
954 const float *pRow = p;
955 for (j = 0; j < w; j++, pRow += 4) {
956 unsigned r;
957 r = float_to_ubyte(pRow[0]);
958 *dst++ = (ubyte) r;
959 }
960 p += src_stride;
961 }
962 }
963
964
965 /*** PIPE_FORMAT_L8A8_UNORM ***/
966
967 static void
968 a8l8_get_tile_rgba(const ushort *src,
969 unsigned w, unsigned h,
970 float *p,
971 unsigned dst_stride)
972 {
973 unsigned i, j;
974
975 for (i = 0; i < h; i++) {
976 float *pRow = p;
977 for (j = 0; j < w; j++, pRow += 4) {
978 ushort p = *src++;
979 pRow[0] =
980 pRow[1] =
981 pRow[2] = ubyte_to_float(p & 0xff);
982 pRow[3] = ubyte_to_float(p >> 8);
983 }
984 p += dst_stride;
985 }
986 }
987
988
989 static void
990 a8l8_put_tile_rgba(ushort *dst,
991 unsigned w, unsigned h,
992 const float *p,
993 unsigned src_stride)
994 {
995 unsigned i, j;
996
997 for (i = 0; i < h; i++) {
998 const float *pRow = p;
999 for (j = 0; j < w; j++, pRow += 4) {
1000 unsigned r, a;
1001 r = float_to_ubyte(pRow[0]);
1002 a = float_to_ubyte(pRow[3]);
1003 *dst++ = (a << 8) | r;
1004 }
1005 p += src_stride;
1006 }
1007 }
1008
1009
1010
1011
1012 /*** PIPE_FORMAT_Z32_UNORM ***/
1013
1014 /**
1015 * Return each Z value as four floats in [0,1].
1016 */
1017 static void
1018 z32_get_tile_rgba(const unsigned *src,
1019 unsigned w, unsigned h,
1020 float *p,
1021 unsigned dst_stride)
1022 {
1023 const double scale = 1.0 / (double) 0xffffffff;
1024 unsigned i, j;
1025
1026 for (i = 0; i < h; i++) {
1027 float *pRow = p;
1028 for (j = 0; j < w; j++, pRow += 4) {
1029 pRow[0] =
1030 pRow[1] =
1031 pRow[2] =
1032 pRow[3] = (float) (*src++ * scale);
1033 }
1034 p += dst_stride;
1035 }
1036 }
1037
1038
1039 /*** PIPE_FORMAT_Z24S8_UNORM ***/
1040
1041 /**
1042 * Return Z component as four float in [0,1]. Stencil part ignored.
1043 */
1044 static void
1045 s8z24_get_tile_rgba(const unsigned *src,
1046 unsigned w, unsigned h,
1047 float *p,
1048 unsigned dst_stride)
1049 {
1050 const double scale = 1.0 / ((1 << 24) - 1);
1051 unsigned i, j;
1052
1053 for (i = 0; i < h; i++) {
1054 float *pRow = p;
1055 for (j = 0; j < w; j++, pRow += 4) {
1056 pRow[0] =
1057 pRow[1] =
1058 pRow[2] =
1059 pRow[3] = (float) (scale * (*src++ & 0xffffff));
1060 }
1061 p += dst_stride;
1062 }
1063 }
1064
1065
1066 /*** PIPE_FORMAT_S8Z24_UNORM ***/
1067
1068 /**
1069 * Return Z component as four float in [0,1]. Stencil part ignored.
1070 */
1071 static void
1072 z24s8_get_tile_rgba(const unsigned *src,
1073 unsigned w, unsigned h,
1074 float *p,
1075 unsigned dst_stride)
1076 {
1077 const double scale = 1.0 / ((1 << 24) - 1);
1078 unsigned i, j;
1079
1080 for (i = 0; i < h; i++) {
1081 float *pRow = p;
1082 for (j = 0; j < w; j++, pRow += 4) {
1083 pRow[0] =
1084 pRow[1] =
1085 pRow[2] =
1086 pRow[3] = (float) (scale * (*src++ >> 8));
1087 }
1088 p += dst_stride;
1089 }
1090 }
1091
1092
1093 /*** PIPE_FORMAT_Z32_FLOAT ***/
1094
1095 /**
1096 * Return each Z value as four floats in [0,1].
1097 */
1098 static void
1099 z32f_get_tile_rgba(const float *src,
1100 unsigned w, unsigned h,
1101 float *p,
1102 unsigned dst_stride)
1103 {
1104 unsigned i, j;
1105
1106 for (i = 0; i < h; i++) {
1107 float *pRow = p;
1108 for (j = 0; j < w; j++, pRow += 4) {
1109 pRow[0] =
1110 pRow[1] =
1111 pRow[2] =
1112 pRow[3] = *src++;
1113 }
1114 p += dst_stride;
1115 }
1116 }
1117
1118
1119 /*** PIPE_FORMAT_UYVY / PIPE_FORMAT_YUYV ***/
1120
1121 /**
1122 * Convert YCbCr (or YCrCb) to RGBA.
1123 */
1124 static void
1125 ycbcr_get_tile_rgba(const ushort *src,
1126 unsigned w, unsigned h,
1127 float *p,
1128 unsigned dst_stride,
1129 boolean rev)
1130 {
1131 const float scale = 1.0f / 255.0f;
1132 unsigned i, j;
1133
1134 for (i = 0; i < h; i++) {
1135 float *pRow = p;
1136 /* do two texels at a time */
1137 for (j = 0; j < (w & ~1); j += 2, src += 2) {
1138 const ushort t0 = src[0];
1139 const ushort t1 = src[1];
1140 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
1141 const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */
1142 ubyte cb, cr;
1143 float r, g, b;
1144
1145 if (rev) {
1146 cb = t1 & 0xff; /* chroma U */
1147 cr = t0 & 0xff; /* chroma V */
1148 }
1149 else {
1150 cb = t0 & 0xff; /* chroma U */
1151 cr = t1 & 0xff; /* chroma V */
1152 }
1153
1154 /* even pixel: y0,cr,cb */
1155 r = 1.164f * (y0-16) + 1.596f * (cr-128);
1156 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1157 b = 1.164f * (y0-16) + 2.018f * (cb-128);
1158 pRow[0] = r * scale;
1159 pRow[1] = g * scale;
1160 pRow[2] = b * scale;
1161 pRow[3] = 1.0f;
1162 pRow += 4;
1163
1164 /* odd pixel: use y1,cr,cb */
1165 r = 1.164f * (y1-16) + 1.596f * (cr-128);
1166 g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1167 b = 1.164f * (y1-16) + 2.018f * (cb-128);
1168 pRow[0] = r * scale;
1169 pRow[1] = g * scale;
1170 pRow[2] = b * scale;
1171 pRow[3] = 1.0f;
1172 pRow += 4;
1173
1174 }
1175 /* do the last texel */
1176 if (w & 1) {
1177 const ushort t0 = src[0];
1178 const ushort t1 = src[1];
1179 const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
1180 ubyte cb, cr;
1181 float r, g, b;
1182
1183 if (rev) {
1184 cb = t1 & 0xff; /* chroma U */
1185 cr = t0 & 0xff; /* chroma V */
1186 }
1187 else {
1188 cb = t0 & 0xff; /* chroma U */
1189 cr = t1 & 0xff; /* chroma V */
1190 }
1191
1192 /* even pixel: y0,cr,cb */
1193 r = 1.164f * (y0-16) + 1.596f * (cr-128);
1194 g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
1195 b = 1.164f * (y0-16) + 2.018f * (cb-128);
1196 pRow[0] = r * scale;
1197 pRow[1] = g * scale;
1198 pRow[2] = b * scale;
1199 pRow[3] = 1.0f;
1200 pRow += 4;
1201 }
1202 p += dst_stride;
1203 }
1204 }
1205
1206
1207 void
1208 pipe_tile_raw_to_rgba(enum pipe_format format,
1209 void *src,
1210 uint w, uint h,
1211 float *dst, unsigned dst_stride)
1212 {
1213 switch (format) {
1214 case PIPE_FORMAT_B8G8R8A8_UNORM:
1215 a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1216 break;
1217 case PIPE_FORMAT_B8G8R8X8_UNORM:
1218 x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1219 break;
1220 case PIPE_FORMAT_A8R8G8B8_UNORM:
1221 b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1222 break;
1223 case PIPE_FORMAT_A8B8G8R8_UNORM:
1224 r8g8b8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1225 break;
1226 case PIPE_FORMAT_B5G5R5X1_UNORM:
1227 x1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1228 break;
1229 case PIPE_FORMAT_B5G5R5A1_UNORM:
1230 a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1231 break;
1232 case PIPE_FORMAT_B4G4R4A4_UNORM:
1233 a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1234 break;
1235 case PIPE_FORMAT_B5G6R5_UNORM:
1236 r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1237 break;
1238 case PIPE_FORMAT_R8G8B8_UNORM:
1239 r8g8b8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1240 break;
1241 case PIPE_FORMAT_L8_UNORM:
1242 l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1243 break;
1244 case PIPE_FORMAT_A8_UNORM:
1245 a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1246 break;
1247 case PIPE_FORMAT_I8_UNORM:
1248 i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1249 break;
1250 case PIPE_FORMAT_L8A8_UNORM:
1251 a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1252 break;
1253 case PIPE_FORMAT_R16_SNORM:
1254 r16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
1255 break;
1256 case PIPE_FORMAT_R16G16B16A16_SNORM:
1257 r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
1258 break;
1259 case PIPE_FORMAT_B8G8R8A8_SRGB:
1260 a8r8g8b8_srgb_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1261 break;
1262 case PIPE_FORMAT_L8A8_SRGB:
1263 a8l8_srgb_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1264 break;
1265 case PIPE_FORMAT_L8_SRGB:
1266 l8_srgb_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
1267 break;
1268 case PIPE_FORMAT_Z16_UNORM:
1269 z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
1270 break;
1271 case PIPE_FORMAT_Z32_UNORM:
1272 z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1273 break;
1274 case PIPE_FORMAT_Z24S8_UNORM:
1275 case PIPE_FORMAT_Z24X8_UNORM:
1276 s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1277 break;
1278 case PIPE_FORMAT_S8Z24_UNORM:
1279 case PIPE_FORMAT_X8Z24_UNORM:
1280 z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
1281 break;
1282 case PIPE_FORMAT_Z32_FLOAT:
1283 z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
1284 break;
1285 case PIPE_FORMAT_UYVY:
1286 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE);
1287 break;
1288 case PIPE_FORMAT_YUYV:
1289 ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
1290 break;
1291 default:
1292 util_format_read_4f(format,
1293 dst, dst_stride * sizeof(float),
1294 src, util_format_get_stride(format, w),
1295 0, 0, w, h);
1296 }
1297 }
1298
1299
1300 void
1301 pipe_get_tile_rgba(struct pipe_context *pipe,
1302 struct pipe_transfer *pt,
1303 uint x, uint y, uint w, uint h,
1304 float *p)
1305 {
1306 unsigned dst_stride = w * 4;
1307 void *packed;
1308 enum pipe_format format = pt->texture->format;
1309
1310 if (pipe_clip_tile(x, y, &w, &h, pt))
1311 return;
1312
1313 packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
1314
1315 if (!packed)
1316 return;
1317
1318 if(format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV)
1319 assert((x & 1) == 0);
1320
1321 pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
1322
1323 pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
1324
1325 FREE(packed);
1326 }
1327
1328
1329 void
1330 pipe_get_tile_swizzle(struct pipe_context *pipe,
1331 struct pipe_transfer *pt,
1332 uint x,
1333 uint y,
1334 uint w,
1335 uint h,
1336 uint swizzle_r,
1337 uint swizzle_g,
1338 uint swizzle_b,
1339 uint swizzle_a,
1340 enum pipe_format format,
1341 float *p)
1342 {
1343 unsigned dst_stride = w * 4;
1344 void *packed;
1345 uint i;
1346 float rgba01[6];
1347
1348 if (pipe_clip_tile(x, y, &w, &h, pt)) {
1349 return;
1350 }
1351
1352 packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
1353 if (!packed) {
1354 return;
1355 }
1356
1357 if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
1358 assert((x & 1) == 0);
1359 }
1360
1361 pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
1362
1363 pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
1364
1365 FREE(packed);
1366
1367 if (swizzle_r == PIPE_SWIZZLE_RED &&
1368 swizzle_g == PIPE_SWIZZLE_GREEN &&
1369 swizzle_b == PIPE_SWIZZLE_BLUE &&
1370 swizzle_a == PIPE_SWIZZLE_ALPHA) {
1371 /* no-op, skip */
1372 return;
1373 }
1374
1375 rgba01[PIPE_SWIZZLE_ZERO] = 0.0f;
1376 rgba01[PIPE_SWIZZLE_ONE] = 1.0f;
1377
1378 for (i = 0; i < w * h; i++) {
1379 rgba01[PIPE_SWIZZLE_RED] = p[0];
1380 rgba01[PIPE_SWIZZLE_GREEN] = p[1];
1381 rgba01[PIPE_SWIZZLE_BLUE] = p[2];
1382 rgba01[PIPE_SWIZZLE_ALPHA] = p[3];
1383
1384 *p++ = rgba01[swizzle_r];
1385 *p++ = rgba01[swizzle_g];
1386 *p++ = rgba01[swizzle_b];
1387 *p++ = rgba01[swizzle_a];
1388 }
1389 }
1390
1391
1392 void
1393 pipe_put_tile_rgba(struct pipe_context *pipe,
1394 struct pipe_transfer *pt,
1395 uint x, uint y, uint w, uint h,
1396 const float *p)
1397 {
1398 unsigned src_stride = w * 4;
1399 void *packed;
1400 enum pipe_format format = pt->texture->format;
1401
1402 if (pipe_clip_tile(x, y, &w, &h, pt))
1403 return;
1404
1405 packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
1406
1407 if (!packed)
1408 return;
1409
1410 switch (format) {
1411 case PIPE_FORMAT_B8G8R8A8_UNORM:
1412 a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1413 break;
1414 case PIPE_FORMAT_B8G8R8X8_UNORM:
1415 x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1416 break;
1417 case PIPE_FORMAT_A8R8G8B8_UNORM:
1418 b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1419 break;
1420 case PIPE_FORMAT_A8B8G8R8_UNORM:
1421 r8g8b8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1422 break;
1423 case PIPE_FORMAT_B5G5R5X1_UNORM:
1424 x1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1425 break;
1426 case PIPE_FORMAT_B5G5R5A1_UNORM:
1427 a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1428 break;
1429 case PIPE_FORMAT_B5G6R5_UNORM:
1430 r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1431 break;
1432 case PIPE_FORMAT_R8G8B8_UNORM:
1433 r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1434 break;
1435 case PIPE_FORMAT_B4G4R4A4_UNORM:
1436 a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1437 break;
1438 case PIPE_FORMAT_L8_UNORM:
1439 l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1440 break;
1441 case PIPE_FORMAT_A8_UNORM:
1442 a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1443 break;
1444 case PIPE_FORMAT_I8_UNORM:
1445 i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1446 break;
1447 case PIPE_FORMAT_L8A8_UNORM:
1448 a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1449 break;
1450 case PIPE_FORMAT_R16_SNORM:
1451 r16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1452 break;
1453 case PIPE_FORMAT_R16G16B16A16_SNORM:
1454 r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
1455 break;
1456 case PIPE_FORMAT_B8G8R8A8_SRGB:
1457 a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
1458 break;
1459 case PIPE_FORMAT_L8A8_SRGB:
1460 a8l8_srgb_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
1461 break;
1462 case PIPE_FORMAT_L8_SRGB:
1463 l8_srgb_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
1464 break;
1465 case PIPE_FORMAT_Z16_UNORM:
1466 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
1467 break;
1468 case PIPE_FORMAT_Z32_UNORM:
1469 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1470 break;
1471 case PIPE_FORMAT_Z24S8_UNORM:
1472 case PIPE_FORMAT_Z24X8_UNORM:
1473 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1474 break;
1475 case PIPE_FORMAT_S8Z24_UNORM:
1476 case PIPE_FORMAT_X8Z24_UNORM:
1477 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1478 break;
1479 default:
1480 util_format_write_4f(format,
1481 p, src_stride * sizeof(float),
1482 packed, util_format_get_stride(format, w),
1483 0, 0, w, h);
1484 }
1485
1486 pipe_put_tile_raw(pipe, pt, x, y, w, h, packed, 0);
1487
1488 FREE(packed);
1489 }
1490
1491
1492 /**
1493 * Get a block of Z values, converted to 32-bit range.
1494 */
1495 void
1496 pipe_get_tile_z(struct pipe_context *pipe,
1497 struct pipe_transfer *pt,
1498 uint x, uint y, uint w, uint h,
1499 uint *z)
1500 {
1501 const uint dstStride = w;
1502 ubyte *map;
1503 uint *pDest = z;
1504 uint i, j;
1505 enum pipe_format format = pt->texture->format;
1506
1507 if (pipe_clip_tile(x, y, &w, &h, pt))
1508 return;
1509
1510 map = (ubyte *)pipe->transfer_map(pipe, pt);
1511 if (!map) {
1512 assert(0);
1513 return;
1514 }
1515
1516 switch (format) {
1517 case PIPE_FORMAT_Z32_UNORM:
1518 {
1519 const uint *ptrc
1520 = (const uint *)(map + y * pt->stride + x*4);
1521 for (i = 0; i < h; i++) {
1522 memcpy(pDest, ptrc, 4 * w);
1523 pDest += dstStride;
1524 ptrc += pt->stride/4;
1525 }
1526 }
1527 break;
1528 case PIPE_FORMAT_Z24S8_UNORM:
1529 case PIPE_FORMAT_Z24X8_UNORM:
1530 {
1531 const uint *ptrc
1532 = (const uint *)(map + y * pt->stride + x*4);
1533 for (i = 0; i < h; i++) {
1534 for (j = 0; j < w; j++) {
1535 /* convert 24-bit Z to 32-bit Z */
1536 pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff);
1537 }
1538 pDest += dstStride;
1539 ptrc += pt->stride/4;
1540 }
1541 }
1542 break;
1543 case PIPE_FORMAT_S8Z24_UNORM:
1544 case PIPE_FORMAT_X8Z24_UNORM:
1545 {
1546 const uint *ptrc
1547 = (const uint *)(map + y * pt->stride + x*4);
1548 for (i = 0; i < h; i++) {
1549 for (j = 0; j < w; j++) {
1550 /* convert 24-bit Z to 32-bit Z */
1551 pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff);
1552 }
1553 pDest += dstStride;
1554 ptrc += pt->stride/4;
1555 }
1556 }
1557 break;
1558 case PIPE_FORMAT_Z16_UNORM:
1559 {
1560 const ushort *ptrc
1561 = (const ushort *)(map + y * pt->stride + x*2);
1562 for (i = 0; i < h; i++) {
1563 for (j = 0; j < w; j++) {
1564 /* convert 16-bit Z to 32-bit Z */
1565 pDest[j] = (ptrc[j] << 16) | ptrc[j];
1566 }
1567 pDest += dstStride;
1568 ptrc += pt->stride/2;
1569 }
1570 }
1571 break;
1572 default:
1573 assert(0);
1574 }
1575
1576 pipe->transfer_unmap(pipe, pt);
1577 }
1578
1579
1580 void
1581 pipe_put_tile_z(struct pipe_context *pipe,
1582 struct pipe_transfer *pt,
1583 uint x, uint y, uint w, uint h,
1584 const uint *zSrc)
1585 {
1586 const uint srcStride = w;
1587 const uint *ptrc = zSrc;
1588 ubyte *map;
1589 uint i, j;
1590 enum pipe_format format = pt->texture->format;
1591
1592 if (pipe_clip_tile(x, y, &w, &h, pt))
1593 return;
1594
1595 map = (ubyte *)pipe->transfer_map(pipe, pt);
1596 if (!map) {
1597 assert(0);
1598 return;
1599 }
1600
1601 switch (format) {
1602 case PIPE_FORMAT_Z32_UNORM:
1603 {
1604 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1605 for (i = 0; i < h; i++) {
1606 memcpy(pDest, ptrc, 4 * w);
1607 pDest += pt->stride/4;
1608 ptrc += srcStride;
1609 }
1610 }
1611 break;
1612 case PIPE_FORMAT_Z24S8_UNORM:
1613 {
1614 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1615 assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
1616 for (i = 0; i < h; i++) {
1617 for (j = 0; j < w; j++) {
1618 /* convert 32-bit Z to 24-bit Z, preserve stencil */
1619 pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
1620 }
1621 pDest += pt->stride/4;
1622 ptrc += srcStride;
1623 }
1624 }
1625 break;
1626 case PIPE_FORMAT_Z24X8_UNORM:
1627 {
1628 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1629 for (i = 0; i < h; i++) {
1630 for (j = 0; j < w; j++) {
1631 /* convert 32-bit Z to 24-bit Z (0 stencil) */
1632 pDest[j] = ptrc[j] >> 8;
1633 }
1634 pDest += pt->stride/4;
1635 ptrc += srcStride;
1636 }
1637 }
1638 break;
1639 case PIPE_FORMAT_S8Z24_UNORM:
1640 {
1641 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1642 assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
1643 for (i = 0; i < h; i++) {
1644 for (j = 0; j < w; j++) {
1645 /* convert 32-bit Z to 24-bit Z, preserve stencil */
1646 pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
1647 }
1648 pDest += pt->stride/4;
1649 ptrc += srcStride;
1650 }
1651 }
1652 break;
1653 case PIPE_FORMAT_X8Z24_UNORM:
1654 {
1655 uint *pDest = (uint *) (map + y * pt->stride + x*4);
1656 for (i = 0; i < h; i++) {
1657 for (j = 0; j < w; j++) {
1658 /* convert 32-bit Z to 24-bit Z (0 stencil) */
1659 pDest[j] = ptrc[j] & 0xffffff00;
1660 }
1661 pDest += pt->stride/4;
1662 ptrc += srcStride;
1663 }
1664 }
1665 break;
1666 case PIPE_FORMAT_Z16_UNORM:
1667 {
1668 ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
1669 for (i = 0; i < h; i++) {
1670 for (j = 0; j < w; j++) {
1671 /* convert 32-bit Z to 16-bit Z */
1672 pDest[j] = ptrc[j] >> 16;
1673 }
1674 pDest += pt->stride/2;
1675 ptrc += srcStride;
1676 }
1677 }
1678 break;
1679 default:
1680 assert(0);
1681 }
1682
1683 pipe->transfer_unmap(pipe, pt);
1684 }
1685
1686