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.
31 * Surfaces should already be in a mapped state.
35 #include "pipe/p_defines.h"
36 #include "pipe/p_util.h"
37 #include "pipe/p_inlines.h"
44 * Move raw block of pixels from surface to user memory.
45 * This should be usable by any hw driver that has mappable surfaces.
48 pipe_get_tile_raw(struct pipe_context
*pipe
,
49 struct pipe_surface
*ps
,
50 uint x
, uint y
, uint w
, uint h
,
51 void *p
, int dst_stride
)
53 const uint cpp
= ps
->cpp
;
55 const uint src_stride
= ps
->pitch
* cpp
;
59 if (dst_stride
== 0) {
63 if (pipe_clip_tile(x
, y
, &w
, &h
, ps
))
66 pSrc
= (const ubyte
*) pipe_surface_map(ps
) + (y
* ps
->pitch
+ x
) * cpp
;
69 for (i
= 0; i
< h
; i
++) {
70 memcpy(pDest
, pSrc
, w
* cpp
);
75 pipe_surface_unmap(ps
);
80 * Move raw block of pixels from user memory to surface.
81 * This should be usable by any hw driver that has mappable surfaces.
84 pipe_put_tile_raw(struct pipe_context
*pipe
,
85 struct pipe_surface
*ps
,
86 uint x
, uint y
, uint w
, uint h
,
87 const void *p
, int src_stride
)
89 const uint cpp
= ps
->cpp
;
91 const uint dst_stride
= ps
->pitch
* cpp
;
95 if (src_stride
== 0) {
99 if (pipe_clip_tile(x
, y
, &w
, &h
, ps
))
102 pSrc
= (const ubyte
*) p
;
103 pDest
= (ubyte
*) pipe_surface_map(ps
) + (y
* ps
->pitch
+ x
) * cpp
;
105 for (i
= 0; i
< h
; i
++) {
106 memcpy(pDest
, pSrc
, w
* cpp
);
111 pipe_surface_unmap(ps
);
117 /** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
118 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
120 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
121 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
125 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
128 a8r8g8b8_get_tile_rgba(unsigned *src
,
129 unsigned w
, unsigned h
,
135 for (i
= 0; i
< h
; i
++) {
137 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
138 const unsigned pixel
= *src
++;
139 pRow
[0] = UBYTE_TO_FLOAT((pixel
>> 16) & 0xff);
140 pRow
[1] = UBYTE_TO_FLOAT((pixel
>> 8) & 0xff);
141 pRow
[2] = UBYTE_TO_FLOAT((pixel
>> 0) & 0xff);
142 pRow
[3] = UBYTE_TO_FLOAT((pixel
>> 24) & 0xff);
150 a8r8g8b8_put_tile_rgba(unsigned *dst
,
151 unsigned w
, unsigned h
,
157 for (i
= 0; i
< h
; i
++) {
158 const float *pRow
= p
;
159 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
161 UNCLAMPED_FLOAT_TO_UBYTE(r
, pRow
[0]);
162 UNCLAMPED_FLOAT_TO_UBYTE(g
, pRow
[1]);
163 UNCLAMPED_FLOAT_TO_UBYTE(b
, pRow
[2]);
164 UNCLAMPED_FLOAT_TO_UBYTE(a
, pRow
[3]);
165 *dst
++ = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
172 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
175 b8g8r8a8_get_tile_rgba(unsigned *src
,
176 unsigned w
, unsigned h
,
182 for (i
= 0; i
< h
; i
++) {
184 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
185 const unsigned pixel
= *src
++;
186 pRow
[0] = UBYTE_TO_FLOAT((pixel
>> 8) & 0xff);
187 pRow
[1] = UBYTE_TO_FLOAT((pixel
>> 16) & 0xff);
188 pRow
[2] = UBYTE_TO_FLOAT((pixel
>> 24) & 0xff);
189 pRow
[3] = UBYTE_TO_FLOAT((pixel
>> 0) & 0xff);
197 b8g8r8a8_put_tile_rgba(unsigned *dst
,
198 unsigned w
, unsigned h
,
204 for (i
= 0; i
< h
; i
++) {
205 const float *pRow
= p
;
206 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
208 UNCLAMPED_FLOAT_TO_UBYTE(r
, pRow
[0]);
209 UNCLAMPED_FLOAT_TO_UBYTE(g
, pRow
[1]);
210 UNCLAMPED_FLOAT_TO_UBYTE(b
, pRow
[2]);
211 UNCLAMPED_FLOAT_TO_UBYTE(a
, pRow
[3]);
212 *dst
++ = (b
<< 24) | (g
<< 16) | (r
<< 8) | a
;
219 /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
222 a1r5g5b5_get_tile_rgba(ushort
*src
,
223 unsigned w
, unsigned h
,
229 for (i
= 0; i
< h
; i
++) {
231 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
232 const ushort pixel
= *src
++;
233 pRow
[0] = ((pixel
>> 10) & 0x1f) * (1.0f
/ 31.0f
);
234 pRow
[1] = ((pixel
>> 5) & 0x1f) * (1.0f
/ 31.0f
);
235 pRow
[2] = ((pixel
) & 0x1f) * (1.0f
/ 31.0f
);
236 pRow
[3] = ((pixel
>> 15) ) * 1.0f
;
243 /*** PIPE_FORMAT_A4R4G4B4_UNORM ***/
246 a4r4g4b4_get_tile_rgba(ushort
*src
,
247 unsigned w
, unsigned h
,
253 for (i
= 0; i
< h
; i
++) {
255 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
256 const ushort pixel
= *src
++;
257 pRow
[0] = ((pixel
>> 8) & 0xf) * (1.0f
/ 15.0f
);
258 pRow
[1] = ((pixel
>> 4) & 0xf) * (1.0f
/ 15.0f
);
259 pRow
[2] = ((pixel
) & 0xf) * (1.0f
/ 15.0f
);
260 pRow
[3] = ((pixel
>> 12) ) * (1.0f
/ 15.0f
);
267 /*** PIPE_FORMAT_R5G6B5_UNORM ***/
270 r5g6b5_get_tile_rgba(ushort
*src
,
271 unsigned w
, unsigned h
,
277 for (i
= 0; i
< h
; i
++) {
279 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
280 const ushort pixel
= *src
++;
281 pRow
[0] = ((pixel
>> 11) & 0x1f) * (1.0f
/ 31.0f
);
282 pRow
[1] = ((pixel
>> 5) & 0x3f) * (1.0f
/ 63.0f
);
283 pRow
[2] = ((pixel
) & 0x1f) * (1.0f
/ 31.0f
);
292 r5g5b5_put_tile_rgba(ushort
*dst
,
293 unsigned w
, unsigned h
,
299 for (i
= 0; i
< h
; i
++) {
300 const float *pRow
= p
;
301 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
302 uint r
= (uint
) (CLAMP(pRow
[0], 0.0, 1.0) * 31.0);
303 uint g
= (uint
) (CLAMP(pRow
[1], 0.0, 1.0) * 63.0);
304 uint b
= (uint
) (CLAMP(pRow
[2], 0.0, 1.0) * 31.0);
305 *dst
++ = (r
<< 11) | (g
<< 5) | (b
);
313 /*** PIPE_FORMAT_Z16_UNORM ***/
316 * Return each Z value as four floats in [0,1].
319 z16_get_tile_rgba(ushort
*src
,
320 unsigned w
, unsigned h
,
324 const float scale
= 1.0f
/ 65535.0f
;
327 for (i
= 0; i
< h
; i
++) {
329 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
333 pRow
[3] = *src
++ * scale
;
342 /*** PIPE_FORMAT_U_L8 ***/
345 l8_get_tile_rgba(ubyte
*src
,
346 unsigned w
, unsigned h
,
352 for (i
= 0; i
< h
; i
++) {
354 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
357 pRow
[2] = UBYTE_TO_FLOAT(*src
);
365 /*** PIPE_FORMAT_U_A8 ***/
368 a8_get_tile_rgba(ubyte
*src
,
369 unsigned w
, unsigned h
,
375 for (i
= 0; i
< h
; i
++) {
377 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
381 pRow
[3] = UBYTE_TO_FLOAT(*src
);
388 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
391 r16g16b16a16_get_tile_rgba(short *src
,
392 unsigned w
, unsigned h
,
398 for (i
= 0; i
< h
; i
++) {
400 for (j
= 0; j
< w
; j
++, src
+= 4, pRow
+= 4) {
401 pRow
[0] = SHORT_TO_FLOAT(src
[0]);
402 pRow
[1] = SHORT_TO_FLOAT(src
[1]);
403 pRow
[2] = SHORT_TO_FLOAT(src
[2]);
404 pRow
[3] = SHORT_TO_FLOAT(src
[3]);
412 r16g16b16a16_put_tile_rgba(short *dst
,
413 unsigned w
, unsigned h
,
419 for (i
= 0; i
< h
; i
++) {
420 const float *pRow
= p
;
421 for (j
= 0; j
< w
; j
++, dst
+= 4, pRow
+= 4) {
422 UNCLAMPED_FLOAT_TO_SHORT(dst
[0], pRow
[0]);
423 UNCLAMPED_FLOAT_TO_SHORT(dst
[1], pRow
[1]);
424 UNCLAMPED_FLOAT_TO_SHORT(dst
[2], pRow
[2]);
425 UNCLAMPED_FLOAT_TO_SHORT(dst
[3], pRow
[3]);
433 /*** PIPE_FORMAT_U_I8 ***/
436 i8_get_tile_rgba(ubyte
*src
,
437 unsigned w
, unsigned h
,
443 for (i
= 0; i
< h
; i
++) {
445 for (j
= 0; j
< w
; j
++, src
++, pRow
+= 4) {
449 pRow
[3] = UBYTE_TO_FLOAT(*src
);
456 /*** PIPE_FORMAT_U_A8_L8 ***/
459 a8_l8_get_tile_rgba(ushort
*src
,
460 unsigned w
, unsigned h
,
466 for (i
= 0; i
< h
; i
++) {
468 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
472 pRow
[2] = UBYTE_TO_FLOAT(p
& 0xff);
473 pRow
[3] = UBYTE_TO_FLOAT(p
>> 8);
482 /*** PIPE_FORMAT_Z32_UNORM ***/
485 * Return each Z value as four floats in [0,1].
488 z32_get_tile_rgba(unsigned *src
,
489 unsigned w
, unsigned h
,
493 const double scale
= 1.0 / (double) 0xffffffff;
496 for (i
= 0; i
< h
; i
++) {
498 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
502 pRow
[3] = (float) (*src
++ * scale
);
509 /*** PIPE_FORMAT_S8Z24_UNORM ***/
512 * Return Z component as four float in [0,1]. Stencil part ignored.
515 s8z24_get_tile_rgba(unsigned *src
,
516 unsigned w
, unsigned h
,
520 const double scale
= 1.0 / ((1 << 24) - 1);
523 for (i
= 0; i
< h
; i
++) {
525 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
529 pRow
[3] = (float) (scale
* (*src
++ & 0xffffff));
536 /*** PIPE_FORMAT_Z24S8_UNORM ***/
539 * Return Z component as four float in [0,1]. Stencil part ignored.
542 z24s8_get_tile_rgba(unsigned *src
,
543 unsigned w
, unsigned h
,
547 const double scale
= 1.0 / ((1 << 24) - 1);
550 for (i
= 0; i
< h
; i
++) {
552 for (j
= 0; j
< w
; j
++, pRow
+= 4) {
556 pRow
[3] = (float) (scale
* (*src
++ >> 8));
564 pipe_get_tile_rgba(struct pipe_context
*pipe
,
565 struct pipe_surface
*ps
,
566 uint x
, uint y
, uint w
, uint h
,
569 unsigned dst_stride
= w
* 4;
572 if (pipe_clip_tile(x
, y
, &w
, &h
, ps
))
575 packed
= MALLOC(h
* w
* ps
->cpp
);
580 pipe_get_tile_raw(pipe
, ps
, x
, y
, w
, h
, packed
, w
* ps
->cpp
);
582 switch (ps
->format
) {
583 case PIPE_FORMAT_A8R8G8B8_UNORM
:
584 a8r8g8b8_get_tile_rgba((unsigned *) packed
, w
, h
, p
, dst_stride
);
586 case PIPE_FORMAT_B8G8R8A8_UNORM
:
587 b8g8r8a8_get_tile_rgba((unsigned *) packed
, w
, h
, p
, dst_stride
);
589 case PIPE_FORMAT_A1R5G5B5_UNORM
:
590 a1r5g5b5_get_tile_rgba((ushort
*) packed
, w
, h
, p
, dst_stride
);
592 case PIPE_FORMAT_A4R4G4B4_UNORM
:
593 a4r4g4b4_get_tile_rgba((ushort
*) packed
, w
, h
, p
, dst_stride
);
595 case PIPE_FORMAT_R5G6B5_UNORM
:
596 r5g6b5_get_tile_rgba((ushort
*) packed
, w
, h
, p
, dst_stride
);
598 case PIPE_FORMAT_U_L8
:
599 l8_get_tile_rgba((ubyte
*) packed
, w
, h
, p
, dst_stride
);
601 case PIPE_FORMAT_U_A8
:
602 a8_get_tile_rgba((ubyte
*) packed
, w
, h
, p
, dst_stride
);
604 case PIPE_FORMAT_U_I8
:
605 i8_get_tile_rgba((ubyte
*) packed
, w
, h
, p
, dst_stride
);
607 case PIPE_FORMAT_U_A8_L8
:
608 a8_l8_get_tile_rgba((ushort
*) packed
, w
, h
, p
, dst_stride
);
610 case PIPE_FORMAT_R16G16B16A16_SNORM
:
611 r16g16b16a16_get_tile_rgba((short *) packed
, w
, h
, p
, dst_stride
);
613 case PIPE_FORMAT_Z16_UNORM
:
614 z16_get_tile_rgba((ushort
*) packed
, w
, h
, p
, dst_stride
);
616 case PIPE_FORMAT_Z32_UNORM
:
617 z32_get_tile_rgba((unsigned *) packed
, w
, h
, p
, dst_stride
);
619 case PIPE_FORMAT_S8Z24_UNORM
:
620 s8z24_get_tile_rgba((unsigned *) packed
, w
, h
, p
, dst_stride
);
622 case PIPE_FORMAT_Z24S8_UNORM
:
623 z24s8_get_tile_rgba((unsigned *) packed
, w
, h
, p
, dst_stride
);
634 pipe_put_tile_rgba(struct pipe_context
*pipe
,
635 struct pipe_surface
*ps
,
636 uint x
, uint y
, uint w
, uint h
,
639 unsigned src_stride
= w
* 4;
642 if (pipe_clip_tile(x
, y
, &w
, &h
, ps
))
645 packed
= MALLOC(h
* w
* ps
->cpp
);
650 switch (ps
->format
) {
651 case PIPE_FORMAT_A8R8G8B8_UNORM
:
652 a8r8g8b8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
654 case PIPE_FORMAT_B8G8R8A8_UNORM
:
655 b8g8r8a8_put_tile_rgba((unsigned *) packed
, w
, h
, p
, src_stride
);
657 case PIPE_FORMAT_A1R5G5B5_UNORM
:
658 /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
660 case PIPE_FORMAT_R5G6B5_UNORM
:
661 r5g5b5_put_tile_rgba((ushort
*) packed
, w
, h
, p
, src_stride
);
663 case PIPE_FORMAT_R8G8B8A8_UNORM
:
665 case PIPE_FORMAT_U_L8
:
666 /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
668 case PIPE_FORMAT_U_A8
:
669 /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
671 case PIPE_FORMAT_U_I8
:
672 /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/
674 case PIPE_FORMAT_U_A8_L8
:
675 /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
677 case PIPE_FORMAT_R16G16B16A16_SNORM
:
678 r16g16b16a16_put_tile_rgba((short *) packed
, w
, h
, p
, src_stride
);
680 case PIPE_FORMAT_Z16_UNORM
:
681 /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
683 case PIPE_FORMAT_Z32_UNORM
:
684 /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
686 case PIPE_FORMAT_S8Z24_UNORM
:
687 /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
689 case PIPE_FORMAT_Z24S8_UNORM
:
690 /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
696 pipe_put_tile_raw(pipe
, ps
, x
, y
, w
, h
, packed
, w
* ps
->cpp
);
703 * Get a block of Z values, converted to 32-bit range.
706 pipe_get_tile_z(struct pipe_context
*pipe
,
707 struct pipe_surface
*ps
,
708 uint x
, uint y
, uint w
, uint h
,
711 const uint dstStride
= w
;
715 if (pipe_clip_tile(x
, y
, &w
, &h
, ps
))
718 switch (ps
->format
) {
719 case PIPE_FORMAT_Z32_UNORM
:
722 = (const uint
*) pipe_surface_map(ps
) + (y
* ps
->pitch
+ x
);
723 for (i
= 0; i
< h
; i
++) {
724 memcpy(pDest
, pSrc
, 4 * w
);
730 case PIPE_FORMAT_S8Z24_UNORM
:
733 = (const uint
*) pipe_surface_map(ps
) + (y
* ps
->pitch
+ x
);
734 for (i
= 0; i
< h
; i
++) {
735 for (j
= 0; j
< w
; j
++) {
736 /* convert 24-bit Z to 32-bit Z */
737 pDest
[j
] = (pSrc
[j
] << 8) | (pSrc
[j
] & 0xff);
744 case PIPE_FORMAT_Z16_UNORM
:
747 = (const ushort
*) pipe_surface_map(ps
) + (y
* ps
->pitch
+ x
);
748 for (i
= 0; i
< h
; i
++) {
749 for (j
= 0; j
< w
; j
++) {
750 /* convert 16-bit Z to 32-bit Z */
751 pDest
[j
] = (pSrc
[j
] << 16) | pSrc
[j
];
762 pipe_surface_unmap(ps
);
767 pipe_put_tile_z(struct pipe_context
*pipe
,
768 struct pipe_surface
*ps
,
769 uint x
, uint y
, uint w
, uint h
,
772 const uint srcStride
= w
;
773 const uint
*pSrc
= zSrc
;
776 if (pipe_clip_tile(x
, y
, &w
, &h
, ps
))
779 switch (ps
->format
) {
780 case PIPE_FORMAT_Z32_UNORM
:
782 uint
*pDest
= (uint
*) pipe_surface_map(ps
) + (y
* ps
->pitch
+ x
);
783 for (i
= 0; i
< h
; i
++) {
784 memcpy(pDest
, pSrc
, 4 * w
);
790 case PIPE_FORMAT_S8Z24_UNORM
:
792 uint
*pDest
= (uint
*) pipe_surface_map(ps
) + (y
* ps
->pitch
+ x
);
793 for (i
= 0; i
< h
; i
++) {
794 for (j
= 0; j
< w
; j
++) {
795 /* convert 32-bit Z to 24-bit Z (0 stencil) */
796 pDest
[j
] = pSrc
[j
] >> 8;
803 case PIPE_FORMAT_Z16_UNORM
:
805 ushort
*pDest
= (ushort
*) pipe_surface_map(ps
) + (y
* ps
->pitch
+ x
);
806 for (i
= 0; i
< h
; i
++) {
807 for (j
= 0; j
< w
; j
++) {
808 /* convert 32-bit Z to 16-bit Z */
809 pDest
[j
] = pSrc
[j
] >> 16;
820 pipe_surface_unmap(ps
);