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 "main/imports.h"
33 #include "main/macros.h"
37 * Softpipe surface functions.
38 * Basically, create surface of a particular type, then plug in default
39 * read/write_quad and get/put_tile() functions.
40 * Note that these quad funcs assume the buffer/region is in a linear
41 * layout with Y=0=top.
42 * If we had swizzled/AOS buffers the read/write quad functions could be
43 * simplified a lot....
48 /*** PIPE_FORMAT_U_A8_R8_G8_B8 ***/
51 a8r8g8b8_read_quad_f_swz(struct softpipe_surface
*sps
, GLint x
, GLint y
,
52 GLfloat (*rrrr
)[QUAD_SIZE
])
55 = ((const GLuint
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
56 + y
* sps
->surface
.region
->pitch
+ x
;
59 assert(sps
->surface
.format
== PIPE_FORMAT_U_A8_R8_G8_B8
);
60 assert(x
< sps
->surface
.width
- 1);
61 assert(y
< 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 GLuint 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
, GLint x
, GLint y
,
77 GLfloat (*rrrr
)[QUAD_SIZE
])
80 = ((GLuint
*) (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 GLuint x
, GLuint y
, GLuint w
, GLuint h
, GLfloat
*p
)
104 = ((const GLuint
*) (ps
->region
->map
+ ps
->offset
))
105 + y
* ps
->region
->pitch
+ x
;
108 assert(ps
->format
== PIPE_FORMAT_U_A8_R8_G8_B8
);
111 assert(x
+ w
<= ps
->width
);
112 assert(y
+ h
<= ps
->height
);
115 if (x
+ w
> ps
->width
)
117 if (y
+ h
> ps
->height
)
120 for (i
= 0; i
< h
; i
++) {
121 for (j
= 0; j
< w
; j
++) {
122 const GLuint pixel
= src
[j
];
123 p
[0] = UBYTE_TO_FLOAT((pixel
>> 16) & 0xff);
124 p
[1] = UBYTE_TO_FLOAT((pixel
>> 8) & 0xff);
125 p
[2] = UBYTE_TO_FLOAT((pixel
>> 0) & 0xff);
126 p
[3] = UBYTE_TO_FLOAT((pixel
>> 24) & 0xff);
129 src
+= ps
->region
->pitch
;
134 /*** PIPE_FORMAT_U_A1_R5_G5_B5 ***/
137 a1r5g5b5_get_tile(struct pipe_surface
*ps
,
138 GLuint x
, GLuint y
, GLuint w
, GLuint h
, GLfloat
*p
)
141 = ((const GLushort
*) (ps
->region
->map
+ ps
->offset
))
142 + y
* ps
->region
->pitch
+ x
;
145 assert(ps
->format
== PIPE_FORMAT_U_A1_R5_G5_B5
);
147 for (i
= 0; i
< h
; i
++) {
148 for (j
= 0; j
< w
; j
++) {
149 const GLushort pixel
= src
[j
];
150 p
[0] = ((pixel
>> 10) & 0x1f) * (1.0 / 31);
151 p
[1] = ((pixel
>> 5) & 0x1f) * (1.0 / 31);
152 p
[2] = ((pixel
) & 0x1f) * (1.0 / 31);
153 p
[3] = ((pixel
>> 15) );
156 src
+= ps
->region
->pitch
;
162 /*** PIPE_FORMAT_U_Z16 ***/
165 z16_read_quad_z(struct softpipe_surface
*sps
,
166 GLint x
, GLint y
, GLuint zzzz
[QUAD_SIZE
])
169 = ((const GLushort
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
170 + y
* sps
->surface
.region
->pitch
+ x
;
172 assert(sps
->surface
.format
== PIPE_FORMAT_U_Z16
);
174 /* converting GLushort to GLuint: */
177 src
+= sps
->surface
.region
->pitch
;
183 z16_write_quad_z(struct softpipe_surface
*sps
,
184 GLint x
, GLint y
, const GLuint zzzz
[QUAD_SIZE
])
187 = ((GLushort
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
188 + y
* sps
->surface
.region
->pitch
+ x
;
190 assert(sps
->surface
.format
== PIPE_FORMAT_U_Z16
);
192 /* converting GLuint to GLushort: */
195 dst
+= sps
->surface
.region
->pitch
;
201 /*** PIPE_FORMAT_U_Z32 ***/
204 z32_read_quad_z(struct softpipe_surface
*sps
,
205 GLint x
, GLint y
, GLuint zzzz
[QUAD_SIZE
])
208 = ((GLuint
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
209 + y
* sps
->surface
.region
->pitch
+ x
;
211 assert(sps
->surface
.format
== PIPE_FORMAT_U_Z32
);
215 src
+= sps
->surface
.region
->pitch
;
221 z32_write_quad_z(struct softpipe_surface
*sps
,
222 GLint x
, GLint y
, const GLuint zzzz
[QUAD_SIZE
])
225 = ((GLuint
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
226 + y
* sps
->surface
.region
->pitch
+ x
;
228 assert(sps
->surface
.format
== PIPE_FORMAT_U_Z32
);
232 dst
+= sps
->surface
.region
->pitch
;
238 /*** PIPE_FORMAT_S8_Z24 ***/
241 s8z24_read_quad_z(struct softpipe_surface
*sps
,
242 GLint x
, GLint y
, GLuint zzzz
[QUAD_SIZE
])
244 static const GLuint mask
= 0x00ffffff;
246 = ((GLuint
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
247 + y
* sps
->surface
.region
->pitch
+ x
;
249 assert(sps
->surface
.format
== PIPE_FORMAT_S8_Z24
);
251 /* extract lower three bytes */
252 zzzz
[0] = src
[0] & mask
;
253 zzzz
[1] = src
[1] & mask
;
254 src
+= sps
->surface
.region
->pitch
;
255 zzzz
[2] = src
[0] & mask
;
256 zzzz
[3] = src
[1] & mask
;
260 s8z24_write_quad_z(struct softpipe_surface
*sps
,
261 GLint x
, GLint y
, const GLuint zzzz
[QUAD_SIZE
])
263 static const GLuint mask
= 0xff000000;
265 = ((GLuint
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
266 + y
* sps
->surface
.region
->pitch
+ x
;
268 assert(sps
->surface
.format
== PIPE_FORMAT_S8_Z24
);
269 assert(zzzz
[0] <= 0xffffff);
271 dst
[0] = (dst
[0] & mask
) | zzzz
[0];
272 dst
[1] = (dst
[1] & mask
) | zzzz
[1];
273 dst
+= sps
->surface
.region
->pitch
;
274 dst
[0] = (dst
[0] & mask
) | zzzz
[2];
275 dst
[1] = (dst
[1] & mask
) | zzzz
[3];
279 s8z24_read_quad_stencil(struct softpipe_surface
*sps
,
280 GLint x
, GLint y
, GLubyte ssss
[QUAD_SIZE
])
283 = ((GLuint
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
284 + y
* sps
->surface
.region
->pitch
+ x
;
286 assert(sps
->surface
.format
== PIPE_FORMAT_S8_Z24
);
288 ssss
[0] = src
[0] >> 24;
289 ssss
[1] = src
[1] >> 24;
290 src
+= sps
->surface
.region
->pitch
;
291 ssss
[2] = src
[0] >> 24;
292 ssss
[3] = src
[1] >> 24;
296 s8z24_write_quad_stencil(struct softpipe_surface
*sps
,
297 GLint x
, GLint y
, const GLubyte ssss
[QUAD_SIZE
])
299 static const GLuint mask
= 0x00ffffff;
301 = ((GLuint
*) (sps
->surface
.region
->map
+ sps
->surface
.offset
))
302 + y
* sps
->surface
.region
->pitch
+ x
;
304 assert(sps
->surface
.format
== PIPE_FORMAT_S8_Z24
);
306 dst
[0] = (dst
[0] & mask
) | (ssss
[0] << 24);
307 dst
[1] = (dst
[1] & mask
) | (ssss
[1] << 24);
308 dst
+= sps
->surface
.region
->pitch
;
309 dst
[0] = (dst
[0] & mask
) | (ssss
[2] << 24);
310 dst
[1] = (dst
[1] & mask
) | (ssss
[3] << 24);
314 /*** PIPE_FORMAT_U_S8 ***/
317 s8_read_quad_stencil(struct softpipe_surface
*sps
,
318 GLint x
, GLint y
, GLubyte ssss
[QUAD_SIZE
])
321 = sps
->surface
.region
->map
+ sps
->surface
.offset
322 + y
* sps
->surface
.region
->pitch
+ x
;
324 assert(sps
->surface
.format
== PIPE_FORMAT_U_S8
);
328 src
+= sps
->surface
.region
->pitch
;
334 s8_write_quad_stencil(struct softpipe_surface
*sps
,
335 GLint x
, GLint y
, const GLubyte ssss
[QUAD_SIZE
])
338 = sps
->surface
.region
->map
+ sps
->surface
.offset
339 + y
* sps
->surface
.region
->pitch
+ x
;
341 assert(sps
->surface
.format
== PIPE_FORMAT_U_S8
);
345 dst
+= sps
->surface
.region
->pitch
;
352 softpipe_init_surface_funcs(struct softpipe_surface
*sps
)
354 switch (sps
->surface
.format
) {
355 case PIPE_FORMAT_U_A8_R8_G8_B8
:
356 sps
->read_quad_f_swz
= a8r8g8b8_read_quad_f_swz
;
357 sps
->write_quad_f_swz
= a8r8g8b8_write_quad_f_swz
;
358 sps
->surface
.get_tile
= a8r8g8b8_get_tile
;
359 case PIPE_FORMAT_U_A1_R5_G5_B5
:
360 sps
->surface
.get_tile
= a1r5g5b5_get_tile
;
362 case PIPE_FORMAT_U_Z16
:
363 sps
->read_quad_z
= z16_read_quad_z
;
364 sps
->write_quad_z
= z16_write_quad_z
;
366 case PIPE_FORMAT_U_Z32
:
367 sps
->read_quad_z
= z32_read_quad_z
;
368 sps
->write_quad_z
= z32_write_quad_z
;
370 case PIPE_FORMAT_S8_Z24
:
371 sps
->read_quad_z
= s8z24_read_quad_z
;
372 sps
->write_quad_z
= s8z24_write_quad_z
;
373 sps
->read_quad_stencil
= s8z24_read_quad_stencil
;
374 sps
->write_quad_stencil
= s8z24_write_quad_stencil
;
376 case PIPE_FORMAT_U_S8
:
377 sps
->read_quad_stencil
= s8_read_quad_stencil
;
378 sps
->write_quad_stencil
= s8_write_quad_stencil
;
386 static struct pipe_surface
*
387 softpipe_surface_alloc(struct pipe_context
*pipe
, GLuint pipeFormat
)
389 struct softpipe_surface
*sps
= CALLOC_STRUCT(softpipe_surface
);
393 assert(pipeFormat
< PIPE_FORMAT_COUNT
);
395 sps
->surface
.format
= pipeFormat
;
396 sps
->surface
.refcount
= 1;
397 softpipe_init_surface_funcs(sps
);
399 return &sps
->surface
;
407 * Called via pipe->get_tex_surface()
408 * XXX is this in the right place?
410 struct pipe_surface
*
411 softpipe_get_tex_surface(struct pipe_context
*pipe
,
412 struct pipe_mipmap_tree
*mt
,
413 GLuint face
, GLuint level
, GLuint zslice
)
415 struct pipe_surface
*ps
;
416 GLuint offset
; /* in bytes */
418 offset
= mt
->level
[level
].level_offset
;
420 if (mt
->target
== GL_TEXTURE_CUBE_MAP_ARB
) {
421 offset
+= mt
->level
[level
].image_offset
[face
] * mt
->cpp
;
423 else if (mt
->target
== GL_TEXTURE_3D
) {
424 offset
+= mt
->level
[level
].image_offset
[zslice
] * mt
->cpp
;
431 ps
= pipe
->surface_alloc(pipe
, mt
->format
);
434 assert(ps
->refcount
);
435 ps
->region
= mt
->region
;
436 ps
->width
= mt
->level
[level
].width
;
437 ps
->height
= mt
->level
[level
].height
;
445 sp_init_surface_functions(struct softpipe_context
*sp
)
447 sp
->pipe
.surface_alloc
= softpipe_surface_alloc
;