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 **************************************************************************/
28 #include "pipe/p_defines.h"
29 #include "pipe/p_util.h"
30 #include "pipe/p_inlines.h"
31 #include "pipe/p_winsys.h"
32 #include "sp_context.h"
34 #include "sp_surface.h"
35 #include "sp_tile_cache.h"
38 * Softpipe surface functions.
42 /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
43 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
45 #define UNCLAMPED_FLOAT_TO_SHORT(us, f) \
46 us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
53 assert(x + w <= ps->width); \
54 assert(y + h <= ps->height); \
62 if (y >= ps->height) \
64 if (x + w > ps->width) \
66 if (y + h > ps->height) \
72 /*** PIPE_FORMAT_U_A8_R8_G8_B8 ***/
75 a8r8g8b8_get_tile(struct pipe_surface
*ps
,
76 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
79 = ((const unsigned *) (ps
->region
->map
+ ps
->offset
))
84 assert(ps
->format
== PIPE_FORMAT_U_A8_R8_G8_B8
);
88 for (i
= 0; i
< h
; i
++) {
90 for (j
= 0; j
< w
; j
++) {
91 const unsigned pixel
= src
[j
];
92 pRow
[0] = UBYTE_TO_FLOAT((pixel
>> 16) & 0xff);
93 pRow
[1] = UBYTE_TO_FLOAT((pixel
>> 8) & 0xff);
94 pRow
[2] = UBYTE_TO_FLOAT((pixel
>> 0) & 0xff);
95 pRow
[3] = UBYTE_TO_FLOAT((pixel
>> 24) & 0xff);
105 a8r8g8b8_put_tile(struct pipe_surface
*ps
,
106 unsigned x
, unsigned y
, unsigned w
, unsigned h
,
110 = ((unsigned *) (ps
->region
->map
+ ps
->offset
))
115 assert(ps
->format
== PIPE_FORMAT_U_A8_R8_G8_B8
);
119 for (i
= 0; i
< h
; i
++) {
120 const float *pRow
= p
;
121 for (j
= 0; j
< w
; j
++) {
123 UNCLAMPED_FLOAT_TO_UBYTE(r
, pRow
[0]);
124 UNCLAMPED_FLOAT_TO_UBYTE(g
, pRow
[1]);
125 UNCLAMPED_FLOAT_TO_UBYTE(b
, pRow
[2]);
126 UNCLAMPED_FLOAT_TO_UBYTE(a
, pRow
[3]);
127 dst
[j
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
136 /*** PIPE_FORMAT_U_B8_G8_R8_A8 ***/
139 b8g8r8a8_get_tile(struct pipe_surface
*ps
,
140 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
143 = ((const unsigned *) (ps
->region
->map
+ ps
->offset
))
148 assert(ps
->format
== PIPE_FORMAT_U_B8_G8_R8_A8
);
152 for (i
= 0; i
< h
; i
++) {
154 for (j
= 0; j
< w
; j
++) {
155 const unsigned pixel
= src
[j
];
156 pRow
[0] = UBYTE_TO_FLOAT((pixel
>> 8) & 0xff);
157 pRow
[1] = UBYTE_TO_FLOAT((pixel
>> 16) & 0xff);
158 pRow
[2] = UBYTE_TO_FLOAT((pixel
>> 24) & 0xff);
159 pRow
[3] = UBYTE_TO_FLOAT((pixel
>> 0) & 0xff);
169 b8g8r8a8_put_tile(struct pipe_surface
*ps
,
170 unsigned x
, unsigned y
, unsigned w
, unsigned h
,
174 = ((unsigned *) (ps
->region
->map
+ ps
->offset
))
179 assert(ps
->format
== PIPE_FORMAT_U_B8_G8_R8_A8
);
183 for (i
= 0; i
< h
; i
++) {
184 const float *pRow
= p
;
185 for (j
= 0; j
< w
; j
++) {
187 UNCLAMPED_FLOAT_TO_UBYTE(r
, pRow
[0]);
188 UNCLAMPED_FLOAT_TO_UBYTE(g
, pRow
[1]);
189 UNCLAMPED_FLOAT_TO_UBYTE(b
, pRow
[2]);
190 UNCLAMPED_FLOAT_TO_UBYTE(a
, pRow
[3]);
191 dst
[j
] = (b
<< 24) | (g
<< 16) | (r
<< 8) | a
;
200 /*** PIPE_FORMAT_U_A1_R5_G5_B5 ***/
203 a1r5g5b5_get_tile(struct pipe_surface
*ps
,
204 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
207 = ((const ushort
*) (ps
->region
->map
+ ps
->offset
))
211 assert(ps
->format
== PIPE_FORMAT_U_A1_R5_G5_B5
);
213 for (i
= 0; i
< h
; i
++) {
214 for (j
= 0; j
< w
; j
++) {
215 const ushort pixel
= src
[j
];
216 p
[0] = ((pixel
>> 10) & 0x1f) * (1.0f
/ 31.0f
);
217 p
[1] = ((pixel
>> 5) & 0x1f) * (1.0f
/ 31.0f
);
218 p
[2] = ((pixel
) & 0x1f) * (1.0f
/ 31.0f
);
219 p
[3] = ((pixel
>> 15) ) * 1.0f
;
228 /*** PIPE_FORMAT_U_Z16 ***/
231 * Return each Z value as four floats in [0,1].
234 z16_get_tile(struct pipe_surface
*ps
,
235 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
238 = ((const ushort
*) (ps
->region
->map
+ ps
->offset
))
240 const float scale
= 1.0f
/ 65535.0f
;
244 assert(ps
->format
== PIPE_FORMAT_U_Z16
);
248 for (i
= 0; i
< h
; i
++) {
250 for (j
= 0; j
< w
; j
++) {
254 pRow
[j
* 4 + 3] = src
[j
] * scale
;
264 /*** PIPE_FORMAT_U_L8 ***/
267 l8_get_tile(struct pipe_surface
*ps
,
268 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
271 = ((const ubyte
*) (ps
->region
->map
+ ps
->offset
))
276 assert(ps
->format
== PIPE_FORMAT_U_L8
);
280 for (i
= 0; i
< h
; i
++) {
282 for (j
= 0; j
< w
; j
++) {
285 pRow
[2] = UBYTE_TO_FLOAT(src
[j
]);
295 /*** PIPE_FORMAT_U_A8 ***/
298 a8_get_tile(struct pipe_surface
*ps
,
299 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
302 = ((const ubyte
*) (ps
->region
->map
+ ps
->offset
))
307 assert(ps
->format
== PIPE_FORMAT_U_A8
);
311 for (i
= 0; i
< h
; i
++) {
313 for (j
= 0; j
< w
; j
++) {
317 pRow
[3] = UBYTE_TO_FLOAT(src
[j
]);
326 /*** PIPE_FORMAT_S_R16_G16_B16_A16 ***/
329 r16g16b16a16_get_tile(struct pipe_surface
*ps
,
330 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
333 = ((const short *) (ps
->region
->map
+ ps
->offset
))
334 + (y
* ps
->pitch
+ x
) * 4;
338 assert(ps
->format
== PIPE_FORMAT_S_R16_G16_B16_A16
);
342 for (i
= 0; i
< h
; i
++) {
344 const short *pixel
= src
;
345 for (j
= 0; j
< w
; j
++) {
346 pRow
[0] = SHORT_TO_FLOAT(pixel
[0]);
347 pRow
[1] = SHORT_TO_FLOAT(pixel
[1]);
348 pRow
[2] = SHORT_TO_FLOAT(pixel
[2]);
349 pRow
[3] = SHORT_TO_FLOAT(pixel
[3]);
353 src
+= ps
->pitch
* 4;
360 r16g16b16a16_put_tile(struct pipe_surface
*ps
,
361 unsigned x
, unsigned y
, unsigned w
, unsigned h
,
365 = ((short *) (ps
->region
->map
+ ps
->offset
))
366 + (y
* ps
->pitch
+ x
) * 4;
370 assert(ps
->format
== PIPE_FORMAT_S_R16_G16_B16_A16
);
374 for (i
= 0; i
< h
; i
++) {
375 const float *pRow
= p
;
376 for (j
= 0; j
< w
; j
++) {
378 UNCLAMPED_FLOAT_TO_SHORT(r
, pRow
[0]);
379 UNCLAMPED_FLOAT_TO_SHORT(g
, pRow
[1]);
380 UNCLAMPED_FLOAT_TO_SHORT(b
, pRow
[2]);
381 UNCLAMPED_FLOAT_TO_SHORT(a
, pRow
[3]);
388 dst
+= ps
->pitch
* 4;
395 /*** PIPE_FORMAT_U_I8 ***/
398 i8_get_tile(struct pipe_surface
*ps
,
399 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
402 = ((const ubyte
*) (ps
->region
->map
+ ps
->offset
))
407 assert(ps
->format
== PIPE_FORMAT_U_I8
);
411 for (i
= 0; i
< h
; i
++) {
413 for (j
= 0; j
< w
; j
++) {
417 pRow
[3] = UBYTE_TO_FLOAT(src
[j
]);
426 /*** PIPE_FORMAT_U_A8_L8 ***/
429 a8_l8_get_tile(struct pipe_surface
*ps
,
430 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
433 = ((const ushort
*) (ps
->region
->map
+ ps
->offset
))
438 assert(ps
->format
== PIPE_FORMAT_U_A8_L8
);
442 for (i
= 0; i
< h
; i
++) {
444 for (j
= 0; j
< w
; j
++) {
445 const ushort p
= src
[j
];
448 pRow
[2] = UBYTE_TO_FLOAT(p
& 0xff);
449 pRow
[3] = UBYTE_TO_FLOAT(p
>> 8);
460 /*** PIPE_FORMAT_U_Z32 ***/
463 * Return each Z value as four floats in [0,1].
466 z32_get_tile(struct pipe_surface
*ps
,
467 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
470 = ((const uint
*) (ps
->region
->map
+ ps
->offset
))
472 const double scale
= 1.0 / (double) 0xffffffff;
476 assert(ps
->format
== PIPE_FORMAT_U_Z16
);
480 for (i
= 0; i
< h
; i
++) {
482 for (j
= 0; j
< w
; j
++) {
486 pRow
[j
* 4 + 3] = (float) (scale
* src
[j
]);
494 /*** PIPE_FORMAT_S8_Z24 ***/
497 * Return Z component as four float in [0,1]. Stencil part ignored.
500 s8z24_get_tile(struct pipe_surface
*ps
,
501 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
504 = ((const uint
*) (ps
->region
->map
+ ps
->offset
))
506 const double scale
= 1.0 / ((1 << 24) - 1);
510 assert(ps
->format
== PIPE_FORMAT_S8_Z24
);
514 for (i
= 0; i
< h
; i
++) {
516 for (j
= 0; j
< w
; j
++) {
520 pRow
[j
* 4 + 3] = (float) (scale
* (src
[j
] & 0xffffff));
528 /*** PIPE_FORMAT_Z24_S8 ***/
531 * Return Z component as four float in [0,1]. Stencil part ignored.
534 z24s8_get_tile(struct pipe_surface
*ps
,
535 unsigned x
, unsigned y
, unsigned w
, unsigned h
, float *p
)
538 = ((const uint
*) (ps
->region
->map
+ ps
->offset
))
540 const double scale
= 1.0 / ((1 << 24) - 1);
544 assert(ps
->format
== PIPE_FORMAT_Z24_S8
);
548 for (i
= 0; i
< h
; i
++) {
550 for (j
= 0; j
< w
; j
++) {
554 pRow
[j
* 4 + 3] = (float) (scale
* (src
[j
] >> 8));
563 * Called via pipe->get_tex_surface()
564 * XXX is this in the right place?
566 struct pipe_surface
*
567 softpipe_get_tex_surface(struct pipe_context
*pipe
,
568 struct pipe_texture
*pt
,
569 unsigned face
, unsigned level
, unsigned zslice
)
571 struct softpipe_texture
*spt
= (struct softpipe_texture
*)pt
;
572 struct pipe_surface
*ps
;
573 unsigned offset
; /* in bytes */
575 offset
= spt
->level_offset
[level
];
577 if (pt
->target
== PIPE_TEXTURE_CUBE
) {
578 offset
+= spt
->image_offset
[level
][face
] * pt
->cpp
;
580 else if (pt
->target
== PIPE_TEXTURE_3D
) {
581 offset
+= spt
->image_offset
[level
][zslice
] * pt
->cpp
;
588 ps
= pipe
->winsys
->surface_alloc(pipe
->winsys
, pt
->format
);
591 assert(ps
->refcount
);
592 pipe_region_reference(&ps
->region
, spt
->region
);
594 ps
->width
= pt
->width
[level
];
595 ps
->height
= pt
->height
[level
];
596 ps
->pitch
= spt
->pitch
;
604 * Move raw block of pixels from surface to user memory.
607 softpipe_get_tile(struct pipe_context
*pipe
, struct pipe_surface
*ps
,
608 uint x
, uint y
, uint w
, uint h
,
609 void *p
, int dst_stride
)
611 const uint cpp
= ps
->cpp
;
616 assert(ps
->region
->map
);
618 if (dst_stride
== 0) {
619 dst_stride
= w
* cpp
;
624 pSrc
= ps
->region
->map
+ ps
->offset
+ (y
* ps
->pitch
+ x
) * cpp
;
627 for (i
= 0; i
< h
; i
++) {
628 memcpy(pDest
, pSrc
, w
* cpp
);
630 pSrc
+= ps
->pitch
* cpp
;
636 * Move raw block of pixels from user memory to surface.
639 softpipe_put_tile(struct pipe_context
*pipe
, struct pipe_surface
*ps
,
640 uint x
, uint y
, uint w
, uint h
,
641 const void *p
, int src_stride
)
643 const uint cpp
= ps
->cpp
;
648 assert(ps
->region
->map
);
650 if (src_stride
== 0) {
651 src_stride
= w
* cpp
;
656 pSrc
= (const ubyte
*) p
;
657 pDest
= ps
->region
->map
+ ps
->offset
+ (y
* ps
->pitch
+ x
) * cpp
;
659 for (i
= 0; i
< h
; i
++) {
660 memcpy(pDest
, pSrc
, w
* cpp
);
661 pDest
+= ps
->pitch
* cpp
;
669 softpipe_get_tile_rgba(struct pipe_context
*pipe
,
670 struct pipe_surface
*ps
,
671 uint x
, uint y
, uint w
, uint h
,
674 switch (ps
->format
) {
675 case PIPE_FORMAT_U_A8_R8_G8_B8
:
676 a8r8g8b8_get_tile(ps
, x
, y
, w
, h
, p
);
678 case PIPE_FORMAT_U_B8_G8_R8_A8
:
679 b8g8r8a8_get_tile(ps
, x
, y
, w
, h
, p
);
681 case PIPE_FORMAT_U_A1_R5_G5_B5
:
682 a1r5g5b5_get_tile(ps
, x
, y
, w
, h
, p
);
684 case PIPE_FORMAT_U_L8
:
685 l8_get_tile(ps
, x
, y
, w
, h
, p
);
687 case PIPE_FORMAT_U_A8
:
688 a8_get_tile(ps
, x
, y
, w
, h
, p
);
690 case PIPE_FORMAT_U_I8
:
691 i8_get_tile(ps
, x
, y
, w
, h
, p
);
693 case PIPE_FORMAT_U_A8_L8
:
694 a8_l8_get_tile(ps
, x
, y
, w
, h
, p
);
696 case PIPE_FORMAT_S_R16_G16_B16_A16
:
697 r16g16b16a16_get_tile(ps
, x
, y
, w
, h
, p
);
699 case PIPE_FORMAT_U_Z16
:
700 z16_get_tile(ps
, x
, y
, w
, h
, p
);
702 case PIPE_FORMAT_U_Z32
:
703 z32_get_tile(ps
, x
, y
, w
, h
, p
);
705 case PIPE_FORMAT_S8_Z24
:
706 s8z24_get_tile(ps
, x
, y
, w
, h
, p
);
708 case PIPE_FORMAT_Z24_S8
:
709 z24s8_get_tile(ps
, x
, y
, w
, h
, p
);
719 softpipe_put_tile_rgba(struct pipe_context
*pipe
,
720 struct pipe_surface
*ps
,
721 uint x
, uint y
, uint w
, uint h
,
724 switch (ps
->format
) {
725 case PIPE_FORMAT_U_A8_R8_G8_B8
:
726 a8r8g8b8_put_tile(ps
, x
, y
, w
, h
, p
);
728 case PIPE_FORMAT_U_B8_G8_R8_A8
:
729 b8g8r8a8_put_tile(ps
, x
, y
, w
, h
, p
);
731 case PIPE_FORMAT_U_A1_R5_G5_B5
:
732 /*a1r5g5b5_put_tile(ps, x, y, w, h, p);*/
734 case PIPE_FORMAT_U_L8
:
735 /*l8_put_tile(ps, x, y, w, h, p);*/
737 case PIPE_FORMAT_U_A8
:
738 /*a8_put_tile(ps, x, y, w, h, p);*/
740 case PIPE_FORMAT_U_I8
:
741 /*i8_put_tile(ps, x, y, w, h, p);*/
743 case PIPE_FORMAT_U_A8_L8
:
744 /*a8_l8_put_tile(ps, x, y, w, h, p);*/
746 case PIPE_FORMAT_S_R16_G16_B16_A16
:
747 r16g16b16a16_put_tile(ps
, x
, y
, w
, h
, p
);
749 case PIPE_FORMAT_U_Z16
:
750 /*z16_put_tile(ps, x, y, w, h, p);*/
752 case PIPE_FORMAT_U_Z32
:
753 /*z32_put_tile(ps, x, y, w, h, p);*/
755 case PIPE_FORMAT_S8_Z24
:
756 /*s8z24_put_tile(ps, x, y, w, h, p);*/
758 case PIPE_FORMAT_Z24_S8
:
759 /*z24s8_put_tile(ps, x, y, w, h, p);*/
768 * Copy 2D rect from one place to another.
769 * Position and sizes are in pixels.
772 copy_rect(ubyte
* dst
,
790 dst
+= dst_y
* dst_pitch
;
791 src
+= src_y
* src_pitch
;
794 if (width
== dst_pitch
&& width
== src_pitch
)
795 memcpy(dst
, src
, height
* width
);
797 for (i
= 0; i
< height
; i
++) {
798 memcpy(dst
, src
, width
);
806 /* Upload data to a rectangular sub-region. Lots of choices how to do this:
808 * - memcpy by span to current destination
809 * - upload data as new buffer and blit
811 * Currently always memcpy.
814 sp_surface_data(struct pipe_context
*pipe
,
815 struct pipe_surface
*dst
,
816 unsigned dstx
, unsigned dsty
,
817 const void *src
, unsigned src_pitch
,
818 unsigned srcx
, unsigned srcy
, unsigned width
, unsigned height
)
820 copy_rect(pipe
->region_map(pipe
, dst
->region
) + dst
->offset
,
823 dstx
, dsty
, width
, height
, src
, src_pitch
, srcx
, srcy
);
825 pipe
->region_unmap(pipe
, dst
->region
);
828 /* Assumes all values are within bounds -- no checking at this level -
829 * do it higher up if required.
832 sp_surface_copy(struct pipe_context
*pipe
,
833 struct pipe_surface
*dst
,
834 unsigned dstx
, unsigned dsty
,
835 struct pipe_surface
*src
,
836 unsigned srcx
, unsigned srcy
, unsigned width
, unsigned height
)
838 ubyte
*src_map
, *dst_map
;
839 assert( dst
->cpp
== src
->cpp
);
841 dst_map
= pipe
->region_map(pipe
, dst
->region
);
842 src_map
= pipe
->region_map(pipe
, src
->region
);
843 copy_rect(dst_map
+ dst
->offset
,
848 src_map
+ src
->offset
,
852 pipe
->region_unmap(pipe
, src
->region
);
853 pipe
->region_unmap(pipe
, dst
->region
);
858 get_pointer(struct pipe_surface
*dst
, unsigned x
, unsigned y
)
860 return dst
->region
->map
+ (y
* dst
->pitch
+ x
) * dst
->cpp
;
864 #define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
868 * Fill a rectangular sub-region. Need better logic about when to
869 * push buffers into AGP - will currently do so whenever possible.
872 sp_surface_fill(struct pipe_context
*pipe
,
873 struct pipe_surface
*dst
,
874 unsigned dstx
, unsigned dsty
,
875 unsigned width
, unsigned height
, unsigned value
)
879 assert(dst
->pitch
> 0);
880 assert(width
<= dst
->pitch
);
882 (void)pipe
->region_map(pipe
, dst
->region
);
887 ubyte
*row
= get_pointer(dst
, dstx
, dsty
);
888 for (i
= 0; i
< height
; i
++) {
889 memset(row
, value
, width
);
896 ushort
*row
= (ushort
*) get_pointer(dst
, dstx
, dsty
);
897 for (i
= 0; i
< height
; i
++) {
898 for (j
= 0; j
< width
; j
++)
899 row
[j
] = (ushort
) value
;
906 unsigned *row
= (unsigned *) get_pointer(dst
, dstx
, dsty
);
907 for (i
= 0; i
< height
; i
++) {
908 for (j
= 0; j
< width
; j
++)
916 /* expand the 4-byte clear value to an 8-byte value */
917 ushort
*row
= (ushort
*) get_pointer(dst
, dstx
, dsty
);
918 ushort val0
= UBYTE_TO_USHORT((value
>> 0) & 0xff);
919 ushort val1
= UBYTE_TO_USHORT((value
>> 8) & 0xff);
920 ushort val2
= UBYTE_TO_USHORT((value
>> 16) & 0xff);
921 ushort val3
= UBYTE_TO_USHORT((value
>> 24) & 0xff);
922 for (i
= 0; i
< height
; i
++) {
923 for (j
= 0; j
< width
; j
++) {
929 row
+= dst
->pitch
* 4;
938 pipe
->region_unmap( pipe
, dst
->region
);
943 sp_init_surface_functions(struct softpipe_context
*sp
)
945 sp
->pipe
.get_tile
= softpipe_get_tile
;
946 sp
->pipe
.put_tile
= softpipe_put_tile
;
948 sp
->pipe
.get_tile_rgba
= softpipe_get_tile_rgba
;
949 sp
->pipe
.put_tile_rgba
= softpipe_put_tile_rgba
;
951 sp
->pipe
.surface_data
= sp_surface_data
;
952 sp
->pipe
.surface_copy
= sp_surface_copy
;
953 sp
->pipe
.surface_fill
= sp_surface_fill
;