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_context
*pipe
,
49 struct pipe_transfer
*pt
,
50 uint x
, uint y
, uint w
, uint h
,
51 void *dst
, int dst_stride
)
56 dst_stride
= util_format_get_stride(pt
->texture
->format
, w
);
58 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
61 src
= pipe
->transfer_map(pipe
, pt
);
66 util_copy_rect(dst
, pt
->texture
->format
, dst_stride
, 0, 0, w
, h
, src
, pt
->stride
, x
, y
);
68 pipe
->transfer_unmap(pipe
, pt
);
73 * Move raw block of pixels from user memory to transfer object.
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
)
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
= pipe
->transfer_map(pipe
, pt
);
95 util_copy_rect(dst
, format
, pt
->stride
, x
, y
, w
, h
, src
, src_stride
, 0, 0);
97 pipe
->transfer_unmap(pipe
, 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_B5G5R5X1_UNORM ***/
301 x1r5g5b5_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
);
323 x1r5g5b5_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 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
;
347 /*** PIPE_FORMAT_B5G5R5A1_UNORM ***/
350 a1r5g5b5_get_tile_rgba(const ushort
*src
,
351 unsigned w
, unsigned h
,
357 for (i
= 0; i
< h
; i
++) {
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
;
372 a1r5g5b5_put_tile_rgba(ushort
*dst
,
373 unsigned w
, unsigned h
,
379 for (i
= 0; i
< h
; i
++) {
380 const float *pRow
= p
;
381 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
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
;
398 /*** PIPE_FORMAT_B4G4R4A4_UNORM ***/
401 a4r4g4b4_get_tile_rgba(const ushort
*src
,
402 unsigned w
, unsigned h
,
408 for (i
= 0; i
< h
; i
++) {
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
);
423 a4r4g4b4_put_tile_rgba(ushort
*dst
,
424 unsigned w
, unsigned h
,
430 for (i
= 0; i
< h
; i
++) {
431 const float *pRow
= p
;
432 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
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]);
442 *dst
++ = (a
<< 12) | (r
<< 8) | (g
<< 4) | b
;
449 /*** PIPE_FORMAT_B5G6R5_UNORM ***/
452 r5g6b5_get_tile_rgba(const ushort
*src
,
453 unsigned w
, unsigned h
,
459 for (i
= 0; i
< h
; i
++) {
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
);
474 r5g6b5_put_tile_rgba(ushort
*dst
,
475 unsigned w
, unsigned h
,
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
);
495 /*** PIPE_FORMAT_R8G8B8_UNORM ***/
498 r8g8b8_get_tile_rgba(const ubyte
*src
,
499 unsigned w
, unsigned h
,
505 for (i
= 0; i
< h
; i
++) {
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]);
520 r8g8b8_put_tile_rgba(ubyte
*dst
,
521 unsigned w
, unsigned h
,
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]);
541 /*** PIPE_FORMAT_Z16_UNORM ***/
544 * Return each Z value as four floats in [0,1].
547 z16_get_tile_rgba(const ushort
*src
,
548 unsigned w
, unsigned h
,
552 const float scale
= 1.0f
/ 65535.0f
;
555 for (i
= 0; i
< h
; i
++) {
557 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
561 pRow
[3] = *src
++ * scale
;
570 /*** PIPE_FORMAT_L8_UNORM ***/
573 l8_get_tile_rgba(const ubyte
*src
,
574 unsigned w
, unsigned h
,
580 for (i
= 0; i
< h
; i
++) {
582 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
585 pRow
[2] = ubyte_to_float(*src
);
594 l8_put_tile_rgba(ubyte
*dst
,
595 unsigned w
, unsigned h
,
601 for (i
= 0; i
< h
; i
++) {
602 const float *pRow
= p
;
603 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
605 r
= float_to_ubyte(pRow
[0]);
614 /*** PIPE_FORMAT_A8_UNORM ***/
617 a8_get_tile_rgba(const ubyte
*src
,
618 unsigned w
, unsigned h
,
624 for (i
= 0; i
< h
; i
++) {
626 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
630 pRow
[3] = ubyte_to_float(*src
);
638 a8_put_tile_rgba(ubyte
*dst
,
639 unsigned w
, unsigned h
,
645 for (i
= 0; i
< h
; i
++) {
646 const float *pRow
= p
;
647 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
649 a
= float_to_ubyte(pRow
[3]);
658 /*** PIPE_FORMAT_R16_SNORM ***/
661 r16_get_tile_rgba(const short *src
,
662 unsigned w
, unsigned h
,
668 for (i
= 0; i
< h
; i
++) {
670 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
671 pRow
[0] = SHORT_TO_FLOAT(src
[0]);
682 r16_put_tile_rgba(short *dst
,
683 unsigned w
, unsigned h
,
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]);
699 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
702 r16g16b16a16_get_tile_rgba(const short *src
,
703 unsigned w
, unsigned h
,
709 for (i
= 0; i
< h
; i
++) {
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]);
723 r16g16b16a16_put_tile_rgba(short *dst
,
724 unsigned w
, unsigned h
,
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]);
743 /*** PIPE_FORMAT_A8B8G8R8_SRGB ***/
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.
751 srgb_to_linear(ubyte cs8
)
753 static float table
[256];
754 static boolean tableReady
= FALSE
;
756 /* compute lookup table now */
758 for (i
= 0; i
< 256; i
++) {
759 const float cs
= ubyte_to_float(i
);
761 table
[i
] = cs
/ 12.92f
;
764 table
[i
] = (float) powf((cs
+ 0.055) / 1.055, 2.4);
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.
779 linear_to_srgb(float cl
)
783 else if (cl
>= 0.0031308F
)
784 return float_to_ubyte(1.055F
* powf(cl
, 0.41666F
) - 0.055F
);
786 return float_to_ubyte(12.92F
* cl
);
793 a8r8g8b8_srgb_get_tile_rgba(const unsigned *src
,
794 unsigned w
, unsigned h
,
800 for (i
= 0; i
< h
; i
++) {
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);
814 a8r8g8b8_srgb_put_tile_rgba(unsigned *dst
,
815 unsigned w
, unsigned h
,
821 for (i
= 0; i
< h
; i
++) {
822 const float *pRow
= p
;
823 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
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
;
836 /*** PIPE_FORMAT_L8A8_SRGB ***/
839 a8l8_srgb_get_tile_rgba(const ushort
*src
,
840 unsigned w
, unsigned h
,
846 for (i
= 0; i
< h
; i
++) {
848 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
852 pRow
[2] = srgb_to_linear(p
& 0xff);
853 pRow
[3] = ubyte_to_float(p
>> 8);
860 a8l8_srgb_put_tile_rgba(ushort
*dst
,
861 unsigned w
, unsigned h
,
867 for (i
= 0; i
< h
; i
++) {
868 const float *pRow
= p
;
869 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
871 r
= linear_to_srgb(pRow
[0]);
872 a
= float_to_ubyte(pRow
[3]);
873 *dst
++ = (a
<< 8) | r
;
880 /*** PIPE_FORMAT_L8_SRGB ***/
883 l8_srgb_get_tile_rgba(const ubyte
*src
,
884 unsigned w
, unsigned h
,
890 for (i
= 0; i
< h
; i
++) {
892 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
895 pRow
[2] = srgb_to_linear(*src
);
903 l8_srgb_put_tile_rgba(ubyte
*dst
,
904 unsigned w
, unsigned h
,
910 for (i
= 0; i
< h
; i
++) {
911 const float *pRow
= p
;
912 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
914 r
= linear_to_srgb(pRow
[0]);
922 /*** PIPE_FORMAT_I8_UNORM ***/
925 i8_get_tile_rgba(const ubyte
*src
,
926 unsigned w
, unsigned h
,
932 for (i
= 0; i
< h
; i
++) {
934 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
938 pRow
[3] = ubyte_to_float(*src
);
946 i8_put_tile_rgba(ubyte
*dst
,
947 unsigned w
, unsigned h
,
953 for (i
= 0; i
< h
; i
++) {
954 const float *pRow
= p
;
955 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
957 r
= float_to_ubyte(pRow
[0]);
965 /*** PIPE_FORMAT_L8A8_UNORM ***/
968 a8l8_get_tile_rgba(const ushort
*src
,
969 unsigned w
, unsigned h
,
975 for (i
= 0; i
< h
; i
++) {
977 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
981 pRow
[2] = ubyte_to_float(p
& 0xff);
982 pRow
[3] = ubyte_to_float(p
>> 8);
990 a8l8_put_tile_rgba(ushort
*dst
,
991 unsigned w
, unsigned h
,
997 for (i
= 0; i
< h
; i
++) {
998 const float *pRow
= p
;
999 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
1001 r
= float_to_ubyte(pRow
[0]);
1002 a
= float_to_ubyte(pRow
[3]);
1003 *dst
++ = (a
<< 8) | r
;
1012 /*** PIPE_FORMAT_Z32_UNORM ***/
1015 * Return each Z value as four floats in [0,1].
1018 z32_get_tile_rgba(const unsigned *src
,
1019 unsigned w
, unsigned h
,
1021 unsigned dst_stride
)
1023 const double scale
= 1.0 / (double) 0xffffffff;
1026 for (i
= 0; i
< h
; i
++) {
1028 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
1032 pRow
[3] = (float) (*src
++ * scale
);
1039 /*** PIPE_FORMAT_Z24S8_UNORM ***/
1042 * Return Z component as four float in [0,1]. Stencil part ignored.
1045 s8z24_get_tile_rgba(const unsigned *src
,
1046 unsigned w
, unsigned h
,
1048 unsigned dst_stride
)
1050 const double scale
= 1.0 / ((1 << 24) - 1);
1053 for (i
= 0; i
< h
; i
++) {
1055 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
1059 pRow
[3] = (float) (scale
* (*src
++ & 0xffffff));
1066 /*** PIPE_FORMAT_S8Z24_UNORM ***/
1069 * Return Z component as four float in [0,1]. Stencil part ignored.
1072 z24s8_get_tile_rgba(const unsigned *src
,
1073 unsigned w
, unsigned h
,
1075 unsigned dst_stride
)
1077 const double scale
= 1.0 / ((1 << 24) - 1);
1080 for (i
= 0; i
< h
; i
++) {
1082 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
1086 pRow
[3] = (float) (scale
* (*src
++ >> 8));
1093 /*** PIPE_FORMAT_Z32_FLOAT ***/
1096 * Return each Z value as four floats in [0,1].
1099 z32f_get_tile_rgba(const float *src
,
1100 unsigned w
, unsigned h
,
1102 unsigned dst_stride
)
1106 for (i
= 0; i
< h
; i
++) {
1108 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
1119 /*** PIPE_FORMAT_UYVY / PIPE_FORMAT_YUYV ***/
1122 * Convert YCbCr (or YCrCb) to RGBA.
1125 ycbcr_get_tile_rgba(const ushort
*src
,
1126 unsigned w
, unsigned h
,
1128 unsigned dst_stride
,
1131 const float scale
= 1.0f
/ 255.0f
;
1134 for (i
= 0; i
< h
; i
++) {
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 */
1146 cb
= t1
& 0xff; /* chroma U */
1147 cr
= t0
& 0xff; /* chroma V */
1150 cb
= t0
& 0xff; /* chroma U */
1151 cr
= t1
& 0xff; /* chroma V */
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
;
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
;
1175 /* do the last texel */
1177 const ushort t0
= src
[0];
1178 const ushort t1
= src
[1];
1179 const ubyte y0
= (t0
>> 8) & 0xff; /* luminance */
1184 cb
= t1
& 0xff; /* chroma U */
1185 cr
= t0
& 0xff; /* chroma V */
1188 cb
= t0
& 0xff; /* chroma U */
1189 cr
= t1
& 0xff; /* chroma V */
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
;
1208 pipe_tile_raw_to_rgba(enum pipe_format format
,
1211 float *dst
, unsigned dst_stride
)
1214 case PIPE_FORMAT_B8G8R8A8_UNORM
:
1215 a8r8g8b8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1217 case PIPE_FORMAT_B8G8R8X8_UNORM
:
1218 x8r8g8b8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1220 case PIPE_FORMAT_A8R8G8B8_UNORM
:
1221 b8g8r8a8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1223 case PIPE_FORMAT_A8B8G8R8_UNORM
:
1224 r8g8b8a8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1226 case PIPE_FORMAT_B5G5R5X1_UNORM
:
1227 x1r5g5b5_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1229 case PIPE_FORMAT_B5G5R5A1_UNORM
:
1230 a1r5g5b5_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1232 case PIPE_FORMAT_B4G4R4A4_UNORM
:
1233 a4r4g4b4_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1235 case PIPE_FORMAT_B5G6R5_UNORM
:
1236 r5g6b5_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1238 case PIPE_FORMAT_R8G8B8_UNORM
:
1239 r8g8b8_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1241 case PIPE_FORMAT_L8_UNORM
:
1242 l8_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1244 case PIPE_FORMAT_A8_UNORM
:
1245 a8_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1247 case PIPE_FORMAT_I8_UNORM
:
1248 i8_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1250 case PIPE_FORMAT_L8A8_UNORM
:
1251 a8l8_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1253 case PIPE_FORMAT_R16_SNORM
:
1254 r16_get_tile_rgba((short *) src
, w
, h
, dst
, dst_stride
);
1256 case PIPE_FORMAT_R16G16B16A16_SNORM
:
1257 r16g16b16a16_get_tile_rgba((short *) src
, w
, h
, dst
, dst_stride
);
1259 case PIPE_FORMAT_B8G8R8A8_SRGB
:
1260 a8r8g8b8_srgb_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1262 case PIPE_FORMAT_L8A8_SRGB
:
1263 a8l8_srgb_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1265 case PIPE_FORMAT_L8_SRGB
:
1266 l8_srgb_get_tile_rgba((ubyte
*) src
, w
, h
, dst
, dst_stride
);
1268 case PIPE_FORMAT_Z16_UNORM
:
1269 z16_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
);
1271 case PIPE_FORMAT_Z32_UNORM
:
1272 z32_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1274 case PIPE_FORMAT_Z24S8_UNORM
:
1275 case PIPE_FORMAT_Z24X8_UNORM
:
1276 s8z24_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1278 case PIPE_FORMAT_S8Z24_UNORM
:
1279 case PIPE_FORMAT_X8Z24_UNORM
:
1280 z24s8_get_tile_rgba((unsigned *) src
, w
, h
, dst
, dst_stride
);
1282 case PIPE_FORMAT_Z32_FLOAT
:
1283 z32f_get_tile_rgba((float *) src
, w
, h
, dst
, dst_stride
);
1285 case PIPE_FORMAT_UYVY
:
1286 ycbcr_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
, FALSE
);
1288 case PIPE_FORMAT_YUYV
:
1289 ycbcr_get_tile_rgba((ushort
*) src
, w
, h
, dst
, dst_stride
, TRUE
);
1292 util_format_read_4f(format
,
1293 dst
, dst_stride
* sizeof(float),
1294 src
, util_format_get_stride(format
, w
),
1301 pipe_get_tile_rgba(struct pipe_context
*pipe
,
1302 struct pipe_transfer
*pt
,
1303 uint x
, uint y
, uint w
, uint h
,
1306 unsigned dst_stride
= w
* 4;
1308 enum pipe_format format
= pt
->texture
->format
;
1310 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
1313 packed
= MALLOC(util_format_get_nblocks(format
, w
, h
) * util_format_get_blocksize(format
));
1318 if(format
== PIPE_FORMAT_UYVY
|| format
== PIPE_FORMAT_YUYV
)
1319 assert((x
& 1) == 0);
1321 pipe_get_tile_raw(pipe
, pt
, x
, y
, w
, h
, packed
, 0);
1323 pipe_tile_raw_to_rgba(format
, packed
, w
, h
, p
, dst_stride
);
1330 pipe_get_tile_swizzle(struct pipe_context
*pipe
,
1331 struct pipe_transfer
*pt
,
1340 enum pipe_format format
,
1343 unsigned dst_stride
= w
* 4;
1348 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
)) {
1352 packed
= MALLOC(util_format_get_nblocks(format
, w
, h
) * util_format_get_blocksize(format
));
1357 if (format
== PIPE_FORMAT_UYVY
|| format
== PIPE_FORMAT_YUYV
) {
1358 assert((x
& 1) == 0);
1361 pipe_get_tile_raw(pipe
, pt
, x
, y
, w
, h
, packed
, 0);
1363 pipe_tile_raw_to_rgba(format
, packed
, w
, h
, p
, dst_stride
);
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
) {
1375 rgba01
[PIPE_SWIZZLE_ZERO
] = 0.0f
;
1376 rgba01
[PIPE_SWIZZLE_ONE
] = 1.0f
;
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];
1384 *p
++ = rgba01
[swizzle_r
];
1385 *p
++ = rgba01
[swizzle_g
];
1386 *p
++ = rgba01
[swizzle_b
];
1387 *p
++ = rgba01
[swizzle_a
];
1393 pipe_put_tile_rgba(struct pipe_context
*pipe
,
1394 struct pipe_transfer
*pt
,
1395 uint x
, uint y
, uint w
, uint h
,
1398 unsigned src_stride
= w
* 4;
1400 enum pipe_format format
= pt
->texture
->format
;
1402 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
1405 packed
= MALLOC(util_format_get_nblocks(format
, w
, h
) * util_format_get_blocksize(format
));
1411 case PIPE_FORMAT_B8G8R8A8_UNORM
:
1412 a8r8g8b8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1414 case PIPE_FORMAT_B8G8R8X8_UNORM
:
1415 x8r8g8b8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1417 case PIPE_FORMAT_A8R8G8B8_UNORM
:
1418 b8g8r8a8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1420 case PIPE_FORMAT_A8B8G8R8_UNORM
:
1421 r8g8b8a8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1423 case PIPE_FORMAT_B5G5R5X1_UNORM
:
1424 x1r5g5b5_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1426 case PIPE_FORMAT_B5G5R5A1_UNORM
:
1427 a1r5g5b5_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1429 case PIPE_FORMAT_B5G6R5_UNORM
:
1430 r5g6b5_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1432 case PIPE_FORMAT_R8G8B8_UNORM
:
1433 r8g8b8_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1435 case PIPE_FORMAT_B4G4R4A4_UNORM
:
1436 a4r4g4b4_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1438 case PIPE_FORMAT_L8_UNORM
:
1439 l8_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1441 case PIPE_FORMAT_A8_UNORM
:
1442 a8_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1444 case PIPE_FORMAT_I8_UNORM
:
1445 i8_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1447 case PIPE_FORMAT_L8A8_UNORM
:
1448 a8l8_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1450 case PIPE_FORMAT_R16_SNORM
:
1451 r16_put_tile_rgba((short *) packed
, w
, h
, p
, src_stride
);
1453 case PIPE_FORMAT_R16G16B16A16_SNORM
:
1454 r16g16b16a16_put_tile_rgba((short *) packed
, w
, h
, p
, src_stride
);
1456 case PIPE_FORMAT_B8G8R8A8_SRGB
:
1457 a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
1459 case PIPE_FORMAT_L8A8_SRGB
:
1460 a8l8_srgb_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
1462 case PIPE_FORMAT_L8_SRGB
:
1463 l8_srgb_put_tile_rgba((ubyte
*) packed
, w
, h
, p
, src_stride
);
1465 case PIPE_FORMAT_Z16_UNORM
:
1466 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
1468 case PIPE_FORMAT_Z32_UNORM
:
1469 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1471 case PIPE_FORMAT_Z24S8_UNORM
:
1472 case PIPE_FORMAT_Z24X8_UNORM
:
1473 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1475 case PIPE_FORMAT_S8Z24_UNORM
:
1476 case PIPE_FORMAT_X8Z24_UNORM
:
1477 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
1480 util_format_write_4f(format
,
1481 p
, src_stride
* sizeof(float),
1482 packed
, util_format_get_stride(format
, w
),
1486 pipe_put_tile_raw(pipe
, pt
, x
, y
, w
, h
, packed
, 0);
1493 * Get a block of Z values, converted to 32-bit range.
1496 pipe_get_tile_z(struct pipe_context
*pipe
,
1497 struct pipe_transfer
*pt
,
1498 uint x
, uint y
, uint w
, uint h
,
1501 const uint dstStride
= w
;
1505 enum pipe_format format
= pt
->texture
->format
;
1507 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
1510 map
= (ubyte
*)pipe
->transfer_map(pipe
, pt
);
1517 case PIPE_FORMAT_Z32_UNORM
:
1520 = (const uint
*)(map
+ y
* pt
->stride
+ x
*4);
1521 for (i
= 0; i
< h
; i
++) {
1522 memcpy(pDest
, ptrc
, 4 * w
);
1524 ptrc
+= pt
->stride
/4;
1528 case PIPE_FORMAT_Z24S8_UNORM
:
1529 case PIPE_FORMAT_Z24X8_UNORM
:
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);
1539 ptrc
+= pt
->stride
/4;
1543 case PIPE_FORMAT_S8Z24_UNORM
:
1544 case PIPE_FORMAT_X8Z24_UNORM
:
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);
1554 ptrc
+= pt
->stride
/4;
1558 case PIPE_FORMAT_Z16_UNORM
:
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
];
1568 ptrc
+= pt
->stride
/2;
1576 pipe
->transfer_unmap(pipe
, pt
);
1581 pipe_put_tile_z(struct pipe_context
*pipe
,
1582 struct pipe_transfer
*pt
,
1583 uint x
, uint y
, uint w
, uint h
,
1586 const uint srcStride
= w
;
1587 const uint
*ptrc
= zSrc
;
1590 enum pipe_format format
= pt
->texture
->format
;
1592 if (pipe_clip_tile(x
, y
, &w
, &h
, pt
))
1595 map
= (ubyte
*)pipe
->transfer_map(pipe
, pt
);
1602 case PIPE_FORMAT_Z32_UNORM
:
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;
1612 case PIPE_FORMAT_Z24S8_UNORM
:
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;
1621 pDest
+= pt
->stride
/4;
1626 case PIPE_FORMAT_Z24X8_UNORM
:
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;
1634 pDest
+= pt
->stride
/4;
1639 case PIPE_FORMAT_S8Z24_UNORM
:
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);
1648 pDest
+= pt
->stride
/4;
1653 case PIPE_FORMAT_X8Z24_UNORM
:
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;
1661 pDest
+= pt
->stride
/4;
1666 case PIPE_FORMAT_Z16_UNORM
:
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;
1674 pDest
+= pt
->stride
/2;
1683 pipe
->transfer_unmap(pipe
, pt
);