2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
28 * glClearColor, glClearIndex, glClear() functions.
45 _mesa_ClearIndex( GLfloat c )
47 GET_CURRENT_CONTEXT(ctx);
49 ctx->Color.ClearIndex = (GLuint) c;
54 * Specify the clear values for the color buffers.
56 * \param red red color component.
57 * \param green green color component.
58 * \param blue blue color component.
59 * \param alpha alpha component.
63 * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a
64 * change, flushes the vertices and notifies the driver via the
65 * dd_function_table::ClearColor callback.
68 _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
70 GET_CURRENT_CONTEXT(ctx);
72 ctx->Color.ClearColor.f[0] = red;
73 ctx->Color.ClearColor.f[1] = green;
74 ctx->Color.ClearColor.f[2] = blue;
75 ctx->Color.ClearColor.f[3] = alpha;
80 * GL_EXT_texture_integer
83 _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a)
85 GET_CURRENT_CONTEXT(ctx);
87 ctx->Color.ClearColor.i[0] = r;
88 ctx->Color.ClearColor.i[1] = g;
89 ctx->Color.ClearColor.i[2] = b;
90 ctx->Color.ClearColor.i[3] = a;
95 * GL_EXT_texture_integer
98 _mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
100 GET_CURRENT_CONTEXT(ctx);
102 ctx->Color.ClearColor.ui[0] = r;
103 ctx->Color.ClearColor.ui[1] = g;
104 ctx->Color.ClearColor.ui[2] = b;
105 ctx->Color.ClearColor.ui[3] = a;
112 * \param mask bit-mask indicating the buffers to be cleared.
114 * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState
115 * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin,
116 * etc. If the rasterization mode is set to GL_RENDER then requests the driver
117 * to clear the buffers, via the dd_function_table::Clear callback.
120 _mesa_Clear( GLbitfield mask )
122 GET_CURRENT_CONTEXT(ctx);
123 FLUSH_VERTICES(ctx, 0);
125 FLUSH_CURRENT(ctx, 0);
127 if (MESA_VERBOSE & VERBOSE_API)
128 _mesa_debug(ctx, "glClear 0x%x\n", mask);
130 if (mask & ~(GL_COLOR_BUFFER_BIT |
131 GL_DEPTH_BUFFER_BIT |
132 GL_STENCIL_BUFFER_BIT |
133 GL_ACCUM_BUFFER_BIT)) {
134 /* invalid bit set */
135 _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);
139 /* Accumulation buffers were removed in core contexts, and they never
140 * existed in OpenGL ES.
142 if ((mask & GL_ACCUM_BUFFER_BIT) != 0
143 && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) {
144 _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)");
149 _mesa_update_state( ctx ); /* update _Xmin, etc */
152 if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
153 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
154 "glClear(incomplete framebuffer)");
158 if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 ||
159 ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax ||
160 ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax)
163 if (ctx->RasterDiscard)
166 if (ctx->RenderMode == GL_RENDER) {
167 GLbitfield bufferMask;
169 /* don't clear depth buffer if depth writing disabled */
170 if (!ctx->Depth.Mask)
171 mask &= ~GL_DEPTH_BUFFER_BIT;
173 /* Build the bitmask to send to device driver's Clear function.
174 * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4
175 * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the
176 * BUFFER_BIT_COLORn flags.
179 if (mask & GL_COLOR_BUFFER_BIT) {
181 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
182 bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]);
186 if ((mask & GL_DEPTH_BUFFER_BIT)
187 && ctx->DrawBuffer->Visual.haveDepthBuffer) {
188 bufferMask |= BUFFER_BIT_DEPTH;
191 if ((mask & GL_STENCIL_BUFFER_BIT)
192 && ctx->DrawBuffer->Visual.haveStencilBuffer) {
193 bufferMask |= BUFFER_BIT_STENCIL;
196 if ((mask & GL_ACCUM_BUFFER_BIT)
197 && ctx->DrawBuffer->Visual.haveAccumBuffer) {
198 bufferMask |= BUFFER_BIT_ACCUM;
201 ASSERT(ctx->Driver.Clear);
202 ctx->Driver.Clear(ctx, bufferMask);
207 /** Returned by make_color_buffer_mask() for errors */
208 #define INVALID_MASK ~0x0
212 * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
213 * BUFFER_BIT_x values.
214 * Return INVALID_MASK if the drawbuffer value is invalid.
217 make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
219 const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
220 GLbitfield mask = 0x0;
222 /* From the GL 4.0 specification:
223 * If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is
224 * specified by passing i as the parameter drawbuffer, and value
225 * points to a four-element vector specifying the R, G, B, and A
226 * color to clear that draw buffer to. If the draw buffer is one
227 * of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
228 * multiple buffers, each selected buffer is cleared to the same
231 * Note that "drawbuffer" and "draw buffer" have different meaning.
232 * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's
233 * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK,
236 if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
240 switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) {
242 if (att[BUFFER_FRONT_LEFT].Renderbuffer)
243 mask |= BUFFER_BIT_FRONT_LEFT;
244 if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
245 mask |= BUFFER_BIT_FRONT_RIGHT;
248 if (att[BUFFER_BACK_LEFT].Renderbuffer)
249 mask |= BUFFER_BIT_BACK_LEFT;
250 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
251 mask |= BUFFER_BIT_BACK_RIGHT;
254 if (att[BUFFER_FRONT_LEFT].Renderbuffer)
255 mask |= BUFFER_BIT_FRONT_LEFT;
256 if (att[BUFFER_BACK_LEFT].Renderbuffer)
257 mask |= BUFFER_BIT_BACK_LEFT;
260 if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
261 mask |= BUFFER_BIT_FRONT_RIGHT;
262 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
263 mask |= BUFFER_BIT_BACK_RIGHT;
265 case GL_FRONT_AND_BACK:
266 if (att[BUFFER_FRONT_LEFT].Renderbuffer)
267 mask |= BUFFER_BIT_FRONT_LEFT;
268 if (att[BUFFER_BACK_LEFT].Renderbuffer)
269 mask |= BUFFER_BIT_BACK_LEFT;
270 if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
271 mask |= BUFFER_BIT_FRONT_RIGHT;
272 if (att[BUFFER_BACK_RIGHT].Renderbuffer)
273 mask |= BUFFER_BIT_BACK_RIGHT;
277 GLuint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
279 if (buf >= 0 && att[buf].Renderbuffer) {
292 * Clear signed integer color buffer or stencil buffer (not depth).
295 _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
297 GET_CURRENT_CONTEXT(ctx);
298 FLUSH_VERTICES(ctx, 0);
300 FLUSH_CURRENT(ctx, 0);
303 _mesa_update_state( ctx );
308 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
310 * "ClearBuffer generates an INVALID VALUE error if buffer is
311 * COLOR and drawbuffer is less than zero, or greater than the
312 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
313 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
315 if (drawbuffer != 0) {
316 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
320 else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer && !ctx->RasterDiscard) {
321 /* Save current stencil clear value, set to 'value', do the
322 * stencil clear and restore the clear value.
323 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
326 const GLuint clearSave = ctx->Stencil.Clear;
327 ctx->Stencil.Clear = *value;
328 ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL);
329 ctx->Stencil.Clear = clearSave;
334 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
335 if (mask == INVALID_MASK) {
336 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
340 else if (mask && !ctx->RasterDiscard) {
341 union gl_color_union clearSave;
344 clearSave = ctx->Color.ClearColor;
346 COPY_4V(ctx->Color.ClearColor.i, value);
347 /* clear buffer(s) */
348 ctx->Driver.Clear(ctx, mask);
350 ctx->Color.ClearColor = clearSave;
355 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
357 * "The result of ClearBuffer is undefined if no conversion between
358 * the type of the specified value and the type of the buffer being
359 * cleared is defined (for example, if ClearBufferiv is called for a
360 * fixed- or floating-point buffer, or if ClearBufferfv is called
361 * for a signed or unsigned integer buffer). This is not an error."
363 * In this case we take "undefined" and "not an error" to mean "ignore."
364 * Note that we still need to generate an error for the invalid
365 * drawbuffer case (see the GL_STENCIL case above).
367 if (drawbuffer != 0) {
368 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
374 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
375 _mesa_lookup_enum_by_nr(buffer));
383 * Clear unsigned integer color buffer (not depth, not stencil).
386 _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
388 GET_CURRENT_CONTEXT(ctx);
390 FLUSH_VERTICES(ctx, 0);
391 FLUSH_CURRENT(ctx, 0);
394 _mesa_update_state( ctx );
400 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
401 if (mask == INVALID_MASK) {
402 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
406 else if (mask && !ctx->RasterDiscard) {
407 union gl_color_union clearSave;
410 clearSave = ctx->Color.ClearColor;
412 COPY_4V(ctx->Color.ClearColor.ui, value);
413 /* clear buffer(s) */
414 ctx->Driver.Clear(ctx, mask);
416 ctx->Color.ClearColor = clearSave;
422 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
424 * "The result of ClearBuffer is undefined if no conversion between
425 * the type of the specified value and the type of the buffer being
426 * cleared is defined (for example, if ClearBufferiv is called for a
427 * fixed- or floating-point buffer, or if ClearBufferfv is called
428 * for a signed or unsigned integer buffer). This is not an error."
430 * In this case we take "undefined" and "not an error" to mean "ignore."
431 * Even though we could do something sensible for GL_STENCIL, page 263
432 * (page 279 of the PDF) says:
434 * "Only ClearBufferiv should be used to clear stencil buffers."
436 * Note that we still need to generate an error for the invalid
437 * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv).
439 if (drawbuffer != 0) {
440 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)",
446 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
447 _mesa_lookup_enum_by_nr(buffer));
455 * Clear fixed-pt or float color buffer or depth buffer (not stencil).
458 _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
460 GET_CURRENT_CONTEXT(ctx);
462 FLUSH_VERTICES(ctx, 0);
463 FLUSH_CURRENT(ctx, 0);
466 _mesa_update_state( ctx );
471 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
473 * "ClearBuffer generates an INVALID VALUE error if buffer is
474 * COLOR and drawbuffer is less than zero, or greater than the
475 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
476 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
478 if (drawbuffer != 0) {
479 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
483 else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer && !ctx->RasterDiscard) {
484 /* Save current depth clear value, set to 'value', do the
485 * depth clear and restore the clear value.
486 * XXX in the future we may have a new ctx->Driver.ClearBuffer()
489 const GLclampd clearSave = ctx->Depth.Clear;
490 ctx->Depth.Clear = *value;
491 ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH);
492 ctx->Depth.Clear = clearSave;
494 /* clear depth buffer to value */
498 const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
499 if (mask == INVALID_MASK) {
500 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
504 else if (mask && !ctx->RasterDiscard) {
505 union gl_color_union clearSave;
508 clearSave = ctx->Color.ClearColor;
510 COPY_4V(ctx->Color.ClearColor.f, value);
511 /* clear buffer(s) */
512 ctx->Driver.Clear(ctx, mask);
514 ctx->Color.ClearColor = clearSave;
519 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
521 * "The result of ClearBuffer is undefined if no conversion between
522 * the type of the specified value and the type of the buffer being
523 * cleared is defined (for example, if ClearBufferiv is called for a
524 * fixed- or floating-point buffer, or if ClearBufferfv is called
525 * for a signed or unsigned integer buffer). This is not an error."
527 * In this case we take "undefined" and "not an error" to mean "ignore."
528 * Note that we still need to generate an error for the invalid
529 * drawbuffer case (see the GL_DEPTH case above).
531 if (drawbuffer != 0) {
532 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
538 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
539 _mesa_lookup_enum_by_nr(buffer));
547 * Clear depth/stencil buffer only.
550 _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
551 GLfloat depth, GLint stencil)
553 GET_CURRENT_CONTEXT(ctx);
556 FLUSH_VERTICES(ctx, 0);
557 FLUSH_CURRENT(ctx, 0);
559 if (buffer != GL_DEPTH_STENCIL) {
560 _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
561 _mesa_lookup_enum_by_nr(buffer));
565 /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says:
567 * "ClearBuffer generates an INVALID VALUE error if buffer is
568 * COLOR and drawbuffer is less than zero, or greater than the
569 * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH,
570 * STENCIL, or DEPTH STENCIL and drawbuffer is not zero."
572 if (drawbuffer != 0) {
573 _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
578 if (ctx->RasterDiscard)
582 _mesa_update_state( ctx );
585 if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer)
586 mask |= BUFFER_BIT_DEPTH;
587 if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer)
588 mask |= BUFFER_BIT_STENCIL;
591 /* save current clear values */
592 const GLclampd clearDepthSave = ctx->Depth.Clear;
593 const GLuint clearStencilSave = ctx->Stencil.Clear;
595 /* set new clear values */
596 ctx->Depth.Clear = depth;
597 ctx->Stencil.Clear = stencil;
600 ctx->Driver.Clear(ctx, mask);
603 ctx->Depth.Clear = clearDepthSave;
604 ctx->Stencil.Clear = clearStencilSave;