update a couple MESA_FORMAT_Zxxx occurances
[mesa.git] / src / mesa / swrast / s_buffers.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /** XXX This file should be named s_clear.c */
26
27 #include "glheader.h"
28 #include "colormac.h"
29 #include "macros.h"
30 #include "imports.h"
31 #include "mtypes.h"
32
33 #include "s_accum.h"
34 #include "s_context.h"
35 #include "s_depth.h"
36 #include "s_masking.h"
37 #include "s_stencil.h"
38
39
40 /**
41 * Clear the color buffer when glColorMask is in effect.
42 */
43 static void
44 clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb)
45 {
46 const GLint x = ctx->DrawBuffer->_Xmin;
47 const GLint y = ctx->DrawBuffer->_Ymin;
48 const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
49 const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
50 GLchan clearColor[4];
51 GLint i;
52
53 ASSERT(ctx->Visual.rgbMode);
54 ASSERT(rb->PutRow);
55
56 CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
57 CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
58 CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
59 CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
60
61 for (i = 0; i < height; i++) {
62 GLchan rgba[MAX_WIDTH][4];
63 GLint j;
64 for (j = 0; j < width; j++) {
65 COPY_CHAN4(rgba[j], clearColor);
66 }
67 _swrast_mask_rgba_array( ctx, rb, width, x, y + i, rgba );
68 rb->PutRow(ctx, rb, width, x, y + i, rgba, NULL);
69 }
70 }
71
72
73 /**
74 * Clear color index buffer with masking.
75 */
76 static void
77 clear_ci_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb)
78 {
79 const GLint x = ctx->DrawBuffer->_Xmin;
80 const GLint y = ctx->DrawBuffer->_Ymin;
81 const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
82 const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
83 GLint i;
84
85 ASSERT(!ctx->Visual.rgbMode);
86 ASSERT(rb->PutRow);
87 ASSERT(rb->DataType == GL_UNSIGNED_INT);
88
89 for (i = 0; i < height;i++) {
90 GLuint span[MAX_WIDTH];
91 GLint j;
92 for (j = 0; j < width;j++) {
93 span[j] = ctx->Color.ClearIndex;
94 }
95 _swrast_mask_ci_array(ctx, rb, width, x, y + i, span);
96 rb->PutRow(ctx, rb, width, x, y + i, span, NULL);
97 }
98 }
99
100
101 /**
102 * Clear an rgba color buffer without channel masking.
103 */
104 static void
105 clear_rgba_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
106 {
107 const GLint x = ctx->DrawBuffer->_Xmin;
108 const GLint y = ctx->DrawBuffer->_Ymin;
109 const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
110 const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
111 GLubyte clear8[4];
112 GLushort clear16[4];
113 GLvoid *clearVal;
114 GLint i;
115
116 ASSERT(ctx->Visual.rgbMode);
117
118 ASSERT(ctx->Color.ColorMask[0] &&
119 ctx->Color.ColorMask[1] &&
120 ctx->Color.ColorMask[2] &&
121 ctx->Color.ColorMask[3]);
122
123 ASSERT(rb->PutMonoRow);
124
125 switch (rb->DataType) {
126 case GL_UNSIGNED_BYTE:
127 UNCLAMPED_FLOAT_TO_UBYTE(clear8[0], ctx->Color.ClearColor[0]);
128 UNCLAMPED_FLOAT_TO_UBYTE(clear8[1], ctx->Color.ClearColor[1]);
129 UNCLAMPED_FLOAT_TO_UBYTE(clear8[2], ctx->Color.ClearColor[2]);
130 UNCLAMPED_FLOAT_TO_UBYTE(clear8[3], ctx->Color.ClearColor[3]);
131 clearVal = clear8;
132 break;
133 case GL_UNSIGNED_SHORT:
134 UNCLAMPED_FLOAT_TO_USHORT(clear16[0], ctx->Color.ClearColor[0]);
135 UNCLAMPED_FLOAT_TO_USHORT(clear16[1], ctx->Color.ClearColor[1]);
136 UNCLAMPED_FLOAT_TO_USHORT(clear16[2], ctx->Color.ClearColor[2]);
137 UNCLAMPED_FLOAT_TO_USHORT(clear16[3], ctx->Color.ClearColor[3]);
138 clearVal = clear16;
139 break;
140 case GL_FLOAT:
141 clearVal = ctx->Color.ClearColor;
142 break;
143 default:
144 _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer");
145 return;
146 }
147
148 for (i = 0; i < height; i++) {
149 rb->PutMonoRow(ctx, rb, width, x, y + i, clearVal, NULL);
150 }
151 }
152
153
154 /**
155 * Clear color index buffer without masking.
156 */
157 static void
158 clear_ci_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
159 {
160 const GLint x = ctx->DrawBuffer->_Xmin;
161 const GLint y = ctx->DrawBuffer->_Ymin;
162 const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
163 const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
164 GLubyte clear8;
165 GLushort clear16;
166 GLuint clear32;
167 GLvoid *clearVal;
168 GLint i;
169
170 ASSERT(!ctx->Visual.rgbMode);
171
172 ASSERT((ctx->Color.IndexMask & ((1 << ctx->Visual.indexBits) - 1))
173 == (GLuint) ((1 << ctx->Visual.indexBits) - 1));
174
175 ASSERT(rb->PutMonoRow);
176
177 /* setup clear value */
178 switch (rb->DataType) {
179 case GL_UNSIGNED_BYTE:
180 clear8 = (GLubyte) ctx->Color.ClearIndex;
181 clearVal = &clear8;
182 break;
183 case GL_UNSIGNED_SHORT:
184 clear16 = (GLushort) ctx->Color.ClearIndex;
185 clearVal = &clear16;
186 break;
187 case GL_UNSIGNED_INT:
188 clear32 = ctx->Color.ClearIndex;
189 clearVal = &clear32;
190 break;
191 default:
192 _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer");
193 return;
194 }
195
196 for (i = 0; i < height; i++)
197 rb->PutMonoRow(ctx, rb, width, x, y + i, clearVal, NULL);
198 }
199
200
201 /**
202 * Clear the front/back/left/right/aux color buffers.
203 * This function is usually only called if the device driver can't
204 * clear its own color buffers for some reason (such as with masking).
205 */
206 static void
207 clear_color_buffers(GLcontext *ctx)
208 {
209 GLboolean masking;
210 GLuint i;
211
212 if (ctx->Visual.rgbMode) {
213 if (ctx->Color.ColorMask[0] &&
214 ctx->Color.ColorMask[1] &&
215 ctx->Color.ColorMask[2] &&
216 ctx->Color.ColorMask[3]) {
217 masking = GL_FALSE;
218 }
219 else {
220 masking = GL_TRUE;
221 }
222 }
223 else {
224 const GLuint indexBits = (1 << ctx->Visual.indexBits) - 1;
225 if ((ctx->Color.IndexMask & indexBits) == indexBits) {
226 masking = GL_FALSE;
227 }
228 else {
229 masking = GL_TRUE;
230 }
231 }
232
233 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers[0]; i++) {
234 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][i];
235 if (ctx->Visual.rgbMode) {
236 if (masking) {
237 clear_rgba_buffer_with_masking(ctx, rb);
238 }
239 else {
240 clear_rgba_buffer(ctx, rb);
241 }
242 }
243 else {
244 if (masking) {
245 clear_ci_buffer_with_masking(ctx, rb);
246 }
247 else {
248 clear_ci_buffer(ctx, rb);
249 }
250 }
251 }
252 }
253
254
255 /**
256 * Called via the device driver's ctx->Driver.Clear() function if the
257 * device driver can't clear one or more of the buffers itself.
258 * \param mask bitfield of BUFER_BIT_* values indicating which renderbuffers
259 * are to be cleared.
260 * \param all if GL_TRUE, clear whole buffer, else clear specified region.
261 */
262 void
263 _swrast_Clear(GLcontext *ctx, GLbitfield mask,
264 GLboolean all, GLint x, GLint y, GLint width, GLint height)
265 {
266 SWcontext *swrast = SWRAST_CONTEXT(ctx);
267
268 (void) all; (void) x; (void) y; (void) width; (void) height;
269
270 #ifdef DEBUG_FOO
271 {
272 const GLbitfield legalBits =
273 BUFFER_BIT_FRONT_LEFT |
274 BUFFER_BIT_FRONT_RIGHT |
275 BUFFER_BIT_BACK_LEFT |
276 BUFFER_BIT_BACK_RIGHT |
277 BUFFER_BIT_DEPTH |
278 BUFFER_BIT_STENCIL |
279 BUFFER_BIT_ACCUM |
280 BUFFER_BIT_AUX0 |
281 BUFFER_BIT_AUX1 |
282 BUFFER_BIT_AUX2 |
283 BUFFER_BIT_AUX3;
284 assert((mask & (~legalBits)) == 0);
285 }
286 #endif
287
288 RENDER_START(swrast,ctx);
289
290 /* do software clearing here */
291 if (mask) {
292 if (mask & ctx->DrawBuffer->_ColorDrawBufferMask[0]) {
293 clear_color_buffers(ctx);
294 }
295 if (mask & BUFFER_BIT_DEPTH) {
296 _swrast_clear_depth_buffer(ctx, ctx->DrawBuffer->_DepthBuffer);
297 }
298 if (mask & BUFFER_BIT_ACCUM) {
299 _swrast_clear_accum_buffer(ctx,
300 ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
301 }
302 if (mask & BUFFER_BIT_STENCIL) {
303 _swrast_clear_stencil_buffer(ctx, ctx->DrawBuffer->_StencilBuffer);
304 }
305 }
306
307 RENDER_FINISH(swrast,ctx);
308 }