1 /**************************************************************************
3 * Copyright 2003 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 **************************************************************************/
28 #include "sp_context.h"
30 #include "sp_surface.h"
31 #include "pipe/p_defines.h"
32 #include "pipe/p_util.h"
36 * Softpipe surface functions.
37 * Basically, create surface of a particular type, then plug in default
38 * read/write_quad and get/put_tile() functions.
39 * Note that these quad funcs assume the buffer/region is in a linear
40 * layout with Y=0=top.
41 * If we had swizzled/AOS buffers the read/write quad functions could be
42 * simplified a lot....
47 /*** PIPE_FORMAT_U_A8_R8_G8_B8 ***/
50 a8r8g8b8_read_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
51 float (*rrrr
)[QUAD_SIZE
])
54 = ((const unsigned *) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
55 + y
* sps
->surface
.region
->pitch
+ x
;
58 assert(sps
->surface
.format
== PIPE_FORMAT_U_A8_R8_G8_B8
);
60 assert(x
< (int) sps
->surface
.width
- 1);
61 assert(y
< (int) sps
->surface
.height
- 1);
63 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
64 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
65 const unsigned p
= src
[j
];
66 rrrr
[0][i
* 2 + j
] = UBYTE_TO_FLOAT((p
>> 16) & 0xff); /*R*/
67 rrrr
[1][i
* 2 + j
] = UBYTE_TO_FLOAT((p
>> 8) & 0xff); /*G*/
68 rrrr
[2][i
* 2 + j
] = UBYTE_TO_FLOAT((p
) & 0xff); /*B*/
69 rrrr
[3][i
* 2 + j
] = UBYTE_TO_FLOAT((p
>> 24) & 0xff); /*A*/
71 src
+= sps
->surface
.region
->pitch
;
76 a8r8g8b8_write_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
77 float (*rrrr
)[QUAD_SIZE
])
80 = ((unsigned *) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
81 + y
* sps
->surface
.region
->pitch
+ x
;
84 assert(sps
->surface
.format
== PIPE_FORMAT_U_A8_R8_G8_B8
);
86 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
87 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
89 UNCLAMPED_FLOAT_TO_UBYTE(r
, rrrr
[0][i
* 2 + j
]); /*R*/
90 UNCLAMPED_FLOAT_TO_UBYTE(g
, rrrr
[1][i
* 2 + j
]); /*G*/
91 UNCLAMPED_FLOAT_TO_UBYTE(b
, rrrr
[2][i
* 2 + j
]); /*B*/
92 UNCLAMPED_FLOAT_TO_UBYTE(a
, rrrr
[3][i
* 2 + j
]); /*A*/
93 dst
[j
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
95 dst
+= sps
->surface
.region
->pitch
;
100 a8r8g8b8_get_tile(struct pipe_surface
*ps
,
101 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
104 = ((const unsigned *) (ps
->region
->map
+ ps
->offset
))
105 + y
* ps
->region
->pitch
+ x
;
109 assert(ps
->format
== PIPE_FORMAT_U_A8_R8_G8_B8
);
112 assert(x
+ w
<= ps
->width
);
113 assert(y
+ h
<= ps
->height
);
115 /* temp clipping hack */
116 if (x
+ w
> ps
->width
)
118 if (y
+ h
> ps
->height
)
121 for (i
= 0; i
< h
; i
++) {
123 for (j
= 0; j
< w
; j
++) {
124 const unsigned pixel
= src
[j
];
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);
131 src
+= ps
->region
->pitch
;
138 a8r8g8b8_put_tile(struct pipe_surface
*ps
,
139 unsigned x
, unsigned y
, unsigned w
, unsigned h
,
143 = ((unsigned *) (ps
->region
->map
+ ps
->offset
))
144 + y
* ps
->region
->pitch
+ x
;
148 assert(ps
->format
== PIPE_FORMAT_U_A8_R8_G8_B8
);
151 assert(x
+ w
<= ps
->width
);
152 assert(y
+ h
<= ps
->height
);
154 /* temp clipping hack */
155 if (x
+ w
> ps
->width
)
157 if (y
+ h
> ps
->height
)
160 for (i
= 0; i
< h
; i
++) {
161 const float *pRow
= p
;
162 for (j
= 0; j
< w
; j
++) {
164 UNCLAMPED_FLOAT_TO_UBYTE(r
, pRow
[0]);
165 UNCLAMPED_FLOAT_TO_UBYTE(g
, pRow
[1]);
166 UNCLAMPED_FLOAT_TO_UBYTE(b
, pRow
[2]);
167 UNCLAMPED_FLOAT_TO_UBYTE(a
, pRow
[3]);
168 dst
[j
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
171 dst
+= ps
->region
->pitch
;
177 /*** PIPE_FORMAT_U_A1_R5_G5_B5 ***/
180 a1r5g5b5_get_tile(struct pipe_surface
*ps
,
181 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
184 = ((const ushort
*) (ps
->region
->map
+ ps
->offset
))
185 + y
* ps
->region
->pitch
+ x
;
188 assert(ps
->format
== PIPE_FORMAT_U_A1_R5_G5_B5
);
190 for (i
= 0; i
< h
; i
++) {
191 for (j
= 0; j
< w
; j
++) {
192 const ushort pixel
= src
[j
];
193 p
[0] = ((pixel
>> 10) & 0x1f) * (1.0f
/ 31.0f
);
194 p
[1] = ((pixel
>> 5) & 0x1f) * (1.0f
/ 31.0f
);
195 p
[2] = ((pixel
) & 0x1f) * (1.0f
/ 31.0f
);
196 p
[3] = ((pixel
>> 15) ) * 1.0f
;
199 src
+= ps
->region
->pitch
;
205 /*** PIPE_FORMAT_U_Z16 ***/
208 z16_read_quad_z(struct softpipe_surface
*sps
,
209 int x
, int y
, unsigned zzzz
[QUAD_SIZE
])
212 = ((const ushort
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
213 + y
* sps
->surface
.region
->pitch
+ x
;
215 assert(sps
->surface
.format
== PIPE_FORMAT_U_Z16
);
217 /* converting ushort to unsigned: */
220 src
+= sps
->surface
.region
->pitch
;
226 z16_write_quad_z(struct softpipe_surface
*sps
,
227 int x
, int y
, const unsigned zzzz
[QUAD_SIZE
])
230 = ((ushort
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
231 + y
* sps
->surface
.region
->pitch
+ x
;
233 assert(sps
->surface
.format
== PIPE_FORMAT_U_Z16
);
235 /* converting unsigned to ushort: */
238 dst
+= sps
->surface
.region
->pitch
;
244 * Return as floats in [0,1].
247 z16_get_tile(struct pipe_surface
*ps
,
248 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
251 = ((const ushort
*) (ps
->region
->map
+ ps
->offset
))
252 + y
* ps
->region
->pitch
+ x
;
253 const float scale
= 1.0 / 65535.0;
257 assert(ps
->format
== PIPE_FORMAT_U_Z16
);
260 assert(x
+ w
<= ps
->width
);
261 assert(y
+ h
<= ps
->height
);
263 /* temp clipping hack */
264 if (x
+ w
> ps
->width
)
266 if (y
+ h
> ps
->height
)
269 for (i
= 0; i
< h
; i
++) {
271 for (j
= 0; j
< w
; j
++) {
272 pRow
[j
] = src
[j
] * scale
;
274 src
+= ps
->region
->pitch
;
282 /*** PIPE_FORMAT_U_L8 ***/
285 l8_read_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
286 float (*rrrr
)[QUAD_SIZE
])
289 = ((const ubyte
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
290 + y
* sps
->surface
.region
->pitch
+ x
;
293 assert(sps
->surface
.format
== PIPE_FORMAT_U_L8
);
294 assert(x
< (int) sps
->surface
.width
- 1);
295 assert(y
< (int) sps
->surface
.height
- 1);
297 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
298 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
301 rrrr
[2][i
* 2 + j
] = UBYTE_TO_FLOAT(src
[j
]);
302 rrrr
[3][i
* 2 + j
] = 1.0F
;
304 src
+= sps
->surface
.region
->pitch
;
309 l8_write_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
310 float (*rrrr
)[QUAD_SIZE
])
313 = ((ubyte
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
314 + y
* sps
->surface
.region
->pitch
+ x
;
317 assert(sps
->surface
.format
== PIPE_FORMAT_U_L8
);
319 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
320 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
322 UNCLAMPED_FLOAT_TO_UBYTE(r
, rrrr
[0][i
* 2 + j
]); /*R*/
325 dst
+= sps
->surface
.region
->pitch
;
330 l8_get_tile(struct pipe_surface
*ps
,
331 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
334 = ((const ubyte
*) (ps
->region
->map
+ ps
->offset
))
335 + y
* ps
->region
->pitch
+ x
;
339 assert(ps
->format
== PIPE_FORMAT_U_L8
);
342 assert(x
+ w
<= ps
->width
);
343 assert(y
+ h
<= ps
->height
);
345 /* temp clipping hack */
346 if (x
+ w
> ps
->width
)
348 if (y
+ h
> ps
->height
)
351 for (i
= 0; i
< h
; i
++) {
353 for (j
= 0; j
< w
; j
++) {
356 pRow
[2] = UBYTE_TO_FLOAT(src
[j
]);
360 src
+= ps
->region
->pitch
;
366 /*** PIPE_FORMAT_U_A8 ***/
369 a8_read_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
370 float (*rrrr
)[QUAD_SIZE
])
373 = ((const ubyte
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
374 + y
* sps
->surface
.region
->pitch
+ x
;
377 assert(sps
->surface
.format
== PIPE_FORMAT_U_A8
);
378 assert(x
< (int) sps
->surface
.width
- 1);
379 assert(y
< (int) sps
->surface
.height
- 1);
381 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
382 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
385 rrrr
[2][i
* 2 + j
] = 0.0F
;
386 rrrr
[3][i
* 2 + j
] = UBYTE_TO_FLOAT(src
[j
]);
388 src
+= sps
->surface
.region
->pitch
;
393 a8_write_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
394 float (*rrrr
)[QUAD_SIZE
])
397 = ((ubyte
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
398 + y
* sps
->surface
.region
->pitch
+ x
;
401 assert(sps
->surface
.format
== PIPE_FORMAT_U_A8
);
403 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
404 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
406 UNCLAMPED_FLOAT_TO_UBYTE(r
, rrrr
[3][i
* 2 + j
]); /*A*/
409 dst
+= sps
->surface
.region
->pitch
;
414 a8_get_tile(struct pipe_surface
*ps
,
415 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
418 = ((const ubyte
*) (ps
->region
->map
+ ps
->offset
))
419 + y
* ps
->region
->pitch
+ x
;
423 assert(ps
->format
== PIPE_FORMAT_U_A8
);
426 assert(x
+ w
<= ps
->width
);
427 assert(y
+ h
<= ps
->height
);
429 /* temp clipping hack */
430 if (x
+ w
> ps
->width
)
432 if (y
+ h
> ps
->height
)
435 for (i
= 0; i
< h
; i
++) {
437 for (j
= 0; j
< w
; j
++) {
441 pRow
[3] = UBYTE_TO_FLOAT(src
[j
]);
444 src
+= ps
->region
->pitch
;
451 /*** PIPE_FORMAT_U_I8 ***/
454 i8_read_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
455 float (*rrrr
)[QUAD_SIZE
])
458 = ((const ubyte
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
459 + y
* sps
->surface
.region
->pitch
+ x
;
462 assert(sps
->surface
.format
== PIPE_FORMAT_U_I8
);
463 assert(x
< (int) sps
->surface
.width
- 1);
464 assert(y
< (int) sps
->surface
.height
- 1);
466 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
467 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
471 rrrr
[3][i
* 2 + j
] = UBYTE_TO_FLOAT(src
[j
]);
473 src
+= sps
->surface
.region
->pitch
;
478 i8_write_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
479 float (*rrrr
)[QUAD_SIZE
])
482 = ((ubyte
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
483 + y
* sps
->surface
.region
->pitch
+ x
;
486 assert(sps
->surface
.format
== PIPE_FORMAT_U_I8
);
488 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
489 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
491 UNCLAMPED_FLOAT_TO_UBYTE(r
, rrrr
[0][i
* 2 + j
]); /*R*/
494 dst
+= sps
->surface
.region
->pitch
;
499 i8_get_tile(struct pipe_surface
*ps
,
500 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
503 = ((const ubyte
*) (ps
->region
->map
+ ps
->offset
))
504 + y
* ps
->region
->pitch
+ x
;
508 assert(ps
->format
== PIPE_FORMAT_U_I8
);
511 assert(x
+ w
<= ps
->width
);
512 assert(y
+ h
<= ps
->height
);
514 /* temp clipping hack */
515 if (x
+ w
> ps
->width
)
517 if (y
+ h
> ps
->height
)
520 for (i
= 0; i
< h
; i
++) {
522 for (j
= 0; j
< w
; j
++) {
526 pRow
[3] = UBYTE_TO_FLOAT(src
[j
]);
529 src
+= ps
->region
->pitch
;
535 /*** PIPE_FORMAT_U_A8_L8 ***/
538 a8_l8_read_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
539 float (*rrrr
)[QUAD_SIZE
])
542 = ((const ushort
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
543 + y
* sps
->surface
.region
->pitch
+ x
;
546 assert(sps
->surface
.format
== PIPE_FORMAT_U_A8_L8
);
547 assert(x
< (int) sps
->surface
.width
- 1);
548 assert(y
< (int) sps
->surface
.height
- 1);
550 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
551 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
552 const ushort p
= src
[j
];
555 rrrr
[2][i
* 2 + j
] = UBYTE_TO_FLOAT(p
>> 8);
556 rrrr
[3][i
* 2 + j
] = UBYTE_TO_FLOAT(p
& 0xff);
558 src
+= sps
->surface
.region
->pitch
;
563 a8_l8_write_quad_f_swz(struct softpipe_surface
*sps
, int x
, int y
,
564 float (*rrrr
)[QUAD_SIZE
])
567 = ((ushort
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
568 + y
* sps
->surface
.region
->pitch
+ x
;
571 assert(sps
->surface
.format
== PIPE_FORMAT_U_A8_L8
);
573 for (i
= 0; i
< 2; i
++) { /* loop over pixel row */
574 for (j
= 0; j
< 2; j
++) { /* loop over pixel column */
576 UNCLAMPED_FLOAT_TO_UBYTE(l
, rrrr
[0][i
* 2 + j
]); /*R*/
577 UNCLAMPED_FLOAT_TO_UBYTE(a
, rrrr
[3][i
* 2 + j
]); /*A*/
578 dst
[j
] = (l
<< 8) | a
;
580 dst
+= sps
->surface
.region
->pitch
;
585 a8_l8_get_tile(struct pipe_surface
*ps
,
586 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
589 = ((const ushort
*) (ps
->region
->map
+ ps
->offset
))
590 + y
* ps
->region
->pitch
+ x
;
594 assert(ps
->format
== PIPE_FORMAT_U_A8_L8
);
597 assert(x
+ w
<= ps
->width
);
598 assert(y
+ h
<= ps
->height
);
600 /* temp clipping hack */
601 if (x
+ w
> ps
->width
)
603 if (y
+ h
> ps
->height
)
606 for (i
= 0; i
< h
; i
++) {
608 for (j
= 0; j
< w
; j
++) {
609 const ushort p
= src
[j
];
612 pRow
[2] = UBYTE_TO_FLOAT(p
& 0xff);
613 pRow
[3] = UBYTE_TO_FLOAT(p
>> 8);
616 src
+= ps
->region
->pitch
;
624 /*** PIPE_FORMAT_U_Z32 ***/
627 z32_read_quad_z(struct softpipe_surface
*sps
,
628 int x
, int y
, unsigned zzzz
[QUAD_SIZE
])
631 = ((unsigned *) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
632 + y
* sps
->surface
.region
->pitch
+ x
;
634 assert(sps
->surface
.format
== PIPE_FORMAT_U_Z32
);
638 src
+= sps
->surface
.region
->pitch
;
644 z32_write_quad_z(struct softpipe_surface
*sps
,
645 int x
, int y
, const unsigned zzzz
[QUAD_SIZE
])
648 = ((unsigned *) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
649 + y
* sps
->surface
.region
->pitch
+ x
;
651 assert(sps
->surface
.format
== PIPE_FORMAT_U_Z32
);
655 dst
+= sps
->surface
.region
->pitch
;
661 * Return as floats in [0,1].
664 z32_get_tile(struct pipe_surface
*ps
,
665 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
668 = ((const uint
*) (ps
->region
->map
+ ps
->offset
))
669 + y
* ps
->region
->pitch
+ x
;
670 const double scale
= 1.0 / (double) 0xffffffff;
674 assert(ps
->format
== PIPE_FORMAT_U_Z16
);
677 assert(x
+ w
<= ps
->width
);
678 assert(y
+ h
<= ps
->height
);
680 /* temp clipping hack */
681 if (x
+ w
> ps
->width
)
683 if (y
+ h
> ps
->height
)
686 for (i
= 0; i
< h
; i
++) {
688 for (j
= 0; j
< w
; j
++) {
689 pRow
[j
] = src
[j
] * scale
;
691 src
+= ps
->region
->pitch
;
697 /*** PIPE_FORMAT_S8_Z24 ***/
700 s8z24_read_quad_z(struct softpipe_surface
*sps
,
701 int x
, int y
, unsigned zzzz
[QUAD_SIZE
])
703 static const unsigned mask
= 0x00ffffff;
705 = ((unsigned *) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
706 + y
* sps
->surface
.region
->pitch
+ x
;
708 assert(sps
->surface
.format
== PIPE_FORMAT_S8_Z24
);
710 /* extract lower three bytes */
711 zzzz
[0] = src
[0] & mask
;
712 zzzz
[1] = src
[1] & mask
;
713 src
+= sps
->surface
.region
->pitch
;
714 zzzz
[2] = src
[0] & mask
;
715 zzzz
[3] = src
[1] & mask
;
719 s8z24_write_quad_z(struct softpipe_surface
*sps
,
720 int x
, int y
, const unsigned zzzz
[QUAD_SIZE
])
722 static const unsigned mask
= 0xff000000;
724 = ((unsigned *) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
725 + y
* sps
->surface
.region
->pitch
+ x
;
727 assert(sps
->surface
.format
== PIPE_FORMAT_S8_Z24
);
728 assert(zzzz
[0] <= 0xffffff);
730 dst
[0] = (dst
[0] & mask
) | zzzz
[0];
731 dst
[1] = (dst
[1] & mask
) | zzzz
[1];
732 dst
+= sps
->surface
.region
->pitch
;
733 dst
[0] = (dst
[0] & mask
) | zzzz
[2];
734 dst
[1] = (dst
[1] & mask
) | zzzz
[3];
738 s8z24_read_quad_stencil(struct softpipe_surface
*sps
,
739 int x
, int y
, ubyte ssss
[QUAD_SIZE
])
742 = ((unsigned *) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
743 + y
* sps
->surface
.region
->pitch
+ x
;
745 assert(sps
->surface
.format
== PIPE_FORMAT_S8_Z24
);
747 ssss
[0] = src
[0] >> 24;
748 ssss
[1] = src
[1] >> 24;
749 src
+= sps
->surface
.region
->pitch
;
750 ssss
[2] = src
[0] >> 24;
751 ssss
[3] = src
[1] >> 24;
755 s8z24_write_quad_stencil(struct softpipe_surface
*sps
,
756 int x
, int y
, const ubyte ssss
[QUAD_SIZE
])
758 static const unsigned mask
= 0x00ffffff;
760 = ((unsigned *) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
761 + y
* sps
->surface
.region
->pitch
+ x
;
763 assert(sps
->surface
.format
== PIPE_FORMAT_S8_Z24
);
765 dst
[0] = (dst
[0] & mask
) | (ssss
[0] << 24);
766 dst
[1] = (dst
[1] & mask
) | (ssss
[1] << 24);
767 dst
+= sps
->surface
.region
->pitch
;
768 dst
[0] = (dst
[0] & mask
) | (ssss
[2] << 24);
769 dst
[1] = (dst
[1] & mask
) | (ssss
[3] << 24);
774 * Return Z component as float in [0,1]. Stencil part ignored.
777 s8z24_get_tile(struct pipe_surface
*ps
,
778 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
781 = ((const uint
*) (ps
->region
->map
+ ps
->offset
))
782 + y
* ps
->region
->pitch
+ x
;
783 const double scale
= 1.0 / ((1 << 24) - 1);
787 assert(ps
->format
== PIPE_FORMAT_S8_Z24
);
790 assert(x
+ w
<= ps
->width
);
791 assert(y
+ h
<= ps
->height
);
793 /* temp clipping hack */
794 if (x
+ w
> ps
->width
)
796 if (y
+ h
> ps
->height
)
799 for (i
= 0; i
< h
; i
++) {
801 for (j
= 0; j
< w
; j
++) {
802 pRow
[j
] = (src
[j
] & 0xffffff) * scale
;
804 src
+= ps
->region
->pitch
;
810 /*** PIPE_FORMAT_U_S8 ***/
813 s8_read_quad_stencil(struct softpipe_surface
*sps
,
814 int x
, int y
, ubyte ssss
[QUAD_SIZE
])
817 = sps
->surface
.region
->map
+ sps
->surface
.offset
818 + y
* sps
->surface
.region
->pitch
+ x
;
820 assert(sps
->surface
.format
== PIPE_FORMAT_U_S8
);
824 src
+= sps
->surface
.region
->pitch
;
830 s8_write_quad_stencil(struct softpipe_surface
*sps
,
831 int x
, int y
, const ubyte ssss
[QUAD_SIZE
])
834 = sps
->surface
.region
->map
+ sps
->surface
.offset
835 + y
* sps
->surface
.region
->pitch
+ x
;
837 assert(sps
->surface
.format
== PIPE_FORMAT_U_S8
);
841 dst
+= sps
->surface
.region
->pitch
;
848 * Initialize the quad_read/write and get/put_tile() methods.
851 softpipe_init_surface_funcs(struct softpipe_surface
*sps
)
853 assert(sps
->surface
.format
);
855 switch (sps
->surface
.format
) {
856 case PIPE_FORMAT_U_A8_R8_G8_B8
:
857 sps
->read_quad_f_swz
= a8r8g8b8_read_quad_f_swz
;
858 sps
->write_quad_f_swz
= a8r8g8b8_write_quad_f_swz
;
859 sps
->surface
.get_tile
= a8r8g8b8_get_tile
;
860 sps
->surface
.put_tile
= a8r8g8b8_put_tile
;
862 case PIPE_FORMAT_U_A1_R5_G5_B5
:
863 sps
->surface
.get_tile
= a1r5g5b5_get_tile
;
865 case PIPE_FORMAT_U_L8
:
866 sps
->read_quad_f_swz
= l8_read_quad_f_swz
;
867 sps
->write_quad_f_swz
= l8_write_quad_f_swz
;
868 sps
->surface
.get_tile
= l8_get_tile
;
870 case PIPE_FORMAT_U_A8
:
871 sps
->read_quad_f_swz
= a8_read_quad_f_swz
;
872 sps
->write_quad_f_swz
= a8_write_quad_f_swz
;
873 sps
->surface
.get_tile
= a8_get_tile
;
875 case PIPE_FORMAT_U_I8
:
876 sps
->read_quad_f_swz
= i8_read_quad_f_swz
;
877 sps
->write_quad_f_swz
= i8_write_quad_f_swz
;
878 sps
->surface
.get_tile
= i8_get_tile
;
880 case PIPE_FORMAT_U_A8_L8
:
881 sps
->read_quad_f_swz
= a8_l8_read_quad_f_swz
;
882 sps
->write_quad_f_swz
= a8_l8_write_quad_f_swz
;
883 sps
->surface
.get_tile
= a8_l8_get_tile
;
886 case PIPE_FORMAT_U_Z16
:
887 sps
->read_quad_z
= z16_read_quad_z
;
888 sps
->write_quad_z
= z16_write_quad_z
;
889 sps
->surface
.get_tile
= z16_get_tile
;
891 case PIPE_FORMAT_U_Z32
:
892 sps
->read_quad_z
= z32_read_quad_z
;
893 sps
->write_quad_z
= z32_write_quad_z
;
894 sps
->surface
.get_tile
= z32_get_tile
;
896 case PIPE_FORMAT_S8_Z24
:
897 sps
->read_quad_z
= s8z24_read_quad_z
;
898 sps
->write_quad_z
= s8z24_write_quad_z
;
899 sps
->read_quad_stencil
= s8z24_read_quad_stencil
;
900 sps
->write_quad_stencil
= s8z24_write_quad_stencil
;
901 sps
->surface
.get_tile
= s8z24_get_tile
;
904 case PIPE_FORMAT_U_S8
:
905 sps
->read_quad_stencil
= s8_read_quad_stencil
;
906 sps
->write_quad_stencil
= s8_write_quad_stencil
;
914 static struct pipe_surface
*
915 softpipe_surface_alloc(struct pipe_context
*pipe
, unsigned pipeFormat
)
917 struct softpipe_surface
*sps
= CALLOC_STRUCT(softpipe_surface
);
921 assert(pipeFormat
< PIPE_FORMAT_COUNT
);
923 sps
->surface
.format
= pipeFormat
;
924 sps
->surface
.refcount
= 1;
925 softpipe_init_surface_funcs(sps
);
927 return &sps
->surface
;
935 * Called via pipe->get_tex_surface()
936 * XXX is this in the right place?
938 struct pipe_surface
*
939 softpipe_get_tex_surface(struct pipe_context
*pipe
,
940 struct pipe_mipmap_tree
*mt
,
941 unsigned face
, unsigned level
, unsigned zslice
)
943 struct pipe_surface
*ps
;
944 unsigned offset
; /* in bytes */
946 offset
= mt
->level
[level
].level_offset
;
948 if (mt
->target
== PIPE_TEXTURE_CUBE
) {
949 offset
+= mt
->level
[level
].image_offset
[face
] * mt
->cpp
;
951 else if (mt
->target
== PIPE_TEXTURE_3D
) {
952 offset
+= mt
->level
[level
].image_offset
[zslice
] * mt
->cpp
;
959 ps
= pipe
->surface_alloc(pipe
, mt
->format
);
962 assert(ps
->refcount
);
963 pipe_region_reference(&ps
->region
, mt
->region
);
964 ps
->width
= mt
->level
[level
].width
;
965 ps
->height
= mt
->level
[level
].height
;
973 sp_init_surface_functions(struct softpipe_context
*sp
)
975 sp
->pipe
.surface_alloc
= softpipe_surface_alloc
;