s/Z24_S8/S8_Z24/ (stencil is in the high byte)
[mesa.git] / src / mesa / pipe / softpipe / sp_surface.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
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:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
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.
25 *
26 **************************************************************************/
27
28 #include "sp_context.h"
29 #include "sp_state.h"
30 #include "sp_surface.h"
31 #include "pipe/p_defines.h"
32 #include "main/imports.h"
33
34
35 /**
36 * Softpipe surface functions.
37 * Basically, create surface of a particular type, then plug in default
38 * read/write_quad functions.
39 * Note that these quad funcs assume the buffer/region is in a linear
40 * layout with Y=0=bottom.
41 * If we had swizzled/AOS buffers the read/write functions could be
42 * simplified a lot....
43 */
44
45
46 #if 000 /* OLD... should be recycled... */
47 static void rgba8_read_quad_f( struct softpipe_surface *gs,
48 GLint x, GLint y,
49 GLfloat (*rgba)[NUM_CHANNELS] )
50 {
51 GLuint i, j, k = 0;
52
53 for (i = 0; i < 2; i++) {
54 for (j = 0; j < 2; j++, k++) {
55 GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
56 rgba[k][0] = ptr[0] * (1.0 / 255.0);
57 rgba[k][1] = ptr[1] * (1.0 / 255.0);
58 rgba[k][2] = ptr[2] * (1.0 / 255.0);
59 rgba[k][3] = ptr[3] * (1.0 / 255.0);
60 }
61 }
62 }
63
64 static void rgba8_read_quad_f_swz( struct softpipe_surface *gs,
65 GLint x, GLint y,
66 GLfloat (*rrrr)[QUAD_SIZE] )
67 {
68 GLuint i, j, k = 0;
69
70 for (i = 0; i < 2; i++) {
71 for (j = 0; j < 2; j++, k++) {
72 GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
73 rrrr[0][k] = ptr[0] * (1.0 / 255.0);
74 rrrr[1][k] = ptr[1] * (1.0 / 255.0);
75 rrrr[2][k] = ptr[2] * (1.0 / 255.0);
76 rrrr[3][k] = ptr[3] * (1.0 / 255.0);
77 }
78 }
79 }
80
81 static void rgba8_write_quad_f( struct softpipe_surface *gs,
82 GLint x, GLint y,
83 GLfloat (*rgba)[NUM_CHANNELS] )
84 {
85 GLuint i, j, k = 0;
86
87 for (i = 0; i < 2; i++) {
88 for (j = 0; j < 2; j++, k++) {
89 GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
90 ptr[0] = rgba[k][0] * 255.0;
91 ptr[1] = rgba[k][1] * 255.0;
92 ptr[2] = rgba[k][2] * 255.0;
93 ptr[3] = rgba[k][3] * 255.0;
94 }
95 }
96 }
97
98 static void rgba8_write_quad_f_swz( struct softpipe_surface *gs,
99 GLint x, GLint y,
100 GLfloat (*rrrr)[QUAD_SIZE] )
101 {
102 GLuint i, j, k = 0;
103
104 for (i = 0; i < 2; i++) {
105 for (j = 0; j < 2; j++, k++) {
106 GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
107 ptr[0] = rrrr[0][k] * 255.0;
108 ptr[1] = rrrr[1][k] * 255.0;
109 ptr[2] = rrrr[2][k] * 255.0;
110 ptr[3] = rrrr[3][k] * 255.0;
111 }
112 }
113 }
114
115 static void rgba8_read_quad_ub( struct softpipe_surface *gs,
116 GLint x, GLint y,
117 GLubyte (*rgba)[NUM_CHANNELS] )
118 {
119 GLuint i, j, k = 0;
120
121 for (i = 0; i < 2; i++) {
122 for (j = 0; j < 2; j++, k++) {
123 GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
124 rgba[k][0] = ptr[0];
125 rgba[k][1] = ptr[1];
126 rgba[k][2] = ptr[2];
127 rgba[k][3] = ptr[3];
128 }
129 }
130 }
131
132 static void rgba8_write_quad_ub( struct softpipe_surface *gs,
133 GLint x, GLint y,
134 GLubyte (*rgba)[NUM_CHANNELS] )
135 {
136 GLuint i, j, k = 0;
137
138 for (i = 0; i < 2; i++) {
139 for (j = 0; j < 2; j++, k++) {
140 GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4;
141 ptr[0] = rgba[k][0];
142 ptr[1] = rgba[k][1];
143 ptr[2] = rgba[k][2];
144 ptr[3] = rgba[k][3];
145 }
146 }
147 }
148
149 #endif
150
151
152
153 static void
154 z16_read_quad_z(struct softpipe_surface *sps,
155 GLint x, GLint y, GLuint zzzz[QUAD_SIZE])
156 {
157 const GLushort *src
158 = (GLushort *) sps->surface.region->map + y * sps->surface.region->pitch + x;
159
160 assert(sps->surface.format == PIPE_FORMAT_U_Z16);
161
162 /* converting GLushort to GLuint: */
163 zzzz[0] = src[0];
164 zzzz[1] = src[1];
165 src += sps->surface.region->pitch;
166 zzzz[2] = src[0];
167 zzzz[3] = src[1];
168 }
169
170 static void
171 z16_write_quad_z(struct softpipe_surface *sps,
172 GLint x, GLint y, const GLuint zzzz[QUAD_SIZE])
173 {
174 GLushort *dst = (GLushort *) sps->surface.region->map + y * sps->surface.region->pitch + x;
175
176 assert(sps->surface.format == PIPE_FORMAT_U_Z16);
177
178 /* converting GLuint to GLushort: */
179 dst[0] = zzzz[0];
180 dst[1] = zzzz[1];
181 dst += sps->surface.region->pitch;
182 dst[0] = zzzz[2];
183 dst[1] = zzzz[3];
184 }
185
186 static void
187 z32_read_quad_z(struct softpipe_surface *sps,
188 GLint x, GLint y, GLuint zzzz[QUAD_SIZE])
189 {
190 const GLuint *src
191 = (GLuint *) sps->surface.region->map + y * sps->surface.region->pitch + x;
192
193 assert(sps->surface.format == PIPE_FORMAT_U_Z32);
194
195 zzzz[0] = src[0];
196 zzzz[1] = src[1];
197 src += sps->surface.region->pitch;
198 zzzz[2] = src[0];
199 zzzz[3] = src[1];
200 }
201
202 static void
203 z32_write_quad_z(struct softpipe_surface *sps,
204 GLint x, GLint y, const GLuint zzzz[QUAD_SIZE])
205 {
206 GLuint *dst = (GLuint *) sps->surface.region->map + y * sps->surface.region->pitch + x;
207
208 assert(sps->surface.format == PIPE_FORMAT_U_Z32);
209
210 dst[0] = zzzz[0];
211 dst[1] = zzzz[1];
212 dst += sps->surface.region->pitch;
213 dst[0] = zzzz[2];
214 dst[1] = zzzz[3];
215 }
216
217 static void
218 s8z24_read_quad_z(struct softpipe_surface *sps,
219 GLint x, GLint y, GLuint zzzz[QUAD_SIZE])
220 {
221 static const GLuint mask = 0x00ffffff;
222 const GLuint *src
223 = (GLuint *) sps->surface.region->map + y * sps->surface.region->pitch + x;
224
225 assert(sps->surface.format == PIPE_FORMAT_S8_Z24);
226
227 zzzz[0] = src[0] & mask;
228 zzzz[1] = src[1] & mask;
229 src += sps->surface.region->pitch;
230 zzzz[2] = src[0] & mask;
231 zzzz[3] = src[1] & mask;
232 }
233
234 static void
235 s8z24_write_quad_z(struct softpipe_surface *sps,
236 GLint x, GLint y, const GLuint zzzz[QUAD_SIZE])
237 {
238 static const GLuint mask = 0xff000000;
239 GLuint *dst = (GLuint *) sps->surface.region->map + y * sps->surface.region->pitch + x;
240
241 assert(sps->surface.format == PIPE_FORMAT_S8_Z24);
242 assert(zzzz[0] <= 0xffffff);
243
244 dst[0] = (dst[0] & mask) | zzzz[0];
245 dst[1] = (dst[1] & mask) | zzzz[1];
246 dst += sps->surface.region->pitch;
247 dst[0] = (dst[0] & mask) | zzzz[2];
248 dst[1] = (dst[1] & mask) | zzzz[3];
249 }
250
251 static void
252 s8z24_read_quad_stencil(struct softpipe_surface *sps,
253 GLint x, GLint y, GLubyte ssss[QUAD_SIZE])
254 {
255 const GLuint *src
256 = (GLuint *) sps->surface.region->map + y * sps->surface.region->pitch + x;
257
258 assert(sps->surface.format == PIPE_FORMAT_S8_Z24);
259
260 ssss[0] = src[0] >> 24;
261 ssss[1] = src[1] >> 24;
262 src += sps->surface.region->pitch;
263 ssss[2] = src[0] >> 24;
264 ssss[3] = src[1] >> 24;
265 }
266
267 static void
268 s8z24_write_quad_stencil(struct softpipe_surface *sps,
269 GLint x, GLint y, const GLubyte ssss[QUAD_SIZE])
270 {
271 static const GLuint mask = 0x00ffffff;
272 GLuint *dst = (GLuint *) sps->surface.region->map + y * sps->surface.region->pitch + x;
273
274 assert(sps->surface.format == PIPE_FORMAT_S8_Z24);
275
276 dst[0] = (dst[0] & mask) | (ssss[0] << 24);
277 dst[1] = (dst[1] & mask) | (ssss[1] << 24);
278 dst += sps->surface.region->pitch;
279 dst[0] = (dst[0] & mask) | (ssss[2] << 24);
280 dst[1] = (dst[1] & mask) | (ssss[3] << 24);
281 }
282
283
284 static void
285 s8_read_quad_stencil(struct softpipe_surface *sps,
286 GLint x, GLint y, GLubyte ssss[QUAD_SIZE])
287 {
288 const GLubyte *src
289 = sps->surface.region->map + y * sps->surface.region->pitch + x;
290
291 assert(sps->surface.format == PIPE_FORMAT_U_S8);
292
293 ssss[0] = src[0];
294 ssss[1] = src[1];
295 src += sps->surface.region->pitch;
296 ssss[2] = src[0];
297 ssss[3] = src[1];
298 }
299
300 static void
301 s8_write_quad_stencil(struct softpipe_surface *sps,
302 GLint x, GLint y, const GLubyte ssss[QUAD_SIZE])
303 {
304 GLubyte *dst
305 = sps->surface.region->map + y * sps->surface.region->pitch + x;
306
307 assert(sps->surface.format == PIPE_FORMAT_U_S8);
308
309 dst[0] = ssss[0];
310 dst[1] = ssss[1];
311 dst += sps->surface.region->pitch;
312 dst[0] = ssss[2];
313 dst[1] = ssss[3];
314 }
315
316
317
318 static void
319 init_quad_funcs(struct softpipe_surface *sps)
320 {
321 switch (sps->surface.format) {
322 case PIPE_FORMAT_U_Z16:
323 sps->read_quad_z = z16_read_quad_z;
324 sps->write_quad_z = z16_write_quad_z;
325 break;
326 case PIPE_FORMAT_U_Z32:
327 sps->read_quad_z = z32_read_quad_z;
328 sps->write_quad_z = z32_write_quad_z;
329 break;
330 case PIPE_FORMAT_S8_Z24:
331 sps->read_quad_z = s8z24_read_quad_z;
332 sps->write_quad_z = s8z24_write_quad_z;
333 sps->read_quad_stencil = s8z24_read_quad_stencil;
334 sps->write_quad_stencil = s8z24_write_quad_stencil;
335 break;
336 case PIPE_FORMAT_U_S8:
337 sps->read_quad_stencil = s8_read_quad_stencil;
338 sps->write_quad_stencil = s8_write_quad_stencil;
339 break;
340 default:
341 assert(0);
342 }
343 }
344
345
346 static struct pipe_surface *
347 sp_surface_alloc(struct pipe_context *pipe, GLenum format)
348 {
349 struct softpipe_surface *sps = CALLOC_STRUCT(softpipe_surface);
350 if (!sps)
351 return NULL;
352
353 sps->surface.format = format;
354 init_quad_funcs(sps);
355
356 return &sps->surface;
357 }
358
359
360 void
361 sp_init_surface_functions(struct softpipe_context *sp)
362 {
363 sp->pipe.surface_alloc = sp_surface_alloc;
364 }