1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
29 * RGBA/float tile get/put functions.
30 * Usable both by drivers and state trackers.
34 #include "pipe/p_defines.h"
35 #include "util/u_inlines.h"
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"
45 * Move raw block of pixels from transfer object to user memory.
48 pipe_get_tile_raw(struct pipe_transfer
*pt
,
49 uint x
, uint y
, uint w
, uint h
,
50 void *dst
, int dst_stride
)
52 struct pipe_screen
*screen
= pt
->texture
->screen
;
56 dst_stride
= util_format_get_stride(pt
->texture
->format
, w
);
58 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
61 src
= screen
->transfer_map(screen
, pt
);
66 util_copy_rect(dst
, pt
->texture
->format
, dst_stride
, 0, 0, w
, h
, src
, pt
->stride
, x
, y
);
68 screen
->transfer_unmap(screen
, pt
);
73 * Move raw block of pixels from user memory to transfer object.
76 pipe_put_tile_raw(struct pipe_transfer
*pt
,
77 uint x
, uint y
, uint w
, uint h
,
78 const void *src
, int src_stride
)
80 struct pipe_screen
*screen
= pt
->texture
->screen
;
82 enum pipe_format format
= pt
->texture
->format
;
85 src_stride
= util_format_get_stride(format
, w
);
87 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
90 dst
= screen
->transfer_map(screen
, pt
);
95 util_copy_rect(dst
, format
, pt
->stride
, x
, y
, w
, h
, src
, src_stride
, 0, 0);
97 screen
->transfer_unmap(screen
, pt
);
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))
106 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
107 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
111 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
114 a8r8g8b8_get_tile_rgba(const unsigned *src
,
115 unsigned w
, unsigned h
,
121 for (i
= 0; i
< h
; i
++) {
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);
136 a8r8g8b8_put_tile_rgba(unsigned *dst
,
137 unsigned w
, unsigned h
,
143 for (i
= 0; i
< h
; i
++) {
144 const float *pRow
= p
;
145 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
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
;
158 /*** PIPE_FORMAT_B8G8R8X8_UNORM ***/
161 x8r8g8b8_get_tile_rgba(const unsigned *src
,
162 unsigned w
, unsigned h
,
168 for (i
= 0; i
< h
; i
++) {
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);
183 x8r8g8b8_put_tile_rgba(unsigned *dst
,
184 unsigned w
, unsigned h
,
190 for (i
= 0; i
< h
; i
++) {
191 const float *pRow
= p
;
192 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
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
;
204 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
207 b8g8r8a8_get_tile_rgba(const unsigned *src
,
208 unsigned w
, unsigned h
,
214 for (i
= 0; i
< h
; i
++) {
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);
229 b8g8r8a8_put_tile_rgba(unsigned *dst
,
230 unsigned w
, unsigned h
,
236 for (i
= 0; i
< h
; i
++) {
237 const float *pRow
= p
;
238 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
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
;
251 /*** PIPE_FORMAT_A8B8G8R8_UNORM ***/
254 r8g8b8a8_get_tile_rgba(const unsigned *src
,
255 unsigned w
, unsigned h
,
261 for (i
= 0; i
< h
; i
++) {
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);
276 r8g8b8a8_put_tile_rgba(unsigned *dst
,
277 unsigned w
, unsigned h
,
283 for (i
= 0; i
< h
; i
++) {
284 const float *pRow
= p
;
285 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
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
;
298 /*** PIPE_FORMAT_B5G5R5A1_UNORM ***/
301 a1r5g5b5_get_tile_rgba(const ushort
*src
,
302 unsigned w
, unsigned h
,
308 for (i
= 0; i
< h
; i
++) {
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] = ((pixel
>> 15) ) * 1.0f
;
323 a1r5g5b5_put_tile_rgba(ushort
*dst
,
324 unsigned w
, unsigned h
,
330 for (i
= 0; i
< h
; i
++) {
331 const float *pRow
= p
;
332 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
334 r
= float_to_ubyte(pRow
[0]);
335 g
= float_to_ubyte(pRow
[1]);
336 b
= float_to_ubyte(pRow
[2]);
337 a
= float_to_ubyte(pRow
[3]);
338 r
= r
>> 3; /* 5 bits */
339 g
= g
>> 3; /* 5 bits */
340 b
= b
>> 3; /* 5 bits */
341 a
= a
>> 7; /* 1 bit */
342 *dst
++ = (a
<< 15) | (r
<< 10) | (g
<< 5) | b
;
349 /*** PIPE_FORMAT_B4G4R4A4_UNORM ***/
352 a4r4g4b4_get_tile_rgba(const ushort
*src
,
353 unsigned w
, unsigned h
,
359 for (i
= 0; i
< h
; i
++) {
361 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
362 const ushort pixel
= *src
++;
363 pRow
[0] = ((pixel
>> 8) & 0xf) * (1.0f
/ 15.0f
);
364 pRow
[1] = ((pixel
>> 4) & 0xf) * (1.0f
/ 15.0f
);
365 pRow
[2] = ((pixel
) & 0xf) * (1.0f
/ 15.0f
);
366 pRow
[3] = ((pixel
>> 12) ) * (1.0f
/ 15.0f
);
374 a4r4g4b4_put_tile_rgba(ushort
*dst
,
375 unsigned w
, unsigned h
,
381 for (i
= 0; i
< h
; i
++) {
382 const float *pRow
= p
;
383 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
385 r
= float_to_ubyte(pRow
[0]);
386 g
= float_to_ubyte(pRow
[1]);
387 b
= float_to_ubyte(pRow
[2]);
388 a
= float_to_ubyte(pRow
[3]);
393 *dst
++ = (a
<< 12) | (r
<< 8) | (g
<< 4) | b
;
400 /*** PIPE_FORMAT_B5G6R5_UNORM ***/
403 r5g6b5_get_tile_rgba(const ushort
*src
,
404 unsigned w
, unsigned h
,
410 for (i
= 0; i
< h
; i
++) {
412 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
413 const ushort pixel
= *src
++;
414 pRow
[0] = ((pixel
>> 11) & 0x1f) * (1.0f
/ 31.0f
);
415 pRow
[1] = ((pixel
>> 5) & 0x3f) * (1.0f
/ 63.0f
);
416 pRow
[2] = ((pixel
) & 0x1f) * (1.0f
/ 31.0f
);
425 r5g6b5_put_tile_rgba(ushort
*dst
,
426 unsigned w
, unsigned h
,
432 for (i
= 0; i
< h
; i
++) {
433 const float *pRow
= p
;
434 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
435 uint r
= (uint
) (CLAMP(pRow
[0], 0.0, 1.0) * 31.0);
436 uint g
= (uint
) (CLAMP(pRow
[1], 0.0, 1.0) * 63.0);
437 uint b
= (uint
) (CLAMP(pRow
[2], 0.0, 1.0) * 31.0);
438 *dst
++ = (r
<< 11) | (g
<< 5) | (b
);
446 /*** PIPE_FORMAT_R8G8B8_UNORM ***/
449 r8g8b8_get_tile_rgba(const ubyte
*src
,
450 unsigned w
, unsigned h
,
456 for (i
= 0; i
< h
; i
++) {
458 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
459 pRow
[0] = ubyte_to_float(src
[0]);
460 pRow
[1] = ubyte_to_float(src
[1]);
461 pRow
[2] = ubyte_to_float(src
[2]);
471 r8g8b8_put_tile_rgba(ubyte
*dst
,
472 unsigned w
, unsigned h
,
478 for (i
= 0; i
< h
; i
++) {
479 const float *pRow
= p
;
480 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
481 dst
[0] = float_to_ubyte(pRow
[0]);
482 dst
[1] = float_to_ubyte(pRow
[1]);
483 dst
[2] = float_to_ubyte(pRow
[2]);
492 /*** PIPE_FORMAT_Z16_UNORM ***/
495 * Return each Z value as four floats in [0,1].
498 z16_get_tile_rgba(const ushort
*src
,
499 unsigned w
, unsigned h
,
503 const float scale
= 1.0f
/ 65535.0f
;
506 for (i
= 0; i
< h
; i
++) {
508 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
512 pRow
[3] = *src
++ * scale
;
521 /*** PIPE_FORMAT_L8_UNORM ***/
524 l8_get_tile_rgba(const ubyte
*src
,
525 unsigned w
, unsigned h
,
531 for (i
= 0; i
< h
; i
++) {
533 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
536 pRow
[2] = ubyte_to_float(*src
);
545 l8_put_tile_rgba(ubyte
*dst
,
546 unsigned w
, unsigned h
,
552 for (i
= 0; i
< h
; i
++) {
553 const float *pRow
= p
;
554 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
556 r
= float_to_ubyte(pRow
[0]);
565 /*** PIPE_FORMAT_A8_UNORM ***/
568 a8_get_tile_rgba(const ubyte
*src
,
569 unsigned w
, unsigned h
,
575 for (i
= 0; i
< h
; i
++) {
577 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
581 pRow
[3] = ubyte_to_float(*src
);
589 a8_put_tile_rgba(ubyte
*dst
,
590 unsigned w
, unsigned h
,
596 for (i
= 0; i
< h
; i
++) {
597 const float *pRow
= p
;
598 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
600 a
= float_to_ubyte(pRow
[3]);
609 /*** PIPE_FORMAT_R16_SNORM ***/
612 r16_get_tile_rgba(const short *src
,
613 unsigned w
, unsigned h
,
619 for (i
= 0; i
< h
; i
++) {
621 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
622 pRow
[0] = SHORT_TO_FLOAT(src
[0]);
633 r16_put_tile_rgba(short *dst
,
634 unsigned w
, unsigned h
,
640 for (i
= 0; i
< h
; i
++) {
641 const float *pRow
= p
;
642 for (j
= 0; j
< w
; j
++, dst
++, pRow
+= 4) {
643 UNCLAMPED_FLOAT_TO_SHORT(dst
[0], pRow
[0]);
650 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
653 r16g16b16a16_get_tile_rgba(const short *src
,
654 unsigned w
, unsigned h
,
660 for (i
= 0; i
< h
; i
++) {
662 for (j
= 0; j
< w
; j
++, src
+= 4, pRow
+= 4) {
663 pRow
[0] = SHORT_TO_FLOAT(src
[0]);
664 pRow
[1] = SHORT_TO_FLOAT(src
[1]);
665 pRow
[2] = SHORT_TO_FLOAT(src
[2]);
666 pRow
[3] = SHORT_TO_FLOAT(src
[3]);
674 r16g16b16a16_put_tile_rgba(short *dst
,
675 unsigned w
, unsigned h
,
681 for (i
= 0; i
< h
; i
++) {
682 const float *pRow
= p
;
683 for (j
= 0; j
< w
; j
++, dst
+= 4, pRow
+= 4) {
684 UNCLAMPED_FLOAT_TO_SHORT(dst
[0], pRow
[0]);
685 UNCLAMPED_FLOAT_TO_SHORT(dst
[1], pRow
[1]);
686 UNCLAMPED_FLOAT_TO_SHORT(dst
[2], pRow
[2]);
687 UNCLAMPED_FLOAT_TO_SHORT(dst
[3], pRow
[3]);
694 /*** PIPE_FORMAT_A8B8G8R8_SRGB ***/
697 * Convert an 8-bit sRGB value from non-linear space to a
698 * linear RGB value in [0, 1].
699 * Implemented with a 256-entry lookup table.
702 srgb_to_linear(ubyte cs8
)
704 static float table
[256];
705 static boolean tableReady
= FALSE
;
707 /* compute lookup table now */
709 for (i
= 0; i
< 256; i
++) {
710 const float cs
= ubyte_to_float(i
);
712 table
[i
] = cs
/ 12.92f
;
715 table
[i
] = (float) powf((cs
+ 0.055) / 1.055, 2.4);
725 * Convert linear float in [0,1] to an srgb ubyte value in [0,255].
726 * XXX this hasn't been tested (render to srgb surface).
727 * XXX this needs optimization.
730 linear_to_srgb(float cl
)
734 else if (cl
>= 0.0031308F
)
735 return float_to_ubyte(1.055F
* powf(cl
, 0.41666F
) - 0.055F
);
737 return float_to_ubyte(12.92F
* cl
);
744 a8r8g8b8_srgb_get_tile_rgba(const unsigned *src
,
745 unsigned w
, unsigned h
,
751 for (i
= 0; i
< h
; i
++) {
753 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
754 const unsigned pixel
= *src
++;
755 pRow
[0] = srgb_to_linear((pixel
>> 16) & 0xff);
756 pRow
[1] = srgb_to_linear((pixel
>> 8) & 0xff);
757 pRow
[2] = srgb_to_linear((pixel
>> 0) & 0xff);
758 pRow
[3] = ubyte_to_float((pixel
>> 24) & 0xff);
765 a8r8g8b8_srgb_put_tile_rgba(unsigned *dst
,
766 unsigned w
, unsigned h
,
772 for (i
= 0; i
< h
; i
++) {
773 const float *pRow
= p
;
774 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
776 r
= linear_to_srgb(pRow
[0]);
777 g
= linear_to_srgb(pRow
[1]);
778 b
= linear_to_srgb(pRow
[2]);
779 a
= float_to_ubyte(pRow
[3]);
780 *dst
++ = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
787 /*** PIPE_FORMAT_L8A8_SRGB ***/
790 a8l8_srgb_get_tile_rgba(const ushort
*src
,
791 unsigned w
, unsigned h
,
797 for (i
= 0; i
< h
; i
++) {
799 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
803 pRow
[2] = srgb_to_linear(p
& 0xff);
804 pRow
[3] = ubyte_to_float(p
>> 8);
811 a8l8_srgb_put_tile_rgba(ushort
*dst
,
812 unsigned w
, unsigned h
,
818 for (i
= 0; i
< h
; i
++) {
819 const float *pRow
= p
;
820 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
822 r
= linear_to_srgb(pRow
[0]);
823 a
= float_to_ubyte(pRow
[3]);
824 *dst
++ = (a
<< 8) | r
;
831 /*** PIPE_FORMAT_L8_SRGB ***/
834 l8_srgb_get_tile_rgba(const ubyte
*src
,
835 unsigned w
, unsigned h
,
841 for (i
= 0; i
< h
; i
++) {
843 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
846 pRow
[2] = srgb_to_linear(*src
);
854 l8_srgb_put_tile_rgba(ubyte
*dst
,
855 unsigned w
, unsigned h
,
861 for (i
= 0; i
< h
; i
++) {
862 const float *pRow
= p
;
863 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
865 r
= linear_to_srgb(pRow
[0]);
873 /*** PIPE_FORMAT_I8_UNORM ***/
876 i8_get_tile_rgba(const ubyte
*src
,
877 unsigned w
, unsigned h
,
883 for (i
= 0; i
< h
; i
++) {
885 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
889 pRow
[3] = ubyte_to_float(*src
);
897 i8_put_tile_rgba(ubyte
*dst
,
898 unsigned w
, unsigned h
,
904 for (i
= 0; i
< h
; i
++) {
905 const float *pRow
= p
;
906 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
908 r
= float_to_ubyte(pRow
[0]);
916 /*** PIPE_FORMAT_L8A8_UNORM ***/
919 a8l8_get_tile_rgba(const ushort
*src
,
920 unsigned w
, unsigned h
,
926 for (i
= 0; i
< h
; i
++) {
928 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
932 pRow
[2] = ubyte_to_float(p
& 0xff);
933 pRow
[3] = ubyte_to_float(p
>> 8);
941 a8l8_put_tile_rgba(ushort
*dst
,
942 unsigned w
, unsigned h
,
948 for (i
= 0; i
< h
; i
++) {
949 const float *pRow
= p
;
950 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
952 r
= float_to_ubyte(pRow
[0]);
953 a
= float_to_ubyte(pRow
[3]);
954 *dst
++ = (a
<< 8) | r
;
963 /*** PIPE_FORMAT_Z32_UNORM ***/
966 * Return each Z value as four floats in [0,1].
969 z32_get_tile_rgba(const unsigned *src
,
970 unsigned w
, unsigned h
,
974 const double scale
= 1.0 / (double) 0xffffffff;
977 for (i
= 0; i
< h
; i
++) {
979 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
983 pRow
[3] = (float) (*src
++ * scale
);
990 /*** PIPE_FORMAT_Z24S8_UNORM ***/
993 * Return Z component as four float in [0,1]. Stencil part ignored.
996 s8z24_get_tile_rgba(const unsigned *src
,
997 unsigned w
, unsigned h
,
1001 const double scale
= 1.0 / ((1 << 24) - 1);
1004 for (i
= 0; i
< h
; i
++) {
1006 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
1010 pRow
[3] = (float) (scale
* (*src
++ & 0xffffff));
1017 /*** PIPE_FORMAT_S8Z24_UNORM ***/
1020 * Return Z component as four float in [0,1]. Stencil part ignored.
1023 z24s8_get_tile_rgba(const unsigned *src
,
1024 unsigned w
, unsigned h
,
1026 unsigned dst_stride
)
1028 const double scale
= 1.0 / ((1 << 24) - 1);
1031 for (i
= 0; i
< h
; i
++) {
1033 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
1037 pRow
[3] = (float) (scale
* (*src
++ >> 8));
1044 /*** PIPE_FORMAT_Z32_FLOAT ***/
1047 * Return each Z value as four floats in [0,1].
1050 z32f_get_tile_rgba(const float *src
,
1051 unsigned w
, unsigned h
,
1053 unsigned dst_stride
)
1057 for (i
= 0; i
< h
; i
++) {
1059 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
1070 /*** PIPE_FORMAT_UYVY / PIPE_FORMAT_YUYV ***/
1073 * Convert YCbCr (or YCrCb) to RGBA.
1076 ycbcr_get_tile_rgba(const ushort
*src
,
1077 unsigned w
, unsigned h
,
1079 unsigned dst_stride
,
1082 const float scale
= 1.0f
/ 255.0f
;
1085 for (i
= 0; i
< h
; i
++) {
1087 /* do two texels at a time */
1088 for (j
= 0; j
< (w
& ~1); j
+= 2, src
+= 2) {
1089 const ushort t0
= src
[0];
1090 const ushort t1
= src
[1];
1091 const ubyte y0
= (t0
>> 8) & 0xff; /* luminance */
1092 const ubyte y1
= (t1
>> 8) & 0xff; /* luminance */
1097 cb
= t1
& 0xff; /* chroma U */
1098 cr
= t0
& 0xff; /* chroma V */
1101 cb
= t0
& 0xff; /* chroma U */
1102 cr
= t1
& 0xff; /* chroma V */
1105 /* even pixel: y0,cr,cb */
1106 r
= 1.164f
* (y0
-16) + 1.596f
* (cr
-128);
1107 g
= 1.164f
* (y0
-16) - 0.813f
* (cr
-128) - 0.391f
* (cb
-128);
1108 b
= 1.164f
* (y0
-16) + 2.018f
* (cb
-128);
1109 pRow
[0] = r
* scale
;
1110 pRow
[1] = g
* scale
;
1111 pRow
[2] = b
* scale
;
1115 /* odd pixel: use y1,cr,cb */
1116 r
= 1.164f
* (y1
-16) + 1.596f
* (cr
-128);
1117 g
= 1.164f
* (y1
-16) - 0.813f
* (cr
-128) - 0.391f
* (cb
-128);
1118 b
= 1.164f
* (y1
-16) + 2.018f
* (cb
-128);
1119 pRow
[0] = r
* scale
;
1120 pRow
[1] = g
* scale
;
1121 pRow
[2] = b
* scale
;
1126 /* do the last texel */
1128 const ushort t0
= src
[0];
1129 const ushort t1
= src
[1];
1130 const ubyte y0
= (t0
>> 8) & 0xff; /* luminance */
1135 cb
= t1
& 0xff; /* chroma U */
1136 cr
= t0
& 0xff; /* chroma V */
1139 cb
= t0
& 0xff; /* chroma U */
1140 cr
= t1
& 0xff; /* chroma V */
1143 /* even pixel: y0,cr,cb */
1144 r
= 1.164f
* (y0
-16) + 1.596f
* (cr
-128);
1145 g
= 1.164f
* (y0
-16) - 0.813f
* (cr
-128) - 0.391f
* (cb
-128);
1146 b
= 1.164f
* (y0
-16) + 2.018f
* (cb
-128);
1147 pRow
[0] = r
* scale
;
1148 pRow
[1] = g
* scale
;
1149 pRow
[2] = b
* scale
;
1159 pipe_tile_raw_to_rgba(enum pipe_format format
,
1162 float *dst
, unsigned dst_stride
)
1165 case PIPE_FORMAT_B8G8R8A8_UNORM
:
1166 a8r8g8b8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1168 case PIPE_FORMAT_B8G8R8X8_UNORM
:
1169 x8r8g8b8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1171 case PIPE_FORMAT_A8R8G8B8_UNORM
:
1172 b8g8r8a8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1174 case PIPE_FORMAT_A8B8G8R8_UNORM
:
1175 r8g8b8a8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1177 case PIPE_FORMAT_B5G5R5A1_UNORM
:
1178 a1r5g5b5_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1180 case PIPE_FORMAT_B4G4R4A4_UNORM
:
1181 a4r4g4b4_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1183 case PIPE_FORMAT_B5G6R5_UNORM
:
1184 r5g6b5_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1186 case PIPE_FORMAT_R8G8B8_UNORM
:
1187 r8g8b8_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1189 case PIPE_FORMAT_L8_UNORM
:
1190 l8_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1192 case PIPE_FORMAT_A8_UNORM
:
1193 a8_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1195 case PIPE_FORMAT_I8_UNORM
:
1196 i8_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1198 case PIPE_FORMAT_L8A8_UNORM
:
1199 a8l8_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1201 case PIPE_FORMAT_R16_SNORM
:
1202 r16_get_tile_rgba((short *) src
, w
, h
, dst
, dst_stride
);
1204 case PIPE_FORMAT_R16G16B16A16_SNORM
:
1205 r16g16b16a16_get_tile_rgba((short *) src
, w
, h
, dst
, dst_stride
);
1207 case PIPE_FORMAT_B8G8R8A8_SRGB
:
1208 a8r8g8b8_srgb_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1210 case PIPE_FORMAT_L8A8_SRGB
:
1211 a8l8_srgb_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1213 case PIPE_FORMAT_L8_SRGB
:
1214 l8_srgb_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1216 case PIPE_FORMAT_Z16_UNORM
:
1217 z16_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1219 case PIPE_FORMAT_Z32_UNORM
:
1220 z32_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1222 case PIPE_FORMAT_Z24S8_UNORM
:
1223 case PIPE_FORMAT_Z24X8_UNORM
:
1224 s8z24_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1226 case PIPE_FORMAT_S8Z24_UNORM
:
1227 case PIPE_FORMAT_X8Z24_UNORM
:
1228 z24s8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1230 case PIPE_FORMAT_Z32_FLOAT
:
1231 z32f_get_tile_rgba((float *) src
, w
, h
, dst
, dst_stride
);
1233 case PIPE_FORMAT_UYVY
:
1234 ycbcr_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
, FALSE
);
1236 case PIPE_FORMAT_YUYV
:
1237 ycbcr_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
, TRUE
);
1240 util_format_read_4f(format
,
1241 dst
, dst_stride
* sizeof(float),
1242 src
, util_format_get_stride(format
, w
),
1249 pipe_get_tile_rgba(struct pipe_transfer
*pt
,
1250 uint x
, uint y
, uint w
, uint h
,
1253 unsigned dst_stride
= w
* 4;
1255 enum pipe_format format
= pt
->texture
->format
;
1257 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
1260 packed
= MALLOC(util_format_get_nblocks(format
, w
, h
) * util_format_get_blocksize(format
));
1265 if(format
== PIPE_FORMAT_UYVY
|| format
== PIPE_FORMAT_YUYV
)
1266 assert((x
& 1) == 0);
1268 pipe_get_tile_raw(pt
, x
, y
, w
, h
, packed
, 0);
1270 pipe_tile_raw_to_rgba(format
, packed
, w
, h
, p
, dst_stride
);
1277 pipe_put_tile_rgba(struct pipe_transfer
*pt
,
1278 uint x
, uint y
, uint w
, uint h
,
1281 unsigned src_stride
= w
* 4;
1283 enum pipe_format format
= pt
->texture
->format
;
1285 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
1288 packed
= MALLOC(util_format_get_nblocks(format
, w
, h
) * util_format_get_blocksize(format
));
1294 case PIPE_FORMAT_B8G8R8A8_UNORM
:
1295 a8r8g8b8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1297 case PIPE_FORMAT_B8G8R8X8_UNORM
:
1298 x8r8g8b8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1300 case PIPE_FORMAT_A8R8G8B8_UNORM
:
1301 b8g8r8a8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1303 case PIPE_FORMAT_A8B8G8R8_UNORM
:
1304 r8g8b8a8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1306 case PIPE_FORMAT_B5G5R5A1_UNORM
:
1307 a1r5g5b5_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1309 case PIPE_FORMAT_B5G6R5_UNORM
:
1310 r5g6b5_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1312 case PIPE_FORMAT_R8G8B8_UNORM
:
1313 r8g8b8_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1315 case PIPE_FORMAT_B4G4R4A4_UNORM
:
1316 a4r4g4b4_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1318 case PIPE_FORMAT_L8_UNORM
:
1319 l8_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1321 case PIPE_FORMAT_A8_UNORM
:
1322 a8_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1324 case PIPE_FORMAT_I8_UNORM
:
1325 i8_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1327 case PIPE_FORMAT_L8A8_UNORM
:
1328 a8l8_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1330 case PIPE_FORMAT_R16_SNORM
:
1331 r16_put_tile_rgba((short *) packed
, w
, h
, p
, src_stride
);
1333 case PIPE_FORMAT_R16G16B16A16_SNORM
:
1334 r16g16b16a16_put_tile_rgba((short *) packed
, w
, h
, p
, src_stride
);
1336 case PIPE_FORMAT_B8G8R8A8_SRGB
:
1337 a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1339 case PIPE_FORMAT_L8A8_SRGB
:
1340 a8l8_srgb_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1342 case PIPE_FORMAT_L8_SRGB
:
1343 l8_srgb_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1345 case PIPE_FORMAT_Z16_UNORM
:
1346 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
1348 case PIPE_FORMAT_Z32_UNORM
:
1349 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1351 case PIPE_FORMAT_Z24S8_UNORM
:
1352 case PIPE_FORMAT_Z24X8_UNORM
:
1353 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1355 case PIPE_FORMAT_S8Z24_UNORM
:
1356 case PIPE_FORMAT_X8Z24_UNORM
:
1357 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1360 util_format_write_4f(format
,
1361 p
, src_stride
* sizeof(float),
1362 packed
, util_format_get_stride(format
, w
),
1366 pipe_put_tile_raw(pt
, x
, y
, w
, h
, packed
, 0);
1373 * Get a block of Z values, converted to 32-bit range.
1376 pipe_get_tile_z(struct pipe_transfer
*pt
,
1377 uint x
, uint y
, uint w
, uint h
,
1380 struct pipe_screen
*screen
= pt
->texture
->screen
;
1381 const uint dstStride
= w
;
1385 enum pipe_format format
= pt
->texture
->format
;
1387 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
1390 map
= (ubyte
*)screen
->transfer_map(screen
, pt
);
1397 case PIPE_FORMAT_Z32_UNORM
:
1400 = (const uint
*)(map
+ y
* pt
->stride
+ x
*4);
1401 for (i
= 0; i
< h
; i
++) {
1402 memcpy(pDest
, ptrc
, 4 * w
);
1404 ptrc
+= pt
->stride
/4;
1408 case PIPE_FORMAT_Z24S8_UNORM
:
1409 case PIPE_FORMAT_Z24X8_UNORM
:
1412 = (const uint
*)(map
+ y
* pt
->stride
+ x
*4);
1413 for (i
= 0; i
< h
; i
++) {
1414 for (j
= 0; j
< w
; j
++) {
1415 /* convert 24-bit Z to 32-bit Z */
1416 pDest
[j
] = (ptrc
[j
] << 8) | ((ptrc
[j
] >> 16) & 0xff);
1419 ptrc
+= pt
->stride
/4;
1423 case PIPE_FORMAT_S8Z24_UNORM
:
1424 case PIPE_FORMAT_X8Z24_UNORM
:
1427 = (const uint
*)(map
+ y
* pt
->stride
+ x
*4);
1428 for (i
= 0; i
< h
; i
++) {
1429 for (j
= 0; j
< w
; j
++) {
1430 /* convert 24-bit Z to 32-bit Z */
1431 pDest
[j
] = (ptrc
[j
] & 0xffffff00) | ((ptrc
[j
] >> 24) & 0xff);
1434 ptrc
+= pt
->stride
/4;
1438 case PIPE_FORMAT_Z16_UNORM
:
1441 = (const ushort
*)(map
+ y
* pt
->stride
+ x
*2);
1442 for (i
= 0; i
< h
; i
++) {
1443 for (j
= 0; j
< w
; j
++) {
1444 /* convert 16-bit Z to 32-bit Z */
1445 pDest
[j
] = (ptrc
[j
] << 16) | ptrc
[j
];
1448 ptrc
+= pt
->stride
/2;
1456 screen
->transfer_unmap(screen
, pt
);
1461 pipe_put_tile_z(struct pipe_transfer
*pt
,
1462 uint x
, uint y
, uint w
, uint h
,
1465 struct pipe_screen
*screen
= pt
->texture
->screen
;
1466 const uint srcStride
= w
;
1467 const uint
*ptrc
= zSrc
;
1470 enum pipe_format format
= pt
->texture
->format
;
1472 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
1475 map
= (ubyte
*)screen
->transfer_map(screen
, pt
);
1482 case PIPE_FORMAT_Z32_UNORM
:
1484 uint
*pDest
= (uint
*) (map
+ y
* pt
->stride
+ x
*4);
1485 for (i
= 0; i
< h
; i
++) {
1486 memcpy(pDest
, ptrc
, 4 * w
);
1487 pDest
+= pt
->stride
/4;
1492 case PIPE_FORMAT_Z24S8_UNORM
:
1494 uint
*pDest
= (uint
*) (map
+ y
* pt
->stride
+ x
*4);
1495 assert((pt
->usage
& PIPE_TRANSFER_READ_WRITE
) == PIPE_TRANSFER_READ_WRITE
);
1496 for (i
= 0; i
< h
; i
++) {
1497 for (j
= 0; j
< w
; j
++) {
1498 /* convert 32-bit Z to 24-bit Z, preserve stencil */
1499 pDest
[j
] = (pDest
[j
] & 0xff000000) | ptrc
[j
] >> 8;
1501 pDest
+= pt
->stride
/4;
1506 case PIPE_FORMAT_Z24X8_UNORM
:
1508 uint
*pDest
= (uint
*) (map
+ y
* pt
->stride
+ x
*4);
1509 for (i
= 0; i
< h
; i
++) {
1510 for (j
= 0; j
< w
; j
++) {
1511 /* convert 32-bit Z to 24-bit Z (0 stencil) */
1512 pDest
[j
] = ptrc
[j
] >> 8;
1514 pDest
+= pt
->stride
/4;
1519 case PIPE_FORMAT_S8Z24_UNORM
:
1521 uint
*pDest
= (uint
*) (map
+ y
* pt
->stride
+ x
*4);
1522 assert((pt
->usage
& PIPE_TRANSFER_READ_WRITE
) == PIPE_TRANSFER_READ_WRITE
);
1523 for (i
= 0; i
< h
; i
++) {
1524 for (j
= 0; j
< w
; j
++) {
1525 /* convert 32-bit Z to 24-bit Z, preserve stencil */
1526 pDest
[j
] = (pDest
[j
] & 0xff) | (ptrc
[j
] & 0xffffff00);
1528 pDest
+= pt
->stride
/4;
1533 case PIPE_FORMAT_X8Z24_UNORM
:
1535 uint
*pDest
= (uint
*) (map
+ y
* pt
->stride
+ x
*4);
1536 for (i
= 0; i
< h
; i
++) {
1537 for (j
= 0; j
< w
; j
++) {
1538 /* convert 32-bit Z to 24-bit Z (0 stencil) */
1539 pDest
[j
] = ptrc
[j
] & 0xffffff00;
1541 pDest
+= pt
->stride
/4;
1546 case PIPE_FORMAT_Z16_UNORM
:
1548 ushort
*pDest
= (ushort
*) (map
+ y
* pt
->stride
+ x
*2);
1549 for (i
= 0; i
< h
; i
++) {
1550 for (j
= 0; j
< w
; j
++) {
1551 /* convert 32-bit Z to 16-bit Z */
1552 pDest
[j
] = ptrc
[j
] >> 16;
1554 pDest
+= pt
->stride
/2;
1563 screen
->transfer_unmap(screen
, pt
);